clightning-dumpkeys

dump clightning output descriptors
git clone git://jb55.com/clightning-dumpkeys
Log | Files | Refs | README | LICENSE

hmac.c (7148B)


      1 
      2 #include <string.h>
      3 #include "hmac.h"
      4 
      5 #define IPAD 0x3636363636363636ULL
      6 #define OPAD 0x5C5C5C5C5C5C5C5CULL
      7 
      8 #define BLOCK_256_U64S (HMAC_SHA256_BLOCKSIZE / sizeof(uint64_t))
      9 #define BLOCK_512_U64S (HMAC_SHA512_BLOCKSIZE / sizeof(uint64_t))
     10 
     11 static inline void xor_block_256(uint64_t block[BLOCK_256_U64S], uint64_t pad)
     12 {
     13 	size_t i;
     14 
     15 	for (i = 0; i < BLOCK_256_U64S; i++)
     16 		block[i] ^= pad;
     17 }
     18 
     19 
     20 static inline void xor_block_512(uint64_t block[BLOCK_512_U64S], uint64_t pad)
     21 {
     22 	size_t i;
     23 
     24 	for (i = 0; i < BLOCK_512_U64S; i++)
     25 		block[i] ^= pad;
     26 }
     27 
     28 void hmac_sha256_init(struct hmac_sha256_ctx *ctx,
     29 		      const void *k, size_t ksize)
     30 {
     31 	struct sha256 hashed_key;
     32 	/* We use k_opad as k_ipad temporarily. */
     33 	uint64_t *k_ipad = ctx->k_opad;
     34 
     35 	/* (keys longer than B bytes are first hashed using H) */
     36 	if (ksize > HMAC_SHA256_BLOCKSIZE) {
     37 		sha256(&hashed_key, k, ksize);
     38 		k = &hashed_key;
     39 		ksize = sizeof(hashed_key);
     40 	}
     41 
     42 	/* From RFC2104:
     43 	 *
     44 	 * (1) append zeros to the end of K to create a B byte string
     45 	 *  (e.g., if K is of length 20 bytes and B=64, then K will be
     46 	 *   appended with 44 zero bytes 0x00)
     47 	 */
     48 	memcpy(k_ipad, k, ksize);
     49 	memset((char *)k_ipad + ksize, 0, HMAC_SHA256_BLOCKSIZE - ksize);
     50 
     51 	/*
     52 	 * (2) XOR (bitwise exclusive-OR) the B byte string computed
     53 	 * in step (1) with ipad
     54 	 */
     55 	xor_block_256(k_ipad, IPAD);
     56 
     57 	/*
     58 	 * We start (4) here, appending text later:
     59 	 *
     60 	 * (3) append the stream of data 'text' to the B byte string resulting
     61 	 * from step (2)
     62 	 * (4) apply H to the stream generated in step (3)
     63 	 */
     64 	sha256_init(&ctx->sha);
     65 	sha256_update(&ctx->sha, k_ipad, HMAC_SHA256_BLOCKSIZE);
     66 
     67 	/*
     68 	 * (5) XOR (bitwise exclusive-OR) the B byte string computed in
     69 	 * step (1) with opad
     70 	 */
     71 	xor_block_256(ctx->k_opad, IPAD^OPAD);
     72 }
     73 
     74 
     75 void hmac_sha512_init(struct hmac_sha512_ctx *ctx,
     76 		      const void *k, size_t ksize)
     77 {
     78 	struct sha512 hashed_key;
     79 	/* We use k_opad as k_ipad temporarily. */
     80 	uint64_t *k_ipad = ctx->k_opad;
     81 
     82 	/* (keys longer than B bytes are first hashed using H) */
     83 	if (ksize > HMAC_SHA512_BLOCKSIZE) {
     84 		sha512(&hashed_key, k, ksize);
     85 		k = &hashed_key;
     86 		ksize = sizeof(hashed_key);
     87 	}
     88 
     89 	/* From RFC2104:
     90 	 *
     91 	 * (1) append zeros to the end of K to create a B byte string
     92 	 *  (e.g., if K is of length 20 bytes and B=64, then K will be
     93 	 *   appended with 44 zero bytes 0x00)
     94 	 */
     95 	memcpy(k_ipad, k, ksize);
     96 	memset((char *)k_ipad + ksize, 0, HMAC_SHA512_BLOCKSIZE - ksize);
     97 
     98 	/*
     99 	 * (2) XOR (bitwise exclusive-OR) the B byte string computed
    100 	 * in step (1) with ipad
    101 	 */
    102 	xor_block_512(k_ipad, IPAD);
    103 
    104 	/*
    105 	 * We start (4) here, appending text later:
    106 	 *
    107 	 * (3) append the stream of data 'text' to the B byte string resulting
    108 	 * from step (2)
    109 	 * (4) apply H to the stream generated in step (3)
    110 	 */
    111 	sha512_init(&ctx->sha);
    112 	sha512_update(&ctx->sha, k_ipad, HMAC_SHA512_BLOCKSIZE);
    113 
    114 	/*
    115 	 * (5) XOR (bitwise exclusive-OR) the B byte string computed in
    116 	 * step (1) with opad
    117 	 */
    118 	xor_block_512(ctx->k_opad, IPAD^OPAD);
    119 }
    120 
    121 
    122 void hmac_sha256_update(struct hmac_sha256_ctx *ctx, const void *p, size_t size)
    123 {
    124 	/* This is the appending-text part of this:
    125 	 *
    126 	 * (3) append the stream of data 'text' to the B byte string resulting
    127 	 * from step (2)
    128 	 * (4) apply H to the stream generated in step (3)
    129 	 */
    130 	sha256_update(&ctx->sha, p, size);
    131 }
    132 
    133 
    134 void hmac_sha512_update(struct hmac_sha512_ctx *ctx, const void *p, size_t size)
    135 {
    136 	sha512_update(&ctx->sha, p, size);
    137 }
    138 
    139 
    140 void hmac_sha256_done(struct hmac_sha256_ctx *ctx,
    141 		      struct hmac_sha256 *hmac)
    142 {
    143 	/* (4) apply H to the stream generated in step (3) */
    144 	sha256_done(&ctx->sha, &hmac->sha);
    145 
    146 	/*
    147 	 * (6) append the H result from step (4) to the B byte string
    148 	 * resulting from step (5)
    149 	 * (7) apply H to the stream generated in step (6) and output
    150 	 * the result
    151 	 */
    152 	sha256_init(&ctx->sha);
    153 	sha256_update(&ctx->sha, ctx->k_opad, sizeof(ctx->k_opad));
    154 	sha256_update(&ctx->sha, &hmac->sha, sizeof(hmac->sha));
    155 	sha256_done(&ctx->sha, &hmac->sha);
    156 }
    157 
    158 
    159 void hmac_sha512_done(struct hmac_sha512_ctx *ctx,
    160 		      struct hmac_sha512 *hmac)
    161 {
    162 	/* (4) apply H to the stream generated in step (3) */
    163 	sha512_done(&ctx->sha, &hmac->sha);
    164 
    165 	/*
    166 	 * (6) append the H result from step (4) to the B byte string
    167 	 * resulting from step (5)
    168 	 * (7) apply H to the stream generated in step (6) and output
    169 	 * the result
    170 	 */
    171 	sha512_init(&ctx->sha);
    172 	sha512_update(&ctx->sha, ctx->k_opad, sizeof(ctx->k_opad));
    173 	sha512_update(&ctx->sha, &hmac->sha, sizeof(hmac->sha));
    174 	sha512_done(&ctx->sha, &hmac->sha);
    175 }
    176 
    177 #if 1
    178 void hmac_sha256(struct hmac_sha256 *hmac,
    179 		 const void *k, size_t ksize,
    180 		 const void *d, size_t dsize)
    181 {
    182 	struct hmac_sha256_ctx ctx;
    183 
    184 	hmac_sha256_init(&ctx, k, ksize);
    185 	hmac_sha256_update(&ctx, d, dsize);
    186 	hmac_sha256_done(&ctx, hmac);
    187 }
    188 
    189 
    190 void hmac_sha512(struct hmac_sha512 *hmac,
    191 		 const void *k, size_t ksize,
    192 		 const void *d, size_t dsize)
    193 {
    194 	struct hmac_sha512_ctx ctx;
    195 
    196 	hmac_sha512_init(&ctx, k, ksize);
    197 	hmac_sha512_update(&ctx, d, dsize);
    198 	hmac_sha512_done(&ctx, hmac);
    199 }
    200 
    201 
    202 #else
    203 /* Direct mapping from MD5 example in RFC2104 */
    204 void hmac_sha256(struct hmac_sha256 *hmac,
    205 		 const void *key, size_t key_len,
    206 		 const void *text, size_t text_len)
    207 {
    208 	struct sha256_ctx context;
    209         unsigned char k_ipad[65];    /* inner padding -
    210                                       * key XORd with ipad
    211                                       */
    212         unsigned char k_opad[65];    /* outer padding -
    213                                       * key XORd with opad
    214                                       *//* start out by storing key in pads */
    215 	unsigned char tk[32];
    216         int i;
    217 
    218         /* if key is longer than 64 bytes reset it to key=MD5(key) */
    219         if (key_len > 64) {
    220 
    221                 struct sha256_ctx      tctx;
    222 
    223                 sha256_init(&tctx);
    224                 sha256_update(&tctx, key, key_len);
    225                 sha256_done(&tctx, tk);
    226 
    227                 key = tk;
    228                 key_len = 32;
    229         }
    230         bzero( k_ipad, sizeof k_ipad);
    231         bzero( k_opad, sizeof k_opad);
    232         bcopy( key, k_ipad, key_len);
    233         bcopy( key, k_opad, key_len);
    234 
    235         /* XOR key with ipad and opad values */
    236         for (i=0; i<64; i++) {
    237                 k_ipad[i] ^= 0x36;
    238                 k_opad[i] ^= 0x5c;
    239         }
    240         /*
    241          * perform inner MD5
    242          */
    243         sha256_init(&context);                   /* init context for 1st
    244                                               * pass */
    245         sha256_update(&context, k_ipad, 64);      /* start with inner pad */
    246         sha256_update(&context, text, text_len); /* then text of datagram */
    247         sha256_done(&context, &hmac->sha);          /* finish up 1st pass */
    248         /*
    249          * perform outer MD5
    250          */
    251         sha256_init(&context);                   /* init context for 2nd
    252                                               * pass */
    253         sha256_update(&context, k_opad, 64);     /* start with outer pad */
    254         sha256_update(&context, &hmac->sha, 32);     /* then results of 1st
    255                                               * hash */
    256         sha256_done(&context, &hmac->sha);          /* finish up 2nd pass */
    257 }
    258 #endif