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