1/* 2 * FIPS 186-2 PRF for libcrypto 3 * Copyright (c) 2004-2005, 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 <openssl/sha.h> 11 12#include "common.h" 13#include "crypto.h" 14 15 16static void sha1_transform(u8 *state, const u8 data[64]) 17{ 18 SHA_CTX context; 19 os_memset(&context, 0, sizeof(context)); 20 os_memcpy(&context.h0, state, 5 * 4); 21 SHA1_Transform(&context, data); 22 os_memcpy(state, &context.h0, 5 * 4); 23} 24 25 26int fips186_2_prf(const u8 *seed, size_t seed_len, u8 *x, size_t xlen) 27{ 28 u8 xkey[64]; 29 u32 t[5], _t[5]; 30 int i, j, m, k; 31 u8 *xpos = x; 32 u32 carry; 33 34 if (seed_len < sizeof(xkey)) 35 os_memset(xkey + seed_len, 0, sizeof(xkey) - seed_len); 36 else 37 seed_len = sizeof(xkey); 38 39 /* FIPS 186-2 + change notice 1 */ 40 41 os_memcpy(xkey, seed, seed_len); 42 t[0] = 0x67452301; 43 t[1] = 0xEFCDAB89; 44 t[2] = 0x98BADCFE; 45 t[3] = 0x10325476; 46 t[4] = 0xC3D2E1F0; 47 48 m = xlen / 40; 49 for (j = 0; j < m; j++) { 50 /* XSEED_j = 0 */ 51 for (i = 0; i < 2; i++) { 52 /* XVAL = (XKEY + XSEED_j) mod 2^b */ 53 54 /* w_i = G(t, XVAL) */ 55 os_memcpy(_t, t, 20); 56 sha1_transform((u8 *) _t, xkey); 57 _t[0] = host_to_be32(_t[0]); 58 _t[1] = host_to_be32(_t[1]); 59 _t[2] = host_to_be32(_t[2]); 60 _t[3] = host_to_be32(_t[3]); 61 _t[4] = host_to_be32(_t[4]); 62 os_memcpy(xpos, _t, 20); 63 64 /* XKEY = (1 + XKEY + w_i) mod 2^b */ 65 carry = 1; 66 for (k = 19; k >= 0; k--) { 67 carry += xkey[k] + xpos[k]; 68 xkey[k] = carry & 0xff; 69 carry >>= 8; 70 } 71 72 xpos += 20; 73 } 74 /* x_j = w_0|w_1 */ 75 } 76 77 return 0; 78} 79