1 /* 2 * FIPS 186-2 PRF for libcrypto 3 * Copyright (c) 2004-2017, Jouni Malinen <j@w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 9 #include "includes.h" 10 #include <wolfssl/options.h> 11 #include <wolfssl/wolfcrypt/sha.h> 12 13 #include "common.h" 14 #include "crypto.h" 15 16 17 static void sha1_transform(u32 *state, const u8 data[64]) 18 { 19 wc_Sha sha; 20 21 os_memset(&sha, 0, sizeof(sha)); 22 sha.digest[0] = state[0]; 23 sha.digest[1] = state[1]; 24 sha.digest[2] = state[2]; 25 sha.digest[3] = state[3]; 26 sha.digest[4] = state[4]; 27 wc_ShaUpdate(&sha, data, 64); 28 state[0] = sha.digest[0]; 29 state[1] = sha.digest[1]; 30 state[2] = sha.digest[2]; 31 state[3] = sha.digest[3]; 32 state[4] = sha.digest[4]; 33 } 34 35 36 int fips186_2_prf(const u8 *seed, size_t seed_len, u8 *x, size_t xlen) 37 { 38 u8 xkey[64]; 39 u32 t[5], _t[5]; 40 int i, j, m, k; 41 u8 *xpos = x; 42 u32 carry; 43 44 if (seed_len < sizeof(xkey)) 45 os_memset(xkey + seed_len, 0, sizeof(xkey) - seed_len); 46 else 47 seed_len = sizeof(xkey); 48 49 /* FIPS 186-2 + change notice 1 */ 50 51 os_memcpy(xkey, seed, seed_len); 52 t[0] = 0x67452301; 53 t[1] = 0xEFCDAB89; 54 t[2] = 0x98BADCFE; 55 t[3] = 0x10325476; 56 t[4] = 0xC3D2E1F0; 57 58 m = xlen / 40; 59 for (j = 0; j < m; j++) { 60 /* XSEED_j = 0 */ 61 for (i = 0; i < 2; i++) { 62 /* XVAL = (XKEY + XSEED_j) mod 2^b */ 63 64 /* w_i = G(t, XVAL) */ 65 os_memcpy(_t, t, 20); 66 sha1_transform(_t, xkey); 67 WPA_PUT_BE32(xpos, _t[0]); 68 WPA_PUT_BE32(xpos + 4, _t[1]); 69 WPA_PUT_BE32(xpos + 8, _t[2]); 70 WPA_PUT_BE32(xpos + 12, _t[3]); 71 WPA_PUT_BE32(xpos + 16, _t[4]); 72 73 /* XKEY = (1 + XKEY + w_i) mod 2^b */ 74 carry = 1; 75 for (k = 19; k >= 0; k--) { 76 carry += xkey[k] + xpos[k]; 77 xkey[k] = carry & 0xff; 78 carry >>= 8; 79 } 80 81 xpos += 20; 82 } 83 /* x_j = w_0|w_1 */ 84 } 85 86 return 0; 87 } 88