Line data Source code
1 : /* Defines a family of functions implementing HMAC over a single hash 2 : function. See fd_hmac.c for example usage. 3 : 4 : #define HASH_ALG sha256 5 : #define HASH_SZ 32UL 6 : #define HASH_BLOCK_SZ 64UL 7 : 8 : HASH_ALG is used to resolve names of the hash algorithm functions 9 : following fd_sha256 conventions (fd_{HASH_ALG}_{init,append,fini}). 10 : HASH_SZ is the byte count of the hash function's output value, and 11 : HASH_BLOCK_SZ is the hash function's internal block size (used by 12 : HMAC for key expansion). */ 13 : 14 : #ifndef HASH_ALG 15 : #error "Define HASH_ALG" 16 : #endif 17 : 18 : #ifndef HASH_SZ 19 : #error "Define HASH_SZ" 20 : #endif 21 : 22 : #ifndef HASH_BLOCK_SZ 23 : #error "Define HASH_BLOCK_SZ" 24 : #endif 25 : 26 : #define HMAC_FN FD_EXPAND_THEN_CONCAT2(fd_hmac_,HASH_ALG) 27 4662432 : #define HASH_(x) FD_EXPAND_THEN_CONCAT4(fd_,HASH_ALG,_,x) 28 : 29 : void * 30 : HMAC_FN( void const * data, 31 : ulong data_sz, 32 : void const * _key, 33 : ulong key_sz, 34 388536 : void * hash ) { 35 : 36 : /* https://tools.ietf.org/html/rfc2104 */ 37 : /* https://en.wikipedia.org/wiki/HMAC */ 38 : 39 : /* Compress key */ 40 : 41 388536 : uchar key[ HASH_BLOCK_SZ ] __attribute__((aligned(32))) = {0}; 42 388536 : if( key_sz>HASH_BLOCK_SZ ) { 43 0 : HASH_(hash)( _key, key_sz, key ); 44 0 : key_sz = HASH_SZ; 45 388536 : } else { 46 388536 : fd_memcpy( key, _key, key_sz ); 47 388536 : } 48 : 49 : /* Pad key */ 50 : 51 388536 : uchar key_ipad[ HASH_BLOCK_SZ ]; 52 388536 : uchar key_opad[ HASH_BLOCK_SZ ]; 53 388536 : memset( key_ipad, 0x36, HASH_BLOCK_SZ ); 54 388536 : memset( key_opad, 0x5c, HASH_BLOCK_SZ ); 55 25254840 : for( ulong i=0; i<HASH_BLOCK_SZ; i++ ) { 56 24866304 : key_ipad[ i ] = (uchar)( key_ipad[ i ] ^ key[ i ] ); 57 24866304 : key_opad[ i ] = (uchar)( key_opad[ i ] ^ key[ i ] ); 58 24866304 : } 59 : 60 : /* Inner SHA calculation */ 61 : 62 388536 : HASH_(t) _sha[ 1 ]; 63 388536 : HASH_(t) * sha = HASH_(join)( HASH_(new)( _sha ) ); 64 388536 : HASH_(init)( sha ); 65 388536 : HASH_(append)( sha, key_ipad, HASH_BLOCK_SZ ); 66 388536 : HASH_(append)( sha, data, data_sz ); 67 388536 : HASH_(fini)( sha, hash ); 68 : 69 : /* Outer SHA calculation */ 70 : 71 388536 : HASH_(init)( sha ); 72 388536 : HASH_(append)( sha, key_opad, HASH_BLOCK_SZ ); 73 388536 : HASH_(append)( sha, hash, HASH_SZ ); 74 388536 : HASH_(fini)( sha, hash ); 75 : 76 388536 : return hash; 77 388536 : } 78 : 79 : #undef HMAC_FN 80 : #undef HASH_ 81 : 82 : #undef HASH_ALG 83 : #undef HASH_SZ 84 : #undef HASH_BLOCK_SZ