📄 fips.c
字号:
/*
* FIPS 186-2 Pseudo-Random Number Generator
* Copyright (C) 2003 Mondru AB.
*
* Available under GPL or BSD license as described below.
*
* The contents of this file may be used under the terms of the GNU
* General Public License Version 2, provided that the above copyright
* notice and this permission notice is included in all copies or
* substantial portions of the software.
*
* As an alternative to the GNU General Public License Version 2 the
* content may also be used under the license conditions described
* below:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The name(s) of the authors of this software must not be used to
* endorse or promote products derived from this software without
* prior written permission.
* THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*
* The initial developer of the original code is
* Jens Jakobsen <jj@openggsn.org>
*
* Contributor(s):
*
*/
#include <string.h>
#include <stdio.h>
#ifndef WINDOWS
#include <netinet/in.h>
#else
#include <winsock2.h>
#endif
#include "sha1.h"
#include "fips.h"
/* Pseudo random number generator
* FIPS 186-2 Appendix 3.1 with change notes: Random Number Generation: 1
* Uses the SHA1 transform function as G().
*
* Based on the initial value XKEY a set of pseudo-random numbers are
* generated. The generated numbers are placed in x, which must be allocated
* prior to calling fips186_2_prng(). On error x is reset to all zero;
*
* Currently the implementation has the following restrictions:
* XKEY must be 20 bytes long (160 bit).
* XSEEDj is not supported.
* x must be multiple of 40 bytes (320 bit).
*/
void fips186_2_prng(unsigned char *XKEY, int XKEYlen,
unsigned char *XSEEDj, int XSEEDjlen,
unsigned char *x, int xlen) {
int i, j, m;
unsigned int addresult, carry;
unsigned long state[5] = {0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476,
0xc3d2e1f0};
unsigned long t[5];
unsigned char xval[64];
unsigned char w[20];
int n;
/* XSEEDj is not (yet) supported */
if (XSEEDjlen != 0) {
memset(x, 0, xlen);
return;
}
/* XKEYlen must be 20 */
if (XKEYlen != 20) {
memset(x, 0, xlen);
return;
}
/* xlen must be multiple of 40 */
if (xlen % 40) {
memset(x, 0, xlen);
return;
}
m = xlen / 40; /* Number of iterations */
/* Step 3 */
for (j=0; j<=(m-1); j++)
{
/* Step 3.2 */
for (i=0; i<=1; i++) {
/* a. XVAL = (XKEY + XSEED_j) mod 2^b */
for (n=0;n<20;n++) xval[n] = XKEY[n]; /* FIPS 186-2 Appendix 3.3 */
for (n=20;n<64;n++) xval[n] = 0;
#ifdef FIPSTEST
printf("xval: ");
for (n=0; n<20; n++) printf("%.2hhx", xval[n]);
printf("\n");
#endif
/* b. w_i = G(t, XVAL) */
memcpy(t, state, 20);
nossl_SHA1_Transform(t, xval);
t[0] = htonl(t[0]);
t[1] = htonl(t[1]);
t[2] = htonl(t[2]);
t[3] = htonl(t[3]);
t[4] = htonl(t[4]);
memcpy(w, t, 20);
#ifdef FIPSTEST
printf("w%d: ", i);
for (n=0; n<20; n++)
printf("%.2hhx", w[n]); printf("\n");
#endif
/* c. XKEY = (1 + XKEY + w_i) mod 2^b */
carry = 0;
for (n=19;n>=0;n--) {
if (n==19) addresult = 1; else addresult = 0;
addresult += XKEY[n] + w[n] + carry;
XKEY[n] = (addresult & 0x00ff);
carry = ((addresult & 0xff00) >> 8);
}
#ifdef FIPSTEST
printf("XKEY: ");
for (n=0; n<20; n++)
printf("%.2hhx", XKEY[n]);
printf("\n");
#endif
/* Step 3.3 xj = (w0 | w1) mod q */
memcpy(&x[j*40+i*20], w, XKEYlen);
}
}
#ifdef FIPSTEST
printf("x: \n");
for (n=0; n<xlen; n++) {
printf("%.2hhx", x[n]);
if ((n+1)%20 == 0) printf("\n");
}
printf("\n");
#endif
return;
}
#ifdef FIPSTEST
/*
* cc -DFIPSTEST -I . fips.c sha1.c -o fips
* ./fips
*/
int main(int argc, char **argv)
{
int n;
unsigned char x[40];
/* Test vector from Multiple Examples of DSA section 2:
http://csrc.nist.gov/encryption/dss/Examples-1024bit.pdf
2.2 Computing a public and private key pair.
*/
unsigned char XKEY[] = {0xbd, 0x02, 0x9b, 0xbe,
0x7f, 0x51, 0x96, 0x0b,
0xcf, 0x9e, 0xdb, 0x2b,
0x61, 0xf0, 0x6f, 0x0f,
0xeb, 0x5a, 0x38, 0xb6};
fips186_2_prng(XKEY, sizeof(XKEY), NULL, 0, x, sizeof(x));
printf("x: \n");
for (n=0; n<sizeof(x); n++) {
printf("%.2hhx", x[n]);
if ((n+1)%20 == 0) printf("\n");
}
printf("\n");
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -