xref: /dflybsd-src/contrib/wpa_supplicant/src/crypto/fips_prf_openssl.c (revision 3a84a4273475ed07d0ab1c2dfeffdfedef35d9cd)
13ff40c12SJohn Marino /*
23ff40c12SJohn Marino  * FIPS 186-2 PRF for libcrypto
33ff40c12SJohn Marino  * Copyright (c) 2004-2005, Jouni Malinen <j@w1.fi>
43ff40c12SJohn Marino  *
53ff40c12SJohn Marino  * This software may be distributed under the terms of the BSD license.
63ff40c12SJohn Marino  * See README for more details.
73ff40c12SJohn Marino  */
83ff40c12SJohn Marino 
93ff40c12SJohn Marino #include "includes.h"
103ff40c12SJohn Marino #include <openssl/sha.h>
113ff40c12SJohn Marino 
123ff40c12SJohn Marino #include "common.h"
133ff40c12SJohn Marino #include "crypto.h"
143ff40c12SJohn Marino 
153ff40c12SJohn Marino 
sha1_transform(u32 * state,const u8 data[64])16*a1157835SDaniel Fojt static void sha1_transform(u32 *state, const u8 data[64])
173ff40c12SJohn Marino {
183ff40c12SJohn Marino 	SHA_CTX context;
193ff40c12SJohn Marino 	os_memset(&context, 0, sizeof(context));
20*a1157835SDaniel Fojt #if defined(OPENSSL_IS_BORINGSSL) && !defined(ANDROID)
21*a1157835SDaniel Fojt 	context.h[0] = state[0];
22*a1157835SDaniel Fojt 	context.h[1] = state[1];
23*a1157835SDaniel Fojt 	context.h[2] = state[2];
24*a1157835SDaniel Fojt 	context.h[3] = state[3];
25*a1157835SDaniel Fojt 	context.h[4] = state[4];
263ff40c12SJohn Marino 	SHA1_Transform(&context, data);
27*a1157835SDaniel Fojt 	state[0] = context.h[0];
28*a1157835SDaniel Fojt 	state[1] = context.h[1];
29*a1157835SDaniel Fojt 	state[2] = context.h[2];
30*a1157835SDaniel Fojt 	state[3] = context.h[3];
31*a1157835SDaniel Fojt 	state[4] = context.h[4];
32*a1157835SDaniel Fojt #else
33*a1157835SDaniel Fojt 	context.h0 = state[0];
34*a1157835SDaniel Fojt 	context.h1 = state[1];
35*a1157835SDaniel Fojt 	context.h2 = state[2];
36*a1157835SDaniel Fojt 	context.h3 = state[3];
37*a1157835SDaniel Fojt 	context.h4 = state[4];
38*a1157835SDaniel Fojt 	SHA1_Transform(&context, data);
39*a1157835SDaniel Fojt 	state[0] = context.h0;
40*a1157835SDaniel Fojt 	state[1] = context.h1;
41*a1157835SDaniel Fojt 	state[2] = context.h2;
42*a1157835SDaniel Fojt 	state[3] = context.h3;
43*a1157835SDaniel Fojt 	state[4] = context.h4;
44*a1157835SDaniel Fojt #endif
453ff40c12SJohn Marino }
463ff40c12SJohn Marino 
473ff40c12SJohn Marino 
fips186_2_prf(const u8 * seed,size_t seed_len,u8 * x,size_t xlen)483ff40c12SJohn Marino int fips186_2_prf(const u8 *seed, size_t seed_len, u8 *x, size_t xlen)
493ff40c12SJohn Marino {
503ff40c12SJohn Marino 	u8 xkey[64];
513ff40c12SJohn Marino 	u32 t[5], _t[5];
523ff40c12SJohn Marino 	int i, j, m, k;
533ff40c12SJohn Marino 	u8 *xpos = x;
543ff40c12SJohn Marino 	u32 carry;
553ff40c12SJohn Marino 
563ff40c12SJohn Marino 	if (seed_len < sizeof(xkey))
573ff40c12SJohn Marino 		os_memset(xkey + seed_len, 0, sizeof(xkey) - seed_len);
583ff40c12SJohn Marino 	else
593ff40c12SJohn Marino 		seed_len = sizeof(xkey);
603ff40c12SJohn Marino 
613ff40c12SJohn Marino 	/* FIPS 186-2 + change notice 1 */
623ff40c12SJohn Marino 
633ff40c12SJohn Marino 	os_memcpy(xkey, seed, seed_len);
643ff40c12SJohn Marino 	t[0] = 0x67452301;
653ff40c12SJohn Marino 	t[1] = 0xEFCDAB89;
663ff40c12SJohn Marino 	t[2] = 0x98BADCFE;
673ff40c12SJohn Marino 	t[3] = 0x10325476;
683ff40c12SJohn Marino 	t[4] = 0xC3D2E1F0;
693ff40c12SJohn Marino 
703ff40c12SJohn Marino 	m = xlen / 40;
713ff40c12SJohn Marino 	for (j = 0; j < m; j++) {
723ff40c12SJohn Marino 		/* XSEED_j = 0 */
733ff40c12SJohn Marino 		for (i = 0; i < 2; i++) {
743ff40c12SJohn Marino 			/* XVAL = (XKEY + XSEED_j) mod 2^b */
753ff40c12SJohn Marino 
763ff40c12SJohn Marino 			/* w_i = G(t, XVAL) */
773ff40c12SJohn Marino 			os_memcpy(_t, t, 20);
78*a1157835SDaniel Fojt 			sha1_transform(_t, xkey);
79*a1157835SDaniel Fojt 			WPA_PUT_BE32(xpos, _t[0]);
80*a1157835SDaniel Fojt 			WPA_PUT_BE32(xpos + 4, _t[1]);
81*a1157835SDaniel Fojt 			WPA_PUT_BE32(xpos + 8, _t[2]);
82*a1157835SDaniel Fojt 			WPA_PUT_BE32(xpos + 12, _t[3]);
83*a1157835SDaniel Fojt 			WPA_PUT_BE32(xpos + 16, _t[4]);
843ff40c12SJohn Marino 
853ff40c12SJohn Marino 			/* XKEY = (1 + XKEY + w_i) mod 2^b */
863ff40c12SJohn Marino 			carry = 1;
873ff40c12SJohn Marino 			for (k = 19; k >= 0; k--) {
883ff40c12SJohn Marino 				carry += xkey[k] + xpos[k];
893ff40c12SJohn Marino 				xkey[k] = carry & 0xff;
903ff40c12SJohn Marino 				carry >>= 8;
913ff40c12SJohn Marino 			}
923ff40c12SJohn Marino 
933ff40c12SJohn Marino 			xpos += 20;
943ff40c12SJohn Marino 		}
953ff40c12SJohn Marino 		/* x_j = w_0|w_1 */
963ff40c12SJohn Marino 	}
973ff40c12SJohn Marino 
983ff40c12SJohn Marino 	return 0;
993ff40c12SJohn Marino }
100