1e28a4053SRui Paulo /* 2e28a4053SRui Paulo * FIPS 186-2 PRF for libcrypto 3e28a4053SRui Paulo * Copyright (c) 2004-2005, Jouni Malinen <j@w1.fi> 4e28a4053SRui Paulo * 5f05cddf9SRui Paulo * This software may be distributed under the terms of the BSD license. 6f05cddf9SRui Paulo * See README for more details. 7e28a4053SRui Paulo */ 8e28a4053SRui Paulo 9e28a4053SRui Paulo #include "includes.h" 10e28a4053SRui Paulo #include <openssl/sha.h> 11e28a4053SRui Paulo 12e28a4053SRui Paulo #include "common.h" 13e28a4053SRui Paulo #include "crypto.h" 14e28a4053SRui Paulo 15e28a4053SRui Paulo 16325151a3SRui Paulo static void sha1_transform(u32 *state, const u8 data[64]) 17e28a4053SRui Paulo { 18e28a4053SRui Paulo SHA_CTX context; 19e28a4053SRui Paulo os_memset(&context, 0, sizeof(context)); 20*780fb4a2SCy Schubert #if defined(OPENSSL_IS_BORINGSSL) && !defined(ANDROID) 21*780fb4a2SCy Schubert context.h[0] = state[0]; 22*780fb4a2SCy Schubert context.h[1] = state[1]; 23*780fb4a2SCy Schubert context.h[2] = state[2]; 24*780fb4a2SCy Schubert context.h[3] = state[3]; 25*780fb4a2SCy Schubert context.h[4] = state[4]; 26*780fb4a2SCy Schubert SHA1_Transform(&context, data); 27*780fb4a2SCy Schubert state[0] = context.h[0]; 28*780fb4a2SCy Schubert state[1] = context.h[1]; 29*780fb4a2SCy Schubert state[2] = context.h[2]; 30*780fb4a2SCy Schubert state[3] = context.h[3]; 31*780fb4a2SCy Schubert state[4] = context.h[4]; 32*780fb4a2SCy Schubert #else 33325151a3SRui Paulo context.h0 = state[0]; 34325151a3SRui Paulo context.h1 = state[1]; 35325151a3SRui Paulo context.h2 = state[2]; 36325151a3SRui Paulo context.h3 = state[3]; 37325151a3SRui Paulo context.h4 = state[4]; 38e28a4053SRui Paulo SHA1_Transform(&context, data); 39325151a3SRui Paulo state[0] = context.h0; 40325151a3SRui Paulo state[1] = context.h1; 41325151a3SRui Paulo state[2] = context.h2; 42325151a3SRui Paulo state[3] = context.h3; 43325151a3SRui Paulo state[4] = context.h4; 44*780fb4a2SCy Schubert #endif 45e28a4053SRui Paulo } 46e28a4053SRui Paulo 47e28a4053SRui Paulo 48e28a4053SRui Paulo int fips186_2_prf(const u8 *seed, size_t seed_len, u8 *x, size_t xlen) 49e28a4053SRui Paulo { 50e28a4053SRui Paulo u8 xkey[64]; 51e28a4053SRui Paulo u32 t[5], _t[5]; 52e28a4053SRui Paulo int i, j, m, k; 53e28a4053SRui Paulo u8 *xpos = x; 54e28a4053SRui Paulo u32 carry; 55e28a4053SRui Paulo 56f05cddf9SRui Paulo if (seed_len < sizeof(xkey)) 57f05cddf9SRui Paulo os_memset(xkey + seed_len, 0, sizeof(xkey) - seed_len); 58f05cddf9SRui Paulo else 59e28a4053SRui Paulo seed_len = sizeof(xkey); 60e28a4053SRui Paulo 61e28a4053SRui Paulo /* FIPS 186-2 + change notice 1 */ 62e28a4053SRui Paulo 63e28a4053SRui Paulo os_memcpy(xkey, seed, seed_len); 64e28a4053SRui Paulo t[0] = 0x67452301; 65e28a4053SRui Paulo t[1] = 0xEFCDAB89; 66e28a4053SRui Paulo t[2] = 0x98BADCFE; 67e28a4053SRui Paulo t[3] = 0x10325476; 68e28a4053SRui Paulo t[4] = 0xC3D2E1F0; 69e28a4053SRui Paulo 70e28a4053SRui Paulo m = xlen / 40; 71e28a4053SRui Paulo for (j = 0; j < m; j++) { 72e28a4053SRui Paulo /* XSEED_j = 0 */ 73e28a4053SRui Paulo for (i = 0; i < 2; i++) { 74e28a4053SRui Paulo /* XVAL = (XKEY + XSEED_j) mod 2^b */ 75e28a4053SRui Paulo 76e28a4053SRui Paulo /* w_i = G(t, XVAL) */ 77e28a4053SRui Paulo os_memcpy(_t, t, 20); 78325151a3SRui Paulo sha1_transform(_t, xkey); 79*780fb4a2SCy Schubert WPA_PUT_BE32(xpos, _t[0]); 80*780fb4a2SCy Schubert WPA_PUT_BE32(xpos + 4, _t[1]); 81*780fb4a2SCy Schubert WPA_PUT_BE32(xpos + 8, _t[2]); 82*780fb4a2SCy Schubert WPA_PUT_BE32(xpos + 12, _t[3]); 83*780fb4a2SCy Schubert WPA_PUT_BE32(xpos + 16, _t[4]); 84e28a4053SRui Paulo 85e28a4053SRui Paulo /* XKEY = (1 + XKEY + w_i) mod 2^b */ 86e28a4053SRui Paulo carry = 1; 87e28a4053SRui Paulo for (k = 19; k >= 0; k--) { 88e28a4053SRui Paulo carry += xkey[k] + xpos[k]; 89e28a4053SRui Paulo xkey[k] = carry & 0xff; 90e28a4053SRui Paulo carry >>= 8; 91e28a4053SRui Paulo } 92e28a4053SRui Paulo 93e28a4053SRui Paulo xpos += 20; 94e28a4053SRui Paulo } 95e28a4053SRui Paulo /* x_j = w_0|w_1 */ 96e28a4053SRui Paulo } 97e28a4053SRui Paulo 98e28a4053SRui Paulo return 0; 99e28a4053SRui Paulo } 100