hkdf.c (2648B)
1 /* MIT (BSD) license */ 2 3 #include "hmac.h" 4 #include "sha256.h" 5 #include <assert.h> 6 #include <string.h> 7 8 void hkdf_sha256(void *okm, size_t okm_size, 9 const void *s, size_t ssize, 10 const void *k, size_t ksize, 11 const void *info, size_t isize) 12 { 13 struct hmac_sha256 prk, t; 14 struct hmac_sha256_ctx ctx; 15 unsigned char c; 16 17 assert(okm_size < 255 * sizeof(t)); 18 19 /* RFC 5869: 20 * 21 * 2.2. Step 1: Extract 22 * 23 * HKDF-Extract(salt, IKM) -> PRK 24 * 25 * Options: 26 * Hash a hash function; HashLen denotes the length of the 27 * hash function output in octets 28 * 29 * Inputs: 30 * salt optional salt value (a non-secret random value); 31 * if not provided, it is set to a string of HashLen zeros. 32 * IKM input keying material 33 * 34 * Output: 35 * PRK a pseudorandom key (of HashLen octets) 36 * 37 * The output PRK is calculated as follows: 38 * 39 * PRK = HMAC-Hash(salt, IKM) 40 */ 41 hmac_sha256(&prk, s, ssize, k, ksize); 42 43 /* 44 * 2.3. Step 2: Expand 45 * 46 * HKDF-Expand(PRK, info, L) -> OKM 47 * 48 * Options: 49 * Hash a hash function; HashLen denotes the length of the 50 * hash function output in octets 51 * 52 * Inputs: 53 * PRK a pseudorandom key of at least HashLen octets 54 * (usually, the output from the extract step) 55 * info optional context and application specific information 56 * (can be a zero-length string) 57 * L length of output keying material in octets 58 * (<= 255*HashLen) 59 * 60 * Output: 61 * OKM output keying material (of L octets) 62 * 63 * The output OKM is calculated as follows: 64 * 65 * N = ceil(L/HashLen) 66 * T = T(1) | T(2) | T(3) | ... | T(N) 67 * OKM = first L octets of T 68 * 69 * where: 70 * T(0) = empty string (zero length) 71 * T(1) = HMAC-Hash(PRK, T(0) | info | 0x01) 72 * T(2) = HMAC-Hash(PRK, T(1) | info | 0x02) 73 * T(3) = HMAC-Hash(PRK, T(2) | info | 0x03) 74 * ... 75 * 76 * (where the constant concatenated to the end of each T(n) is a 77 * single octet.) 78 */ 79 c = 1; 80 hmac_sha256_init(&ctx, &prk, sizeof(prk)); 81 hmac_sha256_update(&ctx, info, isize); 82 hmac_sha256_update(&ctx, &c, 1); 83 hmac_sha256_done(&ctx, &t); 84 85 while (okm_size > sizeof(t)) { 86 memcpy(okm, &t, sizeof(t)); 87 okm = (char *)okm + sizeof(t); 88 okm_size -= sizeof(t); 89 90 c++; 91 hmac_sha256_init(&ctx, &prk, sizeof(prk)); 92 hmac_sha256_update(&ctx, &t, sizeof(t)); 93 hmac_sha256_update(&ctx, info, isize); 94 hmac_sha256_update(&ctx, &c, 1); 95 hmac_sha256_done(&ctx, &t); 96 } 97 memcpy(okm, &t, okm_size); 98 }