fips_prf_openssl.c revision 252726
1214501Srpaulo/* 2214501Srpaulo * FIPS 186-2 PRF for libcrypto 3214501Srpaulo * Copyright (c) 2004-2005, Jouni Malinen <j@w1.fi> 4214501Srpaulo * 5252726Srpaulo * This software may be distributed under the terms of the BSD license. 6252726Srpaulo * See README for more details. 7214501Srpaulo */ 8214501Srpaulo 9214501Srpaulo#include "includes.h" 10214501Srpaulo#include <openssl/sha.h> 11214501Srpaulo 12214501Srpaulo#include "common.h" 13214501Srpaulo#include "crypto.h" 14214501Srpaulo 15214501Srpaulo 16214501Srpaulostatic void sha1_transform(u8 *state, const u8 data[64]) 17214501Srpaulo{ 18214501Srpaulo SHA_CTX context; 19214501Srpaulo os_memset(&context, 0, sizeof(context)); 20214501Srpaulo os_memcpy(&context.h0, state, 5 * 4); 21214501Srpaulo SHA1_Transform(&context, data); 22214501Srpaulo os_memcpy(state, &context.h0, 5 * 4); 23214501Srpaulo} 24214501Srpaulo 25214501Srpaulo 26214501Srpauloint fips186_2_prf(const u8 *seed, size_t seed_len, u8 *x, size_t xlen) 27214501Srpaulo{ 28214501Srpaulo u8 xkey[64]; 29214501Srpaulo u32 t[5], _t[5]; 30214501Srpaulo int i, j, m, k; 31214501Srpaulo u8 *xpos = x; 32214501Srpaulo u32 carry; 33214501Srpaulo 34252726Srpaulo if (seed_len < sizeof(xkey)) 35252726Srpaulo os_memset(xkey + seed_len, 0, sizeof(xkey) - seed_len); 36252726Srpaulo else 37214501Srpaulo seed_len = sizeof(xkey); 38214501Srpaulo 39214501Srpaulo /* FIPS 186-2 + change notice 1 */ 40214501Srpaulo 41214501Srpaulo os_memcpy(xkey, seed, seed_len); 42214501Srpaulo t[0] = 0x67452301; 43214501Srpaulo t[1] = 0xEFCDAB89; 44214501Srpaulo t[2] = 0x98BADCFE; 45214501Srpaulo t[3] = 0x10325476; 46214501Srpaulo t[4] = 0xC3D2E1F0; 47214501Srpaulo 48214501Srpaulo m = xlen / 40; 49214501Srpaulo for (j = 0; j < m; j++) { 50214501Srpaulo /* XSEED_j = 0 */ 51214501Srpaulo for (i = 0; i < 2; i++) { 52214501Srpaulo /* XVAL = (XKEY + XSEED_j) mod 2^b */ 53214501Srpaulo 54214501Srpaulo /* w_i = G(t, XVAL) */ 55214501Srpaulo os_memcpy(_t, t, 20); 56214501Srpaulo sha1_transform((u8 *) _t, xkey); 57214501Srpaulo _t[0] = host_to_be32(_t[0]); 58214501Srpaulo _t[1] = host_to_be32(_t[1]); 59214501Srpaulo _t[2] = host_to_be32(_t[2]); 60214501Srpaulo _t[3] = host_to_be32(_t[3]); 61214501Srpaulo _t[4] = host_to_be32(_t[4]); 62214501Srpaulo os_memcpy(xpos, _t, 20); 63214501Srpaulo 64214501Srpaulo /* XKEY = (1 + XKEY + w_i) mod 2^b */ 65214501Srpaulo carry = 1; 66214501Srpaulo for (k = 19; k >= 0; k--) { 67214501Srpaulo carry += xkey[k] + xpos[k]; 68214501Srpaulo xkey[k] = carry & 0xff; 69214501Srpaulo carry >>= 8; 70214501Srpaulo } 71214501Srpaulo 72214501Srpaulo xpos += 20; 73214501Srpaulo } 74214501Srpaulo /* x_j = w_0|w_1 */ 75214501Srpaulo } 76214501Srpaulo 77214501Srpaulo return 0; 78214501Srpaulo} 79