mirror of
https://github.com/openssl/openssl.git
synced 2024-11-25 11:03:37 +08:00
And so it begins... again.
Initial FIPS 140-2 code ported to HEAD. Doesn't even compile yet, may have missing files, extraneous files and other nastiness. In other words: it's experimental ATM, OK?
This commit is contained in:
parent
72a267331a
commit
2b4b28dc32
8
fips/.cvsignore
Normal file
8
fips/.cvsignore
Normal file
@ -0,0 +1,8 @@
|
||||
lib
|
||||
Makefile.save
|
||||
fips_test_suite
|
||||
fips_premain_dso
|
||||
fips_standalone_sha1
|
||||
fipscanister.o.sha1
|
||||
*.flc
|
||||
semantic.cache
|
103
fips/aes/fips_aes_selftest.c
Normal file
103
fips/aes/fips_aes_selftest.c
Normal file
@ -0,0 +1,103 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2003 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#define OPENSSL_FIPSEVP
|
||||
|
||||
#include <string.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/fips.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
static struct
|
||||
{
|
||||
unsigned char key[16];
|
||||
unsigned char plaintext[16];
|
||||
unsigned char ciphertext[16];
|
||||
} tests[]=
|
||||
{
|
||||
{
|
||||
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
|
||||
0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F },
|
||||
{ 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,
|
||||
0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF },
|
||||
{ 0x69,0xC4,0xE0,0xD8,0x6A,0x7B,0x04,0x30,
|
||||
0xD8,0xCD,0xB7,0x80,0x70,0xB4,0xC5,0x5A },
|
||||
},
|
||||
};
|
||||
|
||||
void FIPS_corrupt_aes()
|
||||
{
|
||||
tests[0].key[0]++;
|
||||
}
|
||||
|
||||
int FIPS_selftest_aes()
|
||||
{
|
||||
int n;
|
||||
int ret = 0;
|
||||
EVP_CIPHER_CTX ctx;
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
|
||||
for(n=0 ; n < 1 ; ++n)
|
||||
{
|
||||
if (fips_cipher_test(&ctx, EVP_aes_128_ecb(),
|
||||
tests[n].key, NULL,
|
||||
tests[n].plaintext,
|
||||
tests[n].ciphertext,
|
||||
16) <= 0)
|
||||
goto err;
|
||||
}
|
||||
ret = 1;
|
||||
err:
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
if (ret == 0)
|
||||
FIPSerr(FIPS_F_FIPS_SELFTEST_AES,FIPS_R_SELFTEST_FAILED);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
939
fips/aes/fips_aesavs.c
Normal file
939
fips/aes/fips_aesavs.c
Normal file
@ -0,0 +1,939 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2004 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
/*---------------------------------------------
|
||||
NIST AES Algorithm Validation Suite
|
||||
Test Program
|
||||
|
||||
Donated to OpenSSL by:
|
||||
V-ONE Corporation
|
||||
20250 Century Blvd, Suite 300
|
||||
Germantown, MD 20874
|
||||
U.S.A.
|
||||
----------------------------------------------*/
|
||||
|
||||
#define OPENSSL_FIPSEVP
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include "e_os.h"
|
||||
|
||||
#ifndef OPENSSL_FIPS
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
printf("No FIPS AES support\n");
|
||||
return(0);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <openssl/fips.h>
|
||||
#include "fips_utl.h"
|
||||
|
||||
#define AES_BLOCK_SIZE 16
|
||||
|
||||
#define VERBOSE 0
|
||||
|
||||
/*-----------------------------------------------*/
|
||||
|
||||
static int AESTest(EVP_CIPHER_CTX *ctx,
|
||||
char *amode, int akeysz, unsigned char *aKey,
|
||||
unsigned char *iVec,
|
||||
int dir, /* 0 = decrypt, 1 = encrypt */
|
||||
unsigned char *plaintext, unsigned char *ciphertext, int len)
|
||||
{
|
||||
const EVP_CIPHER *cipher = NULL;
|
||||
|
||||
if (strcasecmp(amode, "CBC") == 0)
|
||||
{
|
||||
switch (akeysz)
|
||||
{
|
||||
case 128:
|
||||
cipher = EVP_aes_128_cbc();
|
||||
break;
|
||||
|
||||
case 192:
|
||||
cipher = EVP_aes_192_cbc();
|
||||
break;
|
||||
|
||||
case 256:
|
||||
cipher = EVP_aes_256_cbc();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
else if (strcasecmp(amode, "ECB") == 0)
|
||||
{
|
||||
switch (akeysz)
|
||||
{
|
||||
case 128:
|
||||
cipher = EVP_aes_128_ecb();
|
||||
break;
|
||||
|
||||
case 192:
|
||||
cipher = EVP_aes_192_ecb();
|
||||
break;
|
||||
|
||||
case 256:
|
||||
cipher = EVP_aes_256_ecb();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(amode, "CFB128") == 0)
|
||||
{
|
||||
switch (akeysz)
|
||||
{
|
||||
case 128:
|
||||
cipher = EVP_aes_128_cfb128();
|
||||
break;
|
||||
|
||||
case 192:
|
||||
cipher = EVP_aes_192_cfb128();
|
||||
break;
|
||||
|
||||
case 256:
|
||||
cipher = EVP_aes_256_cfb128();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
else if (strncasecmp(amode, "OFB", 3) == 0)
|
||||
{
|
||||
switch (akeysz)
|
||||
{
|
||||
case 128:
|
||||
cipher = EVP_aes_128_ofb();
|
||||
break;
|
||||
|
||||
case 192:
|
||||
cipher = EVP_aes_192_ofb();
|
||||
break;
|
||||
|
||||
case 256:
|
||||
cipher = EVP_aes_256_ofb();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(!strcasecmp(amode,"CFB1"))
|
||||
{
|
||||
switch (akeysz)
|
||||
{
|
||||
case 128:
|
||||
cipher = EVP_aes_128_cfb1();
|
||||
break;
|
||||
|
||||
case 192:
|
||||
cipher = EVP_aes_192_cfb1();
|
||||
break;
|
||||
|
||||
case 256:
|
||||
cipher = EVP_aes_256_cfb1();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(!strcasecmp(amode,"CFB8"))
|
||||
{
|
||||
switch (akeysz)
|
||||
{
|
||||
case 128:
|
||||
cipher = EVP_aes_128_cfb8();
|
||||
break;
|
||||
|
||||
case 192:
|
||||
cipher = EVP_aes_192_cfb8();
|
||||
break;
|
||||
|
||||
case 256:
|
||||
cipher = EVP_aes_256_cfb8();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Unknown mode: %s\n", amode);
|
||||
return 0;
|
||||
}
|
||||
if (!cipher)
|
||||
{
|
||||
printf("Invalid key size: %d\n", akeysz);
|
||||
return 0;
|
||||
}
|
||||
if (EVP_CipherInit_ex(ctx, cipher, NULL, aKey, iVec, dir) <= 0)
|
||||
return 0;
|
||||
if(!strcasecmp(amode,"CFB1"))
|
||||
M_EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS);
|
||||
if (dir)
|
||||
EVP_Cipher(ctx, ciphertext, plaintext, len);
|
||||
else
|
||||
EVP_Cipher(ctx, plaintext, ciphertext, len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------*/
|
||||
char *t_tag[2] = {"PLAINTEXT", "CIPHERTEXT"};
|
||||
char *t_mode[6] = {"CBC","ECB","OFB","CFB1","CFB8","CFB128"};
|
||||
enum Mode {CBC, ECB, OFB, CFB1, CFB8, CFB128};
|
||||
enum XCrypt {XDECRYPT, XENCRYPT};
|
||||
|
||||
/*=============================*/
|
||||
/* Monte Carlo Tests */
|
||||
/*-----------------------------*/
|
||||
|
||||
/*#define gb(a,b) (((a)[(b)/8] >> ((b)%8))&1)*/
|
||||
/*#define sb(a,b,v) ((a)[(b)/8]=((a)[(b)/8]&~(1 << ((b)%8)))|(!!(v) << ((b)%8)))*/
|
||||
|
||||
#define gb(a,b) (((a)[(b)/8] >> (7-(b)%8))&1)
|
||||
#define sb(a,b,v) ((a)[(b)/8]=((a)[(b)/8]&~(1 << (7-(b)%8)))|(!!(v) << (7-(b)%8)))
|
||||
|
||||
static int do_mct(char *amode,
|
||||
int akeysz, unsigned char *aKey,unsigned char *iVec,
|
||||
int dir, unsigned char *text, int len,
|
||||
FILE *rfp)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char key[101][32];
|
||||
unsigned char iv[101][AES_BLOCK_SIZE];
|
||||
unsigned char ptext[1001][32];
|
||||
unsigned char ctext[1001][32];
|
||||
unsigned char ciphertext[64+4];
|
||||
int i, j, n, n1, n2;
|
||||
int imode = 0, nkeysz = akeysz/8;
|
||||
EVP_CIPHER_CTX ctx;
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
|
||||
if (len > 32)
|
||||
{
|
||||
printf("\n>>>> Length exceeds 32 for %s %d <<<<\n\n",
|
||||
amode, akeysz);
|
||||
return -1;
|
||||
}
|
||||
for (imode = 0; imode < 6; ++imode)
|
||||
if (strcmp(amode, t_mode[imode]) == 0)
|
||||
break;
|
||||
if (imode == 6)
|
||||
{
|
||||
printf("Unrecognized mode: %s\n", amode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(key[0], aKey, nkeysz);
|
||||
if (iVec)
|
||||
memcpy(iv[0], iVec, AES_BLOCK_SIZE);
|
||||
if (dir == XENCRYPT)
|
||||
memcpy(ptext[0], text, len);
|
||||
else
|
||||
memcpy(ctext[0], text, len);
|
||||
for (i = 0; i < 100; ++i)
|
||||
{
|
||||
/* printf("Iteration %d\n", i); */
|
||||
if (i > 0)
|
||||
{
|
||||
fprintf(rfp,"COUNT = %d\n",i);
|
||||
OutputValue("KEY",key[i],nkeysz,rfp,0);
|
||||
if (imode != ECB) /* ECB */
|
||||
OutputValue("IV",iv[i],AES_BLOCK_SIZE,rfp,0);
|
||||
/* Output Ciphertext | Plaintext */
|
||||
OutputValue(t_tag[dir^1],dir ? ptext[0] : ctext[0],len,rfp,
|
||||
imode == CFB1);
|
||||
}
|
||||
for (j = 0; j < 1000; ++j)
|
||||
{
|
||||
switch (imode)
|
||||
{
|
||||
case ECB:
|
||||
if (j == 0)
|
||||
{ /* set up encryption */
|
||||
ret = AESTest(&ctx, amode, akeysz, key[i], NULL,
|
||||
dir, /* 0 = decrypt, 1 = encrypt */
|
||||
ptext[j], ctext[j], len);
|
||||
if (dir == XENCRYPT)
|
||||
memcpy(ptext[j+1], ctext[j], len);
|
||||
else
|
||||
memcpy(ctext[j+1], ptext[j], len);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dir == XENCRYPT)
|
||||
{
|
||||
EVP_Cipher(&ctx, ctext[j], ptext[j], len);
|
||||
memcpy(ptext[j+1], ctext[j], len);
|
||||
}
|
||||
else
|
||||
{
|
||||
EVP_Cipher(&ctx, ptext[j], ctext[j], len);
|
||||
memcpy(ctext[j+1], ptext[j], len);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CBC:
|
||||
case OFB:
|
||||
case CFB128:
|
||||
if (j == 0)
|
||||
{
|
||||
ret = AESTest(&ctx, amode, akeysz, key[i], iv[i],
|
||||
dir, /* 0 = decrypt, 1 = encrypt */
|
||||
ptext[j], ctext[j], len);
|
||||
if (dir == XENCRYPT)
|
||||
memcpy(ptext[j+1], iv[i], len);
|
||||
else
|
||||
memcpy(ctext[j+1], iv[i], len);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dir == XENCRYPT)
|
||||
{
|
||||
EVP_Cipher(&ctx, ctext[j], ptext[j], len);
|
||||
memcpy(ptext[j+1], ctext[j-1], len);
|
||||
}
|
||||
else
|
||||
{
|
||||
EVP_Cipher(&ctx, ptext[j], ctext[j], len);
|
||||
memcpy(ctext[j+1], ptext[j-1], len);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CFB8:
|
||||
if (j == 0)
|
||||
{
|
||||
ret = AESTest(&ctx, amode, akeysz, key[i], iv[i],
|
||||
dir, /* 0 = decrypt, 1 = encrypt */
|
||||
ptext[j], ctext[j], len);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dir == XENCRYPT)
|
||||
EVP_Cipher(&ctx, ctext[j], ptext[j], len);
|
||||
else
|
||||
EVP_Cipher(&ctx, ptext[j], ctext[j], len);
|
||||
}
|
||||
if (dir == XENCRYPT)
|
||||
{
|
||||
if (j < 16)
|
||||
memcpy(ptext[j+1], &iv[i][j], len);
|
||||
else
|
||||
memcpy(ptext[j+1], ctext[j-16], len);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (j < 16)
|
||||
memcpy(ctext[j+1], &iv[i][j], len);
|
||||
else
|
||||
memcpy(ctext[j+1], ptext[j-16], len);
|
||||
}
|
||||
break;
|
||||
|
||||
case CFB1:
|
||||
if(j == 0)
|
||||
{
|
||||
#if 0
|
||||
/* compensate for wrong endianness of input file */
|
||||
if(i == 0)
|
||||
ptext[0][0]<<=7;
|
||||
#endif
|
||||
ret = AESTest(&ctx,amode,akeysz,key[i],iv[i],dir,
|
||||
ptext[j], ctext[j], len);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dir == XENCRYPT)
|
||||
EVP_Cipher(&ctx, ctext[j], ptext[j], len);
|
||||
else
|
||||
EVP_Cipher(&ctx, ptext[j], ctext[j], len);
|
||||
|
||||
}
|
||||
if(dir == XENCRYPT)
|
||||
{
|
||||
if(j < 128)
|
||||
sb(ptext[j+1],0,gb(iv[i],j));
|
||||
else
|
||||
sb(ptext[j+1],0,gb(ctext[j-128],0));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(j < 128)
|
||||
sb(ctext[j+1],0,gb(iv[i],j));
|
||||
else
|
||||
sb(ctext[j+1],0,gb(ptext[j-128],0));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
--j; /* reset to last of range */
|
||||
/* Output Ciphertext | Plaintext */
|
||||
OutputValue(t_tag[dir],dir ? ctext[j] : ptext[j],len,rfp,
|
||||
imode == CFB1);
|
||||
fprintf(rfp, "\n"); /* add separator */
|
||||
|
||||
/* Compute next KEY */
|
||||
if (dir == XENCRYPT)
|
||||
{
|
||||
if (imode == CFB8)
|
||||
{ /* ct = CT[j-15] || CT[j-14] || ... || CT[j] */
|
||||
for (n1 = 0, n2 = nkeysz-1; n1 < nkeysz; ++n1, --n2)
|
||||
ciphertext[n1] = ctext[j-n2][0];
|
||||
}
|
||||
else if(imode == CFB1)
|
||||
{
|
||||
for(n1=0,n2=akeysz-1 ; n1 < akeysz ; ++n1,--n2)
|
||||
sb(ciphertext,n1,gb(ctext[j-n2],0));
|
||||
}
|
||||
else
|
||||
switch (akeysz)
|
||||
{
|
||||
case 128:
|
||||
memcpy(ciphertext, ctext[j], 16);
|
||||
break;
|
||||
case 192:
|
||||
memcpy(ciphertext, ctext[j-1]+8, 8);
|
||||
memcpy(ciphertext+8, ctext[j], 16);
|
||||
break;
|
||||
case 256:
|
||||
memcpy(ciphertext, ctext[j-1], 16);
|
||||
memcpy(ciphertext+16, ctext[j], 16);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (imode == CFB8)
|
||||
{ /* ct = CT[j-15] || CT[j-14] || ... || CT[j] */
|
||||
for (n1 = 0, n2 = nkeysz-1; n1 < nkeysz; ++n1, --n2)
|
||||
ciphertext[n1] = ptext[j-n2][0];
|
||||
}
|
||||
else if(imode == CFB1)
|
||||
{
|
||||
for(n1=0,n2=akeysz-1 ; n1 < akeysz ; ++n1,--n2)
|
||||
sb(ciphertext,n1,gb(ptext[j-n2],0));
|
||||
}
|
||||
else
|
||||
switch (akeysz)
|
||||
{
|
||||
case 128:
|
||||
memcpy(ciphertext, ptext[j], 16);
|
||||
break;
|
||||
case 192:
|
||||
memcpy(ciphertext, ptext[j-1]+8, 8);
|
||||
memcpy(ciphertext+8, ptext[j], 16);
|
||||
break;
|
||||
case 256:
|
||||
memcpy(ciphertext, ptext[j-1], 16);
|
||||
memcpy(ciphertext+16, ptext[j], 16);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Compute next key: Key[i+1] = Key[i] xor ct */
|
||||
for (n = 0; n < nkeysz; ++n)
|
||||
key[i+1][n] = key[i][n] ^ ciphertext[n];
|
||||
|
||||
/* Compute next IV and text */
|
||||
if (dir == XENCRYPT)
|
||||
{
|
||||
switch (imode)
|
||||
{
|
||||
case ECB:
|
||||
memcpy(ptext[0], ctext[j], AES_BLOCK_SIZE);
|
||||
break;
|
||||
case CBC:
|
||||
case OFB:
|
||||
case CFB128:
|
||||
memcpy(iv[i+1], ctext[j], AES_BLOCK_SIZE);
|
||||
memcpy(ptext[0], ctext[j-1], AES_BLOCK_SIZE);
|
||||
break;
|
||||
case CFB8:
|
||||
/* IV[i+1] = ct */
|
||||
for (n1 = 0, n2 = 15; n1 < 16; ++n1, --n2)
|
||||
iv[i+1][n1] = ctext[j-n2][0];
|
||||
ptext[0][0] = ctext[j-16][0];
|
||||
break;
|
||||
case CFB1:
|
||||
for(n1=0,n2=127 ; n1 < 128 ; ++n1,--n2)
|
||||
sb(iv[i+1],n1,gb(ctext[j-n2],0));
|
||||
ptext[0][0]=ctext[j-128][0]&0x80;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (imode)
|
||||
{
|
||||
case ECB:
|
||||
memcpy(ctext[0], ptext[j], AES_BLOCK_SIZE);
|
||||
break;
|
||||
case CBC:
|
||||
case OFB:
|
||||
case CFB128:
|
||||
memcpy(iv[i+1], ptext[j], AES_BLOCK_SIZE);
|
||||
memcpy(ctext[0], ptext[j-1], AES_BLOCK_SIZE);
|
||||
break;
|
||||
case CFB8:
|
||||
for (n1 = 0, n2 = 15; n1 < 16; ++n1, --n2)
|
||||
iv[i+1][n1] = ptext[j-n2][0];
|
||||
ctext[0][0] = ptext[j-16][0];
|
||||
break;
|
||||
case CFB1:
|
||||
for(n1=0,n2=127 ; n1 < 128 ; ++n1,--n2)
|
||||
sb(iv[i+1],n1,gb(ptext[j-n2],0));
|
||||
ctext[0][0]=ptext[j-128][0]&0x80;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*================================================*/
|
||||
/*----------------------------
|
||||
# Config info for v-one
|
||||
# AESVS MMT test data for ECB
|
||||
# State : Encrypt and Decrypt
|
||||
# Key Length : 256
|
||||
# Fri Aug 30 04:07:22 PM
|
||||
----------------------------*/
|
||||
|
||||
static int proc_file(char *rqfile, char *rspfile)
|
||||
{
|
||||
char afn[256], rfn[256];
|
||||
FILE *afp = NULL, *rfp = NULL;
|
||||
char ibuf[2048];
|
||||
char tbuf[2048];
|
||||
int ilen, len, ret = 0;
|
||||
char algo[8] = "";
|
||||
char amode[8] = "";
|
||||
char atest[8] = "";
|
||||
int akeysz = 0;
|
||||
unsigned char iVec[20], aKey[40];
|
||||
int dir = -1, err = 0, step = 0;
|
||||
unsigned char plaintext[2048];
|
||||
unsigned char ciphertext[2048];
|
||||
char *rp;
|
||||
EVP_CIPHER_CTX ctx;
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
|
||||
if (!rqfile || !(*rqfile))
|
||||
{
|
||||
printf("No req file\n");
|
||||
return -1;
|
||||
}
|
||||
strcpy(afn, rqfile);
|
||||
|
||||
if ((afp = fopen(afn, "r")) == NULL)
|
||||
{
|
||||
printf("Cannot open file: %s, %s\n",
|
||||
afn, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if (!rspfile)
|
||||
{
|
||||
strcpy(rfn,afn);
|
||||
rp=strstr(rfn,"req/");
|
||||
#ifdef OPENSSL_SYS_WIN32
|
||||
if (!rp)
|
||||
rp=strstr(rfn,"req\\");
|
||||
#endif
|
||||
assert(rp);
|
||||
memcpy(rp,"rsp",3);
|
||||
rp = strstr(rfn, ".req");
|
||||
memcpy(rp, ".rsp", 4);
|
||||
rspfile = rfn;
|
||||
}
|
||||
if ((rfp = fopen(rspfile, "w")) == NULL)
|
||||
{
|
||||
printf("Cannot open file: %s, %s\n",
|
||||
rfn, strerror(errno));
|
||||
fclose(afp);
|
||||
afp = NULL;
|
||||
return -1;
|
||||
}
|
||||
while (!err && (fgets(ibuf, sizeof(ibuf), afp)) != NULL)
|
||||
{
|
||||
tidy_line(tbuf, ibuf);
|
||||
ilen = strlen(ibuf);
|
||||
/* printf("step=%d ibuf=%s",step,ibuf); */
|
||||
switch (step)
|
||||
{
|
||||
case 0: /* read preamble */
|
||||
if (ibuf[0] == '\n')
|
||||
{ /* end of preamble */
|
||||
if ((*algo == '\0') ||
|
||||
(*amode == '\0') ||
|
||||
(akeysz == 0))
|
||||
{
|
||||
printf("Missing Algorithm, Mode or KeySize (%s/%s/%d)\n",
|
||||
algo,amode,akeysz);
|
||||
err = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
fputs(ibuf, rfp);
|
||||
++ step;
|
||||
}
|
||||
}
|
||||
else if (ibuf[0] != '#')
|
||||
{
|
||||
printf("Invalid preamble item: %s\n", ibuf);
|
||||
err = 1;
|
||||
}
|
||||
else
|
||||
{ /* process preamble */
|
||||
char *xp, *pp = ibuf+2;
|
||||
int n;
|
||||
if (akeysz)
|
||||
{ /* insert current time & date */
|
||||
time_t rtim = time(0);
|
||||
fprintf(rfp, "# %s", ctime(&rtim));
|
||||
}
|
||||
else
|
||||
{
|
||||
fputs(ibuf, rfp);
|
||||
if (strncmp(pp, "AESVS ", 6) == 0)
|
||||
{
|
||||
strcpy(algo, "AES");
|
||||
/* get test type */
|
||||
pp += 6;
|
||||
xp = strchr(pp, ' ');
|
||||
n = xp-pp;
|
||||
strncpy(atest, pp, n);
|
||||
atest[n] = '\0';
|
||||
/* get mode */
|
||||
xp = strrchr(pp, ' '); /* get mode" */
|
||||
n = strlen(xp+1)-1;
|
||||
strncpy(amode, xp+1, n);
|
||||
amode[n] = '\0';
|
||||
/* amode[3] = '\0'; */
|
||||
if (VERBOSE)
|
||||
printf("Test = %s, Mode = %s\n", atest, amode);
|
||||
}
|
||||
else if (strncasecmp(pp, "Key Length : ", 13) == 0)
|
||||
{
|
||||
akeysz = atoi(pp+13);
|
||||
if (VERBOSE)
|
||||
printf("Key size = %d\n", akeysz);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: /* [ENCRYPT] | [DECRYPT] */
|
||||
if (ibuf[0] == '[')
|
||||
{
|
||||
fputs(ibuf, rfp);
|
||||
++step;
|
||||
if (strncasecmp(ibuf, "[ENCRYPT]", 9) == 0)
|
||||
dir = 1;
|
||||
else if (strncasecmp(ibuf, "[DECRYPT]", 9) == 0)
|
||||
dir = 0;
|
||||
else
|
||||
{
|
||||
printf("Invalid keyword: %s\n", ibuf);
|
||||
err = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (dir == -1)
|
||||
{
|
||||
err = 1;
|
||||
printf("Missing ENCRYPT/DECRYPT keyword\n");
|
||||
break;
|
||||
}
|
||||
else
|
||||
step = 2;
|
||||
|
||||
case 2: /* KEY = xxxx */
|
||||
fputs(ibuf, rfp);
|
||||
if(*ibuf == '\n')
|
||||
break;
|
||||
if(!strncasecmp(ibuf,"COUNT = ",8))
|
||||
break;
|
||||
|
||||
if (strncasecmp(ibuf, "KEY = ", 6) != 0)
|
||||
{
|
||||
printf("Missing KEY\n");
|
||||
err = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
len = hex2bin((char*)ibuf+6, aKey);
|
||||
if (len < 0)
|
||||
{
|
||||
printf("Invalid KEY\n");
|
||||
err =1;
|
||||
break;
|
||||
}
|
||||
PrintValue("KEY", aKey, len);
|
||||
if (strcmp(amode, "ECB") == 0)
|
||||
{
|
||||
memset(iVec, 0, sizeof(iVec));
|
||||
step = (dir)? 4: 5; /* no ivec for ECB */
|
||||
}
|
||||
else
|
||||
++step;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3: /* IV = xxxx */
|
||||
fputs(ibuf, rfp);
|
||||
if (strncasecmp(ibuf, "IV = ", 5) != 0)
|
||||
{
|
||||
printf("Missing IV\n");
|
||||
err = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
len = hex2bin((char*)ibuf+5, iVec);
|
||||
if (len < 0)
|
||||
{
|
||||
printf("Invalid IV\n");
|
||||
err =1;
|
||||
break;
|
||||
}
|
||||
PrintValue("IV", iVec, len);
|
||||
step = (dir)? 4: 5;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4: /* PLAINTEXT = xxxx */
|
||||
fputs(ibuf, rfp);
|
||||
if (strncasecmp(ibuf, "PLAINTEXT = ", 12) != 0)
|
||||
{
|
||||
printf("Missing PLAINTEXT\n");
|
||||
err = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
int nn = strlen(ibuf+12);
|
||||
if(!strcmp(amode,"CFB1"))
|
||||
len=bint2bin(ibuf+12,nn-1,plaintext);
|
||||
else
|
||||
len=hex2bin(ibuf+12, plaintext);
|
||||
if (len < 0)
|
||||
{
|
||||
printf("Invalid PLAINTEXT: %s", ibuf+12);
|
||||
err =1;
|
||||
break;
|
||||
}
|
||||
if (len >= (int)sizeof(plaintext))
|
||||
{
|
||||
printf("Buffer overflow\n");
|
||||
}
|
||||
PrintValue("PLAINTEXT", (unsigned char*)plaintext, len);
|
||||
if (strcmp(atest, "MCT") == 0) /* Monte Carlo Test */
|
||||
{
|
||||
if(do_mct(amode, akeysz, aKey, iVec,
|
||||
dir, (unsigned char*)plaintext, len,
|
||||
rfp) < 0)
|
||||
EXIT(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = AESTest(&ctx, amode, akeysz, aKey, iVec,
|
||||
dir, /* 0 = decrypt, 1 = encrypt */
|
||||
plaintext, ciphertext, len);
|
||||
OutputValue("CIPHERTEXT",ciphertext,len,rfp,
|
||||
!strcmp(amode,"CFB1"));
|
||||
}
|
||||
step = 6;
|
||||
}
|
||||
break;
|
||||
|
||||
case 5: /* CIPHERTEXT = xxxx */
|
||||
fputs(ibuf, rfp);
|
||||
if (strncasecmp(ibuf, "CIPHERTEXT = ", 13) != 0)
|
||||
{
|
||||
printf("Missing KEY\n");
|
||||
err = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!strcmp(amode,"CFB1"))
|
||||
len=bint2bin(ibuf+13,strlen(ibuf+13)-1,ciphertext);
|
||||
else
|
||||
len = hex2bin(ibuf+13,ciphertext);
|
||||
if (len < 0)
|
||||
{
|
||||
printf("Invalid CIPHERTEXT\n");
|
||||
err =1;
|
||||
break;
|
||||
}
|
||||
|
||||
PrintValue("CIPHERTEXT", ciphertext, len);
|
||||
if (strcmp(atest, "MCT") == 0) /* Monte Carlo Test */
|
||||
{
|
||||
do_mct(amode, akeysz, aKey, iVec,
|
||||
dir, ciphertext, len, rfp);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = AESTest(&ctx, amode, akeysz, aKey, iVec,
|
||||
dir, /* 0 = decrypt, 1 = encrypt */
|
||||
plaintext, ciphertext, len);
|
||||
OutputValue("PLAINTEXT",(unsigned char *)plaintext,len,rfp,
|
||||
!strcmp(amode,"CFB1"));
|
||||
}
|
||||
step = 6;
|
||||
}
|
||||
break;
|
||||
|
||||
case 6:
|
||||
if (ibuf[0] != '\n')
|
||||
{
|
||||
err = 1;
|
||||
printf("Missing terminator\n");
|
||||
}
|
||||
else if (strcmp(atest, "MCT") != 0)
|
||||
{ /* MCT already added terminating nl */
|
||||
fputs(ibuf, rfp);
|
||||
}
|
||||
step = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (rfp)
|
||||
fclose(rfp);
|
||||
if (afp)
|
||||
fclose(afp);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
Processes either a single file or
|
||||
a set of files whose names are passed in a file.
|
||||
A single file is specified as:
|
||||
aes_test -f xxx.req
|
||||
A set of files is specified as:
|
||||
aes_test -d xxxxx.xxx
|
||||
The default is: -d req.txt
|
||||
--------------------------------------------------*/
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *rqlist = "req.txt", *rspfile = NULL;
|
||||
FILE *fp = NULL;
|
||||
char fn[250] = "", rfn[256] = "";
|
||||
int f_opt = 0, d_opt = 1;
|
||||
fips_set_error_print();
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
if(!FIPS_mode_set(1))
|
||||
EXIT(1);
|
||||
#endif
|
||||
if (argc > 1)
|
||||
{
|
||||
if (strcasecmp(argv[1], "-d") == 0)
|
||||
{
|
||||
d_opt = 1;
|
||||
}
|
||||
else if (strcasecmp(argv[1], "-f") == 0)
|
||||
{
|
||||
f_opt = 1;
|
||||
d_opt = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Invalid parameter: %s\n", argv[1]);
|
||||
return 0;
|
||||
}
|
||||
if (argc < 3)
|
||||
{
|
||||
printf("Missing parameter\n");
|
||||
return 0;
|
||||
}
|
||||
if (d_opt)
|
||||
rqlist = argv[2];
|
||||
else
|
||||
{
|
||||
strcpy(fn, argv[2]);
|
||||
rspfile = argv[3];
|
||||
}
|
||||
}
|
||||
if (d_opt)
|
||||
{ /* list of files (directory) */
|
||||
if (!(fp = fopen(rqlist, "r")))
|
||||
{
|
||||
printf("Cannot open req list file\n");
|
||||
return -1;
|
||||
}
|
||||
while (fgets(fn, sizeof(fn), fp))
|
||||
{
|
||||
strtok(fn, "\r\n");
|
||||
strcpy(rfn, fn);
|
||||
if (VERBOSE)
|
||||
printf("Processing: %s\n", rfn);
|
||||
if (proc_file(rfn, rspfile))
|
||||
{
|
||||
printf(">>> Processing failed for: %s <<<\n", rfn);
|
||||
EXIT(1);
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
else /* single file */
|
||||
{
|
||||
if (VERBOSE)
|
||||
printf("Processing: %s\n", fn);
|
||||
if (proc_file(fn, rspfile))
|
||||
{
|
||||
printf(">>> Processing failed for: %s <<<\n", fn);
|
||||
}
|
||||
}
|
||||
EXIT(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
139
fips/des/fips_des_selftest.c
Normal file
139
fips/des/fips_des_selftest.c
Normal file
@ -0,0 +1,139 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2003 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#define OPENSSL_FIPSEVP
|
||||
|
||||
#include <string.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/fips.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
|
||||
static struct
|
||||
{
|
||||
unsigned char key[16];
|
||||
unsigned char plaintext[8];
|
||||
unsigned char ciphertext[8];
|
||||
} tests2[]=
|
||||
{
|
||||
{
|
||||
{ 0x7c,0x4f,0x6e,0xf7,0xa2,0x04,0x16,0xec,
|
||||
0x0b,0x6b,0x7c,0x9e,0x5e,0x19,0xa7,0xc4 },
|
||||
{ 0x06,0xa7,0xd8,0x79,0xaa,0xce,0x69,0xef },
|
||||
{ 0x4c,0x11,0x17,0x55,0xbf,0xc4,0x4e,0xfd }
|
||||
},
|
||||
{
|
||||
{ 0x5d,0x9e,0x01,0xd3,0x25,0xc7,0x3e,0x34,
|
||||
0x01,0x16,0x7c,0x85,0x23,0xdf,0xe0,0x68 },
|
||||
{ 0x9c,0x50,0x09,0x0f,0x5e,0x7d,0x69,0x7e },
|
||||
{ 0xd2,0x0b,0x18,0xdf,0xd9,0x0d,0x9e,0xff },
|
||||
}
|
||||
};
|
||||
|
||||
static struct
|
||||
{
|
||||
unsigned char key[24];
|
||||
unsigned char plaintext[8];
|
||||
unsigned char ciphertext[8];
|
||||
} tests3[]=
|
||||
{
|
||||
{
|
||||
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10,
|
||||
0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0 },
|
||||
{ 0x8f,0x8f,0xbf,0x9b,0x5d,0x48,0xb4,0x1c },
|
||||
{ 0x59,0x8c,0xe5,0xd3,0x6c,0xa2,0xea,0x1b },
|
||||
},
|
||||
{
|
||||
{ 0xDC,0xBA,0x98,0x76,0x54,0x32,0x10,0xFE,
|
||||
0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,
|
||||
0xED,0x39,0xD9,0x50,0xFA,0x74,0xBC,0xC4 },
|
||||
{ 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF },
|
||||
{ 0x11,0x25,0xb0,0x35,0xbe,0xa0,0x82,0x86 },
|
||||
},
|
||||
};
|
||||
|
||||
void FIPS_corrupt_des()
|
||||
{
|
||||
tests2[0].plaintext[0]++;
|
||||
}
|
||||
|
||||
int FIPS_selftest_des()
|
||||
{
|
||||
int n, ret = 0;
|
||||
EVP_CIPHER_CTX ctx;
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
/* Encrypt/decrypt with 2-key 3DES and compare to known answers */
|
||||
for(n=0 ; n < 2 ; ++n)
|
||||
{
|
||||
if (!fips_cipher_test(&ctx, EVP_des_ede_ecb(),
|
||||
tests2[n].key, NULL,
|
||||
tests2[n].plaintext, tests2[n].ciphertext, 8))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Encrypt/decrypt with 3DES and compare to known answers */
|
||||
for(n=0 ; n < 2 ; ++n)
|
||||
{
|
||||
if (!fips_cipher_test(&ctx, EVP_des_ede3_ecb(),
|
||||
tests3[n].key, NULL,
|
||||
tests3[n].plaintext, tests3[n].ciphertext, 8))
|
||||
goto err;
|
||||
}
|
||||
ret = 1;
|
||||
err:
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
if (ret == 0)
|
||||
FIPSerr(FIPS_F_FIPS_SELFTEST_DES,FIPS_R_SELFTEST_FAILED);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
702
fips/des/fips_desmovs.c
Normal file
702
fips/des/fips_desmovs.c
Normal file
@ -0,0 +1,702 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2004 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
/*---------------------------------------------
|
||||
NIST DES Modes of Operation Validation System
|
||||
Test Program
|
||||
|
||||
Based on the AES Validation Suite, which was:
|
||||
Donated to OpenSSL by:
|
||||
V-ONE Corporation
|
||||
20250 Century Blvd, Suite 300
|
||||
Germantown, MD 20874
|
||||
U.S.A.
|
||||
----------------------------------------------*/
|
||||
|
||||
#define OPENSSL_FIPSEVP
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <openssl/des.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include "e_os.h"
|
||||
|
||||
#ifndef OPENSSL_FIPS
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
printf("No FIPS DES support\n");
|
||||
return(0);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <openssl/fips.h>
|
||||
#include "fips_utl.h"
|
||||
|
||||
#define DES_BLOCK_SIZE 8
|
||||
|
||||
#define VERBOSE 0
|
||||
|
||||
static int DESTest(EVP_CIPHER_CTX *ctx,
|
||||
char *amode, int akeysz, unsigned char *aKey,
|
||||
unsigned char *iVec,
|
||||
int dir, /* 0 = decrypt, 1 = encrypt */
|
||||
unsigned char *out, unsigned char *in, int len)
|
||||
{
|
||||
const EVP_CIPHER *cipher = NULL;
|
||||
|
||||
if (akeysz != 192)
|
||||
{
|
||||
printf("Invalid key size: %d\n", akeysz);
|
||||
EXIT(1);
|
||||
}
|
||||
|
||||
if (strcasecmp(amode, "CBC") == 0)
|
||||
cipher = EVP_des_ede3_cbc();
|
||||
else if (strcasecmp(amode, "ECB") == 0)
|
||||
cipher = EVP_des_ede3_ecb();
|
||||
else if (strcasecmp(amode, "CFB64") == 0)
|
||||
cipher = EVP_des_ede3_cfb64();
|
||||
else if (strncasecmp(amode, "OFB", 3) == 0)
|
||||
cipher = EVP_des_ede3_ofb();
|
||||
else if(!strcasecmp(amode,"CFB8"))
|
||||
cipher = EVP_des_ede3_cfb8();
|
||||
else if(!strcasecmp(amode,"CFB1"))
|
||||
cipher = EVP_des_ede3_cfb1();
|
||||
else
|
||||
{
|
||||
printf("Unknown mode: %s\n", amode);
|
||||
EXIT(1);
|
||||
}
|
||||
|
||||
if (EVP_CipherInit_ex(ctx, cipher, NULL, aKey, iVec, dir) <= 0)
|
||||
return 0;
|
||||
if(!strcasecmp(amode,"CFB1"))
|
||||
M_EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS);
|
||||
EVP_Cipher(ctx, out, in, len);
|
||||
|
||||
return 1;
|
||||
}
|
||||
#if 0
|
||||
static void DebugValue(char *tag, unsigned char *val, int len)
|
||||
{
|
||||
char obuf[2048];
|
||||
int olen;
|
||||
olen = bin2hex(val, len, obuf);
|
||||
printf("%s = %.*s\n", tag, olen, obuf);
|
||||
}
|
||||
#endif
|
||||
static void shiftin(unsigned char *dst,unsigned char *src,int nbits)
|
||||
{
|
||||
int n;
|
||||
|
||||
/* move the bytes... */
|
||||
memmove(dst,dst+nbits/8,3*8-nbits/8);
|
||||
/* append new data */
|
||||
memcpy(dst+3*8-nbits/8,src,(nbits+7)/8);
|
||||
/* left shift the bits */
|
||||
if(nbits%8)
|
||||
for(n=0 ; n < 3*8 ; ++n)
|
||||
dst[n]=(dst[n] << (nbits%8))|(dst[n+1] >> (8-nbits%8));
|
||||
}
|
||||
|
||||
/*-----------------------------------------------*/
|
||||
char *t_tag[2] = {"PLAINTEXT", "CIPHERTEXT"};
|
||||
char *t_mode[6] = {"CBC","ECB","OFB","CFB1","CFB8","CFB64"};
|
||||
enum Mode {CBC, ECB, OFB, CFB1, CFB8, CFB64};
|
||||
int Sizes[6]={64,64,64,1,8,64};
|
||||
|
||||
static void do_mct(char *amode,
|
||||
int akeysz, int numkeys, unsigned char *akey,unsigned char *ivec,
|
||||
int dir, unsigned char *text, int len,
|
||||
FILE *rfp)
|
||||
{
|
||||
int i,imode;
|
||||
unsigned char nk[4*8]; /* longest key+8 */
|
||||
unsigned char text0[8];
|
||||
|
||||
for (imode=0 ; imode < 6 ; ++imode)
|
||||
if(!strcmp(amode,t_mode[imode]))
|
||||
break;
|
||||
if (imode == 6)
|
||||
{
|
||||
printf("Unrecognized mode: %s\n", amode);
|
||||
EXIT(1);
|
||||
}
|
||||
|
||||
for(i=0 ; i < 400 ; ++i)
|
||||
{
|
||||
int j;
|
||||
int n;
|
||||
int kp=akeysz/64;
|
||||
unsigned char old_iv[8];
|
||||
EVP_CIPHER_CTX ctx;
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
|
||||
fprintf(rfp,"\nCOUNT = %d\n",i);
|
||||
if(kp == 1)
|
||||
OutputValue("KEY",akey,8,rfp,0);
|
||||
else
|
||||
for(n=0 ; n < kp ; ++n)
|
||||
{
|
||||
fprintf(rfp,"KEY%d",n+1);
|
||||
OutputValue("",akey+n*8,8,rfp,0);
|
||||
}
|
||||
|
||||
if(imode != ECB)
|
||||
OutputValue("IV",ivec,8,rfp,0);
|
||||
OutputValue(t_tag[dir^1],text,len,rfp,imode == CFB1);
|
||||
#if 0
|
||||
/* compensate for endianness */
|
||||
if(imode == CFB1)
|
||||
text[0]<<=7;
|
||||
#endif
|
||||
memcpy(text0,text,8);
|
||||
|
||||
for(j=0 ; j < 10000 ; ++j)
|
||||
{
|
||||
unsigned char old_text[8];
|
||||
|
||||
memcpy(old_text,text,8);
|
||||
if(j == 0)
|
||||
{
|
||||
memcpy(old_iv,ivec,8);
|
||||
DESTest(&ctx,amode,akeysz,akey,ivec,dir,text,text,len);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(old_iv,ctx.iv,8);
|
||||
EVP_Cipher(&ctx,text,text,len);
|
||||
}
|
||||
if(j == 9999)
|
||||
{
|
||||
OutputValue(t_tag[dir],text,len,rfp,imode == CFB1);
|
||||
/* memcpy(ivec,text,8); */
|
||||
}
|
||||
/* DebugValue("iv",ctx.iv,8); */
|
||||
/* accumulate material for the next key */
|
||||
shiftin(nk,text,Sizes[imode]);
|
||||
/* DebugValue("nk",nk,24);*/
|
||||
if((dir && (imode == CFB1 || imode == CFB8 || imode == CFB64
|
||||
|| imode == CBC)) || imode == OFB)
|
||||
memcpy(text,old_iv,8);
|
||||
|
||||
if(!dir && (imode == CFB1 || imode == CFB8 || imode == CFB64))
|
||||
{
|
||||
/* the test specifies using the output of the raw DES operation
|
||||
which we don't have, so reconstruct it... */
|
||||
for(n=0 ; n < 8 ; ++n)
|
||||
text[n]^=old_text[n];
|
||||
}
|
||||
}
|
||||
for(n=0 ; n < 8 ; ++n)
|
||||
akey[n]^=nk[16+n];
|
||||
for(n=0 ; n < 8 ; ++n)
|
||||
akey[8+n]^=nk[8+n];
|
||||
for(n=0 ; n < 8 ; ++n)
|
||||
akey[16+n]^=nk[n];
|
||||
if(numkeys < 3)
|
||||
memcpy(&akey[2*8],akey,8);
|
||||
if(numkeys < 2)
|
||||
memcpy(&akey[8],akey,8);
|
||||
DES_set_odd_parity((DES_cblock *)akey);
|
||||
DES_set_odd_parity((DES_cblock *)(akey+8));
|
||||
DES_set_odd_parity((DES_cblock *)(akey+16));
|
||||
memcpy(ivec,ctx.iv,8);
|
||||
|
||||
/* pointless exercise - the final text doesn't depend on the
|
||||
initial text in OFB mode, so who cares what it is? (Who
|
||||
designed these tests?) */
|
||||
if(imode == OFB)
|
||||
for(n=0 ; n < 8 ; ++n)
|
||||
text[n]=text0[n]^old_iv[n];
|
||||
}
|
||||
}
|
||||
|
||||
static int proc_file(char *rqfile, char *rspfile)
|
||||
{
|
||||
char afn[256], rfn[256];
|
||||
FILE *afp = NULL, *rfp = NULL;
|
||||
char ibuf[2048], tbuf[2048];
|
||||
int ilen, len, ret = 0;
|
||||
char amode[8] = "";
|
||||
char atest[100] = "";
|
||||
int akeysz=0;
|
||||
unsigned char iVec[20], aKey[40];
|
||||
int dir = -1, err = 0, step = 0;
|
||||
unsigned char plaintext[2048];
|
||||
unsigned char ciphertext[2048];
|
||||
char *rp;
|
||||
EVP_CIPHER_CTX ctx;
|
||||
int numkeys=1;
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
|
||||
if (!rqfile || !(*rqfile))
|
||||
{
|
||||
printf("No req file\n");
|
||||
return -1;
|
||||
}
|
||||
strcpy(afn, rqfile);
|
||||
|
||||
if ((afp = fopen(afn, "r")) == NULL)
|
||||
{
|
||||
printf("Cannot open file: %s, %s\n",
|
||||
afn, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if (!rspfile)
|
||||
{
|
||||
strcpy(rfn,afn);
|
||||
rp=strstr(rfn,"req/");
|
||||
#ifdef OPENSSL_SYS_WIN32
|
||||
if (!rp)
|
||||
rp=strstr(rfn,"req\\");
|
||||
#endif
|
||||
assert(rp);
|
||||
memcpy(rp,"rsp",3);
|
||||
rp = strstr(rfn, ".req");
|
||||
memcpy(rp, ".rsp", 4);
|
||||
rspfile = rfn;
|
||||
}
|
||||
if ((rfp = fopen(rspfile, "w")) == NULL)
|
||||
{
|
||||
printf("Cannot open file: %s, %s\n",
|
||||
rfn, strerror(errno));
|
||||
fclose(afp);
|
||||
afp = NULL;
|
||||
return -1;
|
||||
}
|
||||
while (!err && (fgets(ibuf, sizeof(ibuf), afp)) != NULL)
|
||||
{
|
||||
tidy_line(tbuf, ibuf);
|
||||
ilen = strlen(ibuf);
|
||||
/* printf("step=%d ibuf=%s",step,ibuf);*/
|
||||
if(step == 3 && !strcmp(amode,"ECB"))
|
||||
{
|
||||
memset(iVec, 0, sizeof(iVec));
|
||||
step = (dir)? 4: 5; /* no ivec for ECB */
|
||||
}
|
||||
switch (step)
|
||||
{
|
||||
case 0: /* read preamble */
|
||||
if (ibuf[0] == '\n')
|
||||
{ /* end of preamble */
|
||||
if (*amode == '\0')
|
||||
{
|
||||
printf("Missing Mode\n");
|
||||
err = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
fputs(ibuf, rfp);
|
||||
++ step;
|
||||
}
|
||||
}
|
||||
else if (ibuf[0] != '#')
|
||||
{
|
||||
printf("Invalid preamble item: %s\n", ibuf);
|
||||
err = 1;
|
||||
}
|
||||
else
|
||||
{ /* process preamble */
|
||||
char *xp, *pp = ibuf+2;
|
||||
int n;
|
||||
if(*amode)
|
||||
{ /* insert current time & date */
|
||||
time_t rtim = time(0);
|
||||
fprintf(rfp, "# %s", ctime(&rtim));
|
||||
}
|
||||
else
|
||||
{
|
||||
fputs(ibuf, rfp);
|
||||
if(!strncmp(pp,"INVERSE ",8) || !strncmp(pp,"DES ",4)
|
||||
|| !strncmp(pp,"TDES ",5)
|
||||
|| !strncmp(pp,"PERMUTATION ",12)
|
||||
|| !strncmp(pp,"SUBSTITUTION ",13)
|
||||
|| !strncmp(pp,"VARIABLE ",9))
|
||||
{
|
||||
/* get test type */
|
||||
if(!strncmp(pp,"DES ",4))
|
||||
pp+=4;
|
||||
else if(!strncmp(pp,"TDES ",5))
|
||||
pp+=5;
|
||||
xp = strchr(pp, ' ');
|
||||
n = xp-pp;
|
||||
strncpy(atest, pp, n);
|
||||
atest[n] = '\0';
|
||||
/* get mode */
|
||||
xp = strrchr(pp, ' '); /* get mode" */
|
||||
n = strlen(xp+1)-1;
|
||||
strncpy(amode, xp+1, n);
|
||||
amode[n] = '\0';
|
||||
/* amode[3] = '\0'; */
|
||||
if (VERBOSE)
|
||||
printf("Test=%s, Mode=%s\n",atest,amode);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: /* [ENCRYPT] | [DECRYPT] */
|
||||
if(ibuf[0] == '\n')
|
||||
break;
|
||||
if (ibuf[0] == '[')
|
||||
{
|
||||
fputs(ibuf, rfp);
|
||||
++step;
|
||||
if (strncasecmp(ibuf, "[ENCRYPT]", 9) == 0)
|
||||
dir = 1;
|
||||
else if (strncasecmp(ibuf, "[DECRYPT]", 9) == 0)
|
||||
dir = 0;
|
||||
else
|
||||
{
|
||||
printf("Invalid keyword: %s\n", ibuf);
|
||||
err = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (dir == -1)
|
||||
{
|
||||
err = 1;
|
||||
printf("Missing ENCRYPT/DECRYPT keyword\n");
|
||||
break;
|
||||
}
|
||||
else
|
||||
step = 2;
|
||||
|
||||
case 2: /* KEY = xxxx */
|
||||
if(*ibuf == '\n')
|
||||
{
|
||||
fputs(ibuf, rfp);
|
||||
break;
|
||||
}
|
||||
if(!strncasecmp(ibuf,"COUNT = ",8))
|
||||
{
|
||||
fputs(ibuf, rfp);
|
||||
break;
|
||||
}
|
||||
if(!strncasecmp(ibuf,"COUNT=",6))
|
||||
{
|
||||
fputs(ibuf, rfp);
|
||||
break;
|
||||
}
|
||||
if(!strncasecmp(ibuf,"NumKeys = ",10))
|
||||
{
|
||||
numkeys=atoi(ibuf+10);
|
||||
break;
|
||||
}
|
||||
|
||||
fputs(ibuf, rfp);
|
||||
if(!strncasecmp(ibuf,"KEY = ",6))
|
||||
{
|
||||
akeysz=64;
|
||||
len = hex2bin((char*)ibuf+6, aKey);
|
||||
if (len < 0)
|
||||
{
|
||||
printf("Invalid KEY\n");
|
||||
err=1;
|
||||
break;
|
||||
}
|
||||
PrintValue("KEY", aKey, len);
|
||||
++step;
|
||||
}
|
||||
else if(!strncasecmp(ibuf,"KEYs = ",7))
|
||||
{
|
||||
akeysz=64*3;
|
||||
len=hex2bin(ibuf+7,aKey);
|
||||
if(len != 8)
|
||||
{
|
||||
printf("Invalid KEY\n");
|
||||
err=1;
|
||||
break;
|
||||
}
|
||||
memcpy(aKey+8,aKey,8);
|
||||
memcpy(aKey+16,aKey,8);
|
||||
ibuf[4]='\0';
|
||||
PrintValue("KEYs",aKey,len);
|
||||
++step;
|
||||
}
|
||||
else if(!strncasecmp(ibuf,"KEY",3))
|
||||
{
|
||||
int n=ibuf[3]-'1';
|
||||
|
||||
akeysz=64*3;
|
||||
len=hex2bin(ibuf+7,aKey+n*8);
|
||||
if(len != 8)
|
||||
{
|
||||
printf("Invalid KEY\n");
|
||||
err=1;
|
||||
break;
|
||||
}
|
||||
ibuf[4]='\0';
|
||||
PrintValue(ibuf,aKey,len);
|
||||
if(n == 2)
|
||||
++step;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Missing KEY\n");
|
||||
err = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3: /* IV = xxxx */
|
||||
fputs(ibuf, rfp);
|
||||
if (strncasecmp(ibuf, "IV = ", 5) != 0)
|
||||
{
|
||||
printf("Missing IV\n");
|
||||
err = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
len = hex2bin((char*)ibuf+5, iVec);
|
||||
if (len < 0)
|
||||
{
|
||||
printf("Invalid IV\n");
|
||||
err =1;
|
||||
break;
|
||||
}
|
||||
PrintValue("IV", iVec, len);
|
||||
step = (dir)? 4: 5;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4: /* PLAINTEXT = xxxx */
|
||||
fputs(ibuf, rfp);
|
||||
if (strncasecmp(ibuf, "PLAINTEXT = ", 12) != 0)
|
||||
{
|
||||
printf("Missing PLAINTEXT\n");
|
||||
err = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
int nn = strlen(ibuf+12);
|
||||
if(!strcmp(amode,"CFB1"))
|
||||
len=bint2bin(ibuf+12,nn-1,plaintext);
|
||||
else
|
||||
len=hex2bin(ibuf+12, plaintext);
|
||||
if (len < 0)
|
||||
{
|
||||
printf("Invalid PLAINTEXT: %s", ibuf+12);
|
||||
err =1;
|
||||
break;
|
||||
}
|
||||
if (len >= (int)sizeof(plaintext))
|
||||
{
|
||||
printf("Buffer overflow\n");
|
||||
}
|
||||
PrintValue("PLAINTEXT", (unsigned char*)plaintext, len);
|
||||
if (strcmp(atest, "Monte") == 0) /* Monte Carlo Test */
|
||||
{
|
||||
do_mct(amode,akeysz,numkeys,aKey,iVec,dir,plaintext,len,rfp);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(dir == 1);
|
||||
ret = DESTest(&ctx, amode, akeysz, aKey, iVec,
|
||||
dir, /* 0 = decrypt, 1 = encrypt */
|
||||
ciphertext, plaintext, len);
|
||||
OutputValue("CIPHERTEXT",ciphertext,len,rfp,
|
||||
!strcmp(amode,"CFB1"));
|
||||
}
|
||||
step = 6;
|
||||
}
|
||||
break;
|
||||
|
||||
case 5: /* CIPHERTEXT = xxxx */
|
||||
fputs(ibuf, rfp);
|
||||
if (strncasecmp(ibuf, "CIPHERTEXT = ", 13) != 0)
|
||||
{
|
||||
printf("Missing KEY\n");
|
||||
err = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!strcmp(amode,"CFB1"))
|
||||
len=bint2bin(ibuf+13,strlen(ibuf+13)-1,ciphertext);
|
||||
else
|
||||
len = hex2bin(ibuf+13,ciphertext);
|
||||
if (len < 0)
|
||||
{
|
||||
printf("Invalid CIPHERTEXT\n");
|
||||
err =1;
|
||||
break;
|
||||
}
|
||||
|
||||
PrintValue("CIPHERTEXT", ciphertext, len);
|
||||
if (strcmp(atest, "Monte") == 0) /* Monte Carlo Test */
|
||||
{
|
||||
do_mct(amode, akeysz, numkeys, aKey, iVec,
|
||||
dir, ciphertext, len, rfp);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(dir == 0);
|
||||
ret = DESTest(&ctx, amode, akeysz, aKey, iVec,
|
||||
dir, /* 0 = decrypt, 1 = encrypt */
|
||||
plaintext, ciphertext, len);
|
||||
OutputValue("PLAINTEXT",(unsigned char *)plaintext,len,rfp,
|
||||
!strcmp(amode,"CFB1"));
|
||||
}
|
||||
step = 6;
|
||||
}
|
||||
break;
|
||||
|
||||
case 6:
|
||||
if (ibuf[0] != '\n')
|
||||
{
|
||||
err = 1;
|
||||
printf("Missing terminator\n");
|
||||
}
|
||||
else if (strcmp(atest, "MCT") != 0)
|
||||
{ /* MCT already added terminating nl */
|
||||
fputs(ibuf, rfp);
|
||||
}
|
||||
step = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (rfp)
|
||||
fclose(rfp);
|
||||
if (afp)
|
||||
fclose(afp);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
Processes either a single file or
|
||||
a set of files whose names are passed in a file.
|
||||
A single file is specified as:
|
||||
aes_test -f xxx.req
|
||||
A set of files is specified as:
|
||||
aes_test -d xxxxx.xxx
|
||||
The default is: -d req.txt
|
||||
--------------------------------------------------*/
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *rqlist = "req.txt", *rspfile = NULL;
|
||||
FILE *fp = NULL;
|
||||
char fn[250] = "", rfn[256] = "";
|
||||
int f_opt = 0, d_opt = 1;
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
fips_set_error_print();
|
||||
if(!FIPS_mode_set(1))
|
||||
EXIT(1);
|
||||
#endif
|
||||
if (argc > 1)
|
||||
{
|
||||
if (strcasecmp(argv[1], "-d") == 0)
|
||||
{
|
||||
d_opt = 1;
|
||||
}
|
||||
else if (strcasecmp(argv[1], "-f") == 0)
|
||||
{
|
||||
f_opt = 1;
|
||||
d_opt = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Invalid parameter: %s\n", argv[1]);
|
||||
return 0;
|
||||
}
|
||||
if (argc < 3)
|
||||
{
|
||||
printf("Missing parameter\n");
|
||||
return 0;
|
||||
}
|
||||
if (d_opt)
|
||||
rqlist = argv[2];
|
||||
else
|
||||
{
|
||||
strcpy(fn, argv[2]);
|
||||
rspfile = argv[3];
|
||||
}
|
||||
}
|
||||
if (d_opt)
|
||||
{ /* list of files (directory) */
|
||||
if (!(fp = fopen(rqlist, "r")))
|
||||
{
|
||||
printf("Cannot open req list file\n");
|
||||
return -1;
|
||||
}
|
||||
while (fgets(fn, sizeof(fn), fp))
|
||||
{
|
||||
strtok(fn, "\r\n");
|
||||
strcpy(rfn, fn);
|
||||
printf("Processing: %s\n", rfn);
|
||||
if (proc_file(rfn, rspfile))
|
||||
{
|
||||
printf(">>> Processing failed for: %s <<<\n", rfn);
|
||||
EXIT(1);
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
else /* single file */
|
||||
{
|
||||
if (VERBOSE)
|
||||
printf("Processing: %s\n", fn);
|
||||
if (proc_file(fn, rspfile))
|
||||
{
|
||||
printf(">>> Processing failed for: %s <<<\n", fn);
|
||||
}
|
||||
}
|
||||
EXIT(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
4
fips/dh/.cvsignore
Normal file
4
fips/dh/.cvsignore
Normal file
@ -0,0 +1,4 @@
|
||||
lib
|
||||
*.flc
|
||||
semantic.cache
|
||||
Makefile.save
|
115
fips/dh/Makefile
Normal file
115
fips/dh/Makefile
Normal file
@ -0,0 +1,115 @@
|
||||
#
|
||||
# OpenSSL/fips/dh/Makefile
|
||||
#
|
||||
|
||||
DIR= dh
|
||||
TOP= ../..
|
||||
CC= cc
|
||||
INCLUDES=
|
||||
CFLAG=-g
|
||||
INSTALL_PREFIX=
|
||||
OPENSSLDIR= /usr/local/ssl
|
||||
INSTALLTOP=/usr/local/ssl
|
||||
MAKEDEPPROG= makedepend
|
||||
MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
|
||||
MAKEFILE= Makefile
|
||||
AR= ar r
|
||||
|
||||
CFLAGS= $(INCLUDES) $(CFLAG)
|
||||
|
||||
GENERAL=Makefile
|
||||
TEST=
|
||||
APPS=
|
||||
|
||||
LIB=$(TOP)/libcrypto.a
|
||||
LIBSRC= fips_dh_lib.c
|
||||
LIBOBJ= fips_dh_lib.o
|
||||
|
||||
SRC= $(LIBSRC)
|
||||
|
||||
EXHEADER=
|
||||
HEADER= $(EXHEADER)
|
||||
|
||||
ALL= $(GENERAL) $(SRC) $(HEADER)
|
||||
|
||||
top:
|
||||
(cd $(TOP); $(MAKE) DIRS=fips FDIRS=$(DIR) sub_all)
|
||||
|
||||
all: lib
|
||||
|
||||
lib: $(LIBOBJ)
|
||||
@echo $(LIBOBJ) > lib
|
||||
|
||||
files:
|
||||
$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
|
||||
|
||||
links:
|
||||
@$(PERL) $(TOP)/util/mklink.pl $(TOP)/include/openssl $(EXHEADER)
|
||||
@$(PERL) $(TOP)/util/mklink.pl $(TOP)/test $(TEST)
|
||||
@$(PERL) $(TOP)/util/mklink.pl $(TOP)/apps $(APPS)
|
||||
|
||||
install:
|
||||
@headerlist="$(EXHEADER)"; for i in $$headerlist; \
|
||||
do \
|
||||
(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
|
||||
chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
|
||||
done
|
||||
|
||||
tags:
|
||||
ctags $(SRC)
|
||||
|
||||
tests:
|
||||
|
||||
fips_test:
|
||||
|
||||
lint:
|
||||
lint -DLINT $(INCLUDES) $(SRC)>fluff
|
||||
|
||||
depend:
|
||||
$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(SRC) $(TEST)
|
||||
|
||||
dclean:
|
||||
$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
|
||||
mv -f Makefile.new $(MAKEFILE)
|
||||
|
||||
clean:
|
||||
rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
|
||||
|
||||
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
||||
|
||||
fips_dh_check.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
|
||||
fips_dh_check.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
|
||||
fips_dh_check.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
|
||||
fips_dh_check.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
|
||||
fips_dh_check.o: ../../include/openssl/opensslconf.h
|
||||
fips_dh_check.o: ../../include/openssl/opensslv.h
|
||||
fips_dh_check.o: ../../include/openssl/ossl_typ.h
|
||||
fips_dh_check.o: ../../include/openssl/safestack.h
|
||||
fips_dh_check.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
|
||||
fips_dh_check.o: fips_dh_check.c
|
||||
fips_dh_gen.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
|
||||
fips_dh_gen.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
|
||||
fips_dh_gen.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
|
||||
fips_dh_gen.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
|
||||
fips_dh_gen.o: ../../include/openssl/opensslconf.h
|
||||
fips_dh_gen.o: ../../include/openssl/opensslv.h
|
||||
fips_dh_gen.o: ../../include/openssl/ossl_typ.h
|
||||
fips_dh_gen.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
|
||||
fips_dh_gen.o: ../../include/openssl/symhacks.h fips_dh_gen.c
|
||||
fips_dh_key.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
|
||||
fips_dh_key.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
|
||||
fips_dh_key.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
|
||||
fips_dh_key.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
|
||||
fips_dh_key.o: ../../include/openssl/opensslconf.h
|
||||
fips_dh_key.o: ../../include/openssl/opensslv.h
|
||||
fips_dh_key.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
|
||||
fips_dh_key.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
|
||||
fips_dh_key.o: ../../include/openssl/symhacks.h fips_dh_key.c
|
||||
fips_dh_lib.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
|
||||
fips_dh_lib.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
|
||||
fips_dh_lib.o: ../../include/openssl/e_os2.h
|
||||
fips_dh_lib.o: ../../include/openssl/opensslconf.h
|
||||
fips_dh_lib.o: ../../include/openssl/opensslv.h
|
||||
fips_dh_lib.o: ../../include/openssl/ossl_typ.h
|
||||
fips_dh_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
|
||||
fips_dh_lib.o: ../../include/openssl/symhacks.h fips_dh_lib.c
|
95
fips/dh/fips_dh_lib.c
Normal file
95
fips/dh/fips_dh_lib.c
Normal file
@ -0,0 +1,95 @@
|
||||
/* fips_dh_lib.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2007.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2007 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/dh.h>
|
||||
|
||||
/* Minimal FIPS versions of FIPS_dh_new() and FIPS_dh_free(): to
|
||||
* reduce external dependencies.
|
||||
*/
|
||||
|
||||
DH *FIPS_dh_new(void)
|
||||
{
|
||||
DH *ret;
|
||||
ret = OPENSSL_malloc(sizeof(DH));
|
||||
if (!ret)
|
||||
return NULL;
|
||||
memset(ret, 0, sizeof(DH));
|
||||
ret->meth = DH_OpenSSL();
|
||||
if (ret->meth->init)
|
||||
ret->meth->init(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void FIPS_dh_free(DH *r)
|
||||
{
|
||||
if (!r)
|
||||
return;
|
||||
if (r->meth->finish)
|
||||
r->meth->finish(r);
|
||||
if (r->p != NULL) BN_clear_free(r->p);
|
||||
if (r->g != NULL) BN_clear_free(r->g);
|
||||
if (r->q != NULL) BN_clear_free(r->q);
|
||||
if (r->j != NULL) BN_clear_free(r->j);
|
||||
if (r->seed) OPENSSL_free(r->seed);
|
||||
if (r->counter != NULL) BN_clear_free(r->counter);
|
||||
if (r->pub_key != NULL) BN_clear_free(r->pub_key);
|
||||
if (r->priv_key != NULL) BN_clear_free(r->priv_key);
|
||||
OPENSSL_free(r);
|
||||
}
|
4
fips/dsa/.cvsignore
Normal file
4
fips/dsa/.cvsignore
Normal file
@ -0,0 +1,4 @@
|
||||
lib
|
||||
Makefile.save
|
||||
*.flc
|
||||
semantic.cache
|
191
fips/dsa/Makefile
Normal file
191
fips/dsa/Makefile
Normal file
@ -0,0 +1,191 @@
|
||||
#
|
||||
# OpenSSL/fips/dsa/Makefile
|
||||
#
|
||||
|
||||
DIR= dsa
|
||||
TOP= ../..
|
||||
CC= cc
|
||||
INCLUDES=
|
||||
CFLAG=-g
|
||||
INSTALL_PREFIX=
|
||||
OPENSSLDIR= /usr/local/ssl
|
||||
INSTALLTOP=/usr/local/ssl
|
||||
MAKEDEPPROG= makedepend
|
||||
MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
|
||||
MAKEFILE= Makefile
|
||||
AR= ar r
|
||||
|
||||
CFLAGS= $(INCLUDES) $(CFLAG)
|
||||
|
||||
GENERAL=Makefile
|
||||
TEST=fips_dsatest.c fips_dssvs.c
|
||||
APPS=
|
||||
|
||||
LIB=$(TOP)/libcrypto.a
|
||||
LIBSRC= fips_dsa_selftest.c \
|
||||
fips_dsa_lib.c fips_dsa_sign.c
|
||||
LIBOBJ= fips_dsa_selftest.o \
|
||||
fips_dsa_lib.o fips_dsa_sign.o
|
||||
|
||||
SRC= $(LIBSRC)
|
||||
|
||||
EXHEADER=
|
||||
HEADER= $(EXHEADER)
|
||||
|
||||
ALL= $(GENERAL) $(SRC) $(HEADER)
|
||||
|
||||
top:
|
||||
(cd $(TOP); $(MAKE) DIRS=fips FDIRS=$(DIR) sub_all)
|
||||
|
||||
all: lib
|
||||
|
||||
lib: $(LIBOBJ)
|
||||
@echo $(LIBOBJ) > lib
|
||||
|
||||
files:
|
||||
$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
|
||||
|
||||
links:
|
||||
@$(PERL) $(TOP)/util/mklink.pl $(TOP)/include/openssl $(EXHEADER)
|
||||
@$(PERL) $(TOP)/util/mklink.pl $(TOP)/test $(TEST)
|
||||
@$(PERL) $(TOP)/util/mklink.pl $(TOP)/apps $(APPS)
|
||||
|
||||
install:
|
||||
@headerlist="$(EXHEADER)"; for i in $$headerlist; \
|
||||
do \
|
||||
(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
|
||||
chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
|
||||
done
|
||||
|
||||
tags:
|
||||
ctags $(SRC)
|
||||
|
||||
tests:
|
||||
|
||||
Q=../testvectors/dsa/req
|
||||
A=../testvectors/dsa/rsp
|
||||
|
||||
fips_test:
|
||||
-rm -rf $A
|
||||
mkdir $A
|
||||
if [ -f $(Q)/PQGGen.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_dssvs pqg < $(Q)/PQGGen.req > $(A)/PQGGen.rsp; fi
|
||||
if [ -f $(Q)/KeyPair.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_dssvs keypair < $(Q)/KeyPair.req > $(A)/KeyPair.rsp; fi
|
||||
if [ -f $(Q)/SigGen.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_dssvs siggen < $(Q)/SigGen.req > $(A)/SigGen.rsp; fi
|
||||
if [ -f $(Q)/SigVer.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_dssvs sigver < $Q/SigVer.req > $A/SigVer.rsp; fi
|
||||
|
||||
lint:
|
||||
lint -DLINT $(INCLUDES) $(SRC)>fluff
|
||||
|
||||
depend:
|
||||
$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(SRC) $(TEST)
|
||||
|
||||
dclean:
|
||||
$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
|
||||
mv -f Makefile.new $(MAKEFILE)
|
||||
|
||||
clean:
|
||||
rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
|
||||
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
||||
|
||||
fips_dsa_gen.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
|
||||
fips_dsa_gen.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
|
||||
fips_dsa_gen.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
|
||||
fips_dsa_gen.o: ../../include/openssl/err.h ../../include/openssl/evp.h
|
||||
fips_dsa_gen.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
|
||||
fips_dsa_gen.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
|
||||
fips_dsa_gen.o: ../../include/openssl/opensslconf.h
|
||||
fips_dsa_gen.o: ../../include/openssl/opensslv.h
|
||||
fips_dsa_gen.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
|
||||
fips_dsa_gen.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
|
||||
fips_dsa_gen.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
|
||||
fips_dsa_gen.o: fips_dsa_gen.c
|
||||
fips_dsa_key.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
|
||||
fips_dsa_key.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
|
||||
fips_dsa_key.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
|
||||
fips_dsa_key.o: ../../include/openssl/err.h ../../include/openssl/evp.h
|
||||
fips_dsa_key.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
|
||||
fips_dsa_key.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
|
||||
fips_dsa_key.o: ../../include/openssl/opensslconf.h
|
||||
fips_dsa_key.o: ../../include/openssl/opensslv.h
|
||||
fips_dsa_key.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
|
||||
fips_dsa_key.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
|
||||
fips_dsa_key.o: ../../include/openssl/symhacks.h ../fips_locl.h fips_dsa_key.c
|
||||
fips_dsa_lib.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
|
||||
fips_dsa_lib.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
|
||||
fips_dsa_lib.o: ../../include/openssl/e_os2.h
|
||||
fips_dsa_lib.o: ../../include/openssl/opensslconf.h
|
||||
fips_dsa_lib.o: ../../include/openssl/opensslv.h
|
||||
fips_dsa_lib.o: ../../include/openssl/ossl_typ.h
|
||||
fips_dsa_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
|
||||
fips_dsa_lib.o: ../../include/openssl/symhacks.h fips_dsa_lib.c
|
||||
fips_dsa_ossl.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
|
||||
fips_dsa_ossl.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
|
||||
fips_dsa_ossl.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
|
||||
fips_dsa_ossl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
|
||||
fips_dsa_ossl.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
|
||||
fips_dsa_ossl.o: ../../include/openssl/engine.h ../../include/openssl/err.h
|
||||
fips_dsa_ossl.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
|
||||
fips_dsa_ossl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
|
||||
fips_dsa_ossl.o: ../../include/openssl/objects.h
|
||||
fips_dsa_ossl.o: ../../include/openssl/opensslconf.h
|
||||
fips_dsa_ossl.o: ../../include/openssl/opensslv.h
|
||||
fips_dsa_ossl.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
|
||||
fips_dsa_ossl.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
|
||||
fips_dsa_ossl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
|
||||
fips_dsa_ossl.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
|
||||
fips_dsa_ossl.o: ../../include/openssl/x509_vfy.h fips_dsa_ossl.c
|
||||
fips_dsa_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
|
||||
fips_dsa_selftest.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
|
||||
fips_dsa_selftest.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
|
||||
fips_dsa_selftest.o: ../../include/openssl/err.h ../../include/openssl/evp.h
|
||||
fips_dsa_selftest.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
|
||||
fips_dsa_selftest.o: ../../include/openssl/obj_mac.h
|
||||
fips_dsa_selftest.o: ../../include/openssl/objects.h
|
||||
fips_dsa_selftest.o: ../../include/openssl/opensslconf.h
|
||||
fips_dsa_selftest.o: ../../include/openssl/opensslv.h
|
||||
fips_dsa_selftest.o: ../../include/openssl/ossl_typ.h
|
||||
fips_dsa_selftest.o: ../../include/openssl/safestack.h
|
||||
fips_dsa_selftest.o: ../../include/openssl/stack.h
|
||||
fips_dsa_selftest.o: ../../include/openssl/symhacks.h fips_dsa_selftest.c
|
||||
fips_dsa_sign.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
|
||||
fips_dsa_sign.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
|
||||
fips_dsa_sign.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
|
||||
fips_dsa_sign.o: ../../include/openssl/err.h ../../include/openssl/evp.h
|
||||
fips_dsa_sign.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
|
||||
fips_dsa_sign.o: ../../include/openssl/obj_mac.h
|
||||
fips_dsa_sign.o: ../../include/openssl/objects.h
|
||||
fips_dsa_sign.o: ../../include/openssl/opensslconf.h
|
||||
fips_dsa_sign.o: ../../include/openssl/opensslv.h
|
||||
fips_dsa_sign.o: ../../include/openssl/ossl_typ.h
|
||||
fips_dsa_sign.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
|
||||
fips_dsa_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
|
||||
fips_dsa_sign.o: fips_dsa_sign.c
|
||||
fips_dsatest.o: ../../e_os.h ../../include/openssl/asn1.h
|
||||
fips_dsatest.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
|
||||
fips_dsatest.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
|
||||
fips_dsatest.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
|
||||
fips_dsatest.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
|
||||
fips_dsatest.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
|
||||
fips_dsatest.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
|
||||
fips_dsatest.o: ../../include/openssl/err.h ../../include/openssl/evp.h
|
||||
fips_dsatest.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h
|
||||
fips_dsatest.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
|
||||
fips_dsatest.o: ../../include/openssl/objects.h
|
||||
fips_dsatest.o: ../../include/openssl/opensslconf.h
|
||||
fips_dsatest.o: ../../include/openssl/opensslv.h
|
||||
fips_dsatest.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
|
||||
fips_dsatest.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
|
||||
fips_dsatest.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
|
||||
fips_dsatest.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
|
||||
fips_dsatest.o: ../../include/openssl/ui_compat.h ../../include/openssl/x509.h
|
||||
fips_dsatest.o: ../../include/openssl/x509_vfy.h ../fips_utl.h fips_dsatest.c
|
||||
fips_dssvs.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
|
||||
fips_dssvs.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
|
||||
fips_dssvs.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
|
||||
fips_dssvs.o: ../../include/openssl/err.h ../../include/openssl/evp.h
|
||||
fips_dssvs.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
|
||||
fips_dssvs.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
|
||||
fips_dssvs.o: ../../include/openssl/opensslconf.h
|
||||
fips_dssvs.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
|
||||
fips_dssvs.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
|
||||
fips_dssvs.o: ../../include/openssl/symhacks.h ../fips_utl.h fips_dssvs.c
|
95
fips/dsa/fips_dsa_lib.c
Normal file
95
fips/dsa/fips_dsa_lib.c
Normal file
@ -0,0 +1,95 @@
|
||||
/* fips_dsa_lib.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2007.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2007 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <openssl/dsa.h>
|
||||
#include <openssl/bn.h>
|
||||
|
||||
/* Minimal FIPS versions of FIPS_dsa_new() and FIPS_dsa_free: to
|
||||
* reduce external dependencies.
|
||||
*/
|
||||
|
||||
DSA *FIPS_dsa_new(void)
|
||||
{
|
||||
DSA *ret;
|
||||
ret = OPENSSL_malloc(sizeof(DSA));
|
||||
if (!ret)
|
||||
return NULL;
|
||||
memset(ret, 0, sizeof(DSA));
|
||||
ret->meth = DSA_OpenSSL();
|
||||
if (ret->meth->init)
|
||||
ret->meth->init(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void FIPS_dsa_free(DSA *r)
|
||||
{
|
||||
if (!r)
|
||||
return;
|
||||
if (r->meth->finish)
|
||||
r->meth->finish(r);
|
||||
if (r->p != NULL) BN_clear_free(r->p);
|
||||
if (r->q != NULL) BN_clear_free(r->q);
|
||||
if (r->g != NULL) BN_clear_free(r->g);
|
||||
if (r->pub_key != NULL) BN_clear_free(r->pub_key);
|
||||
if (r->priv_key != NULL) BN_clear_free(r->priv_key);
|
||||
if (r->kinv != NULL) BN_clear_free(r->kinv);
|
||||
if (r->r != NULL) BN_clear_free(r->r);
|
||||
OPENSSL_free(r);
|
||||
}
|
||||
|
182
fips/dsa/fips_dsa_selftest.c
Normal file
182
fips/dsa/fips_dsa_selftest.c
Normal file
@ -0,0 +1,182 @@
|
||||
/* crypto/dsa/dsatest.c */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* 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 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#define OPENSSL_FIPSEVP
|
||||
|
||||
#include <string.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/dsa.h>
|
||||
#include <openssl/fips.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
|
||||
/* seed, out_p, out_q, out_g are taken the NIST test vectors */
|
||||
|
||||
static unsigned char seed[20] = {
|
||||
0x77, 0x8f, 0x40, 0x74, 0x6f, 0x66, 0xbe, 0x33, 0xce, 0xbe, 0x99, 0x34,
|
||||
0x4c, 0xfc, 0xf3, 0x28, 0xaa, 0x70, 0x2d, 0x3a
|
||||
};
|
||||
|
||||
static unsigned char out_p[] = {
|
||||
0xf7, 0x7c, 0x1b, 0x83, 0xd8, 0xe8, 0x5c, 0x7f, 0x85, 0x30, 0x17, 0x57,
|
||||
0x21, 0x95, 0xfe, 0x26, 0x04, 0xeb, 0x47, 0x4c, 0x3a, 0x4a, 0x81, 0x4b,
|
||||
0x71, 0x2e, 0xed, 0x6e, 0x4f, 0x3d, 0x11, 0x0f, 0x7c, 0xfe, 0x36, 0x43,
|
||||
0x51, 0xd9, 0x81, 0x39, 0x17, 0xdf, 0x62, 0xf6, 0x9c, 0x01, 0xa8, 0x69,
|
||||
0x71, 0xdd, 0x29, 0x7f, 0x47, 0xe6, 0x65, 0xa6, 0x22, 0xe8, 0x6a, 0x12,
|
||||
0x2b, 0xc2, 0x81, 0xff, 0x32, 0x70, 0x2f, 0x9e, 0xca, 0x53, 0x26, 0x47,
|
||||
0x0f, 0x59, 0xd7, 0x9e, 0x2c, 0xa5, 0x07, 0xc4, 0x49, 0x52, 0xa3, 0xe4,
|
||||
0x6b, 0x04, 0x00, 0x25, 0x49, 0xe2, 0xe6, 0x7f, 0x28, 0x78, 0x97, 0xb8,
|
||||
0x3a, 0x32, 0x14, 0x38, 0xa2, 0x51, 0x33, 0x22, 0x44, 0x7e, 0xd7, 0xef,
|
||||
0x45, 0xdb, 0x06, 0x4a, 0xd2, 0x82, 0x4a, 0x82, 0x2c, 0xb1, 0xd7, 0xd8,
|
||||
0xb6, 0x73, 0x00, 0x4d, 0x94, 0x77, 0x94, 0xef
|
||||
};
|
||||
|
||||
static unsigned char out_q[] = {
|
||||
0xd4, 0x0a, 0xac, 0x9f, 0xbd, 0x8c, 0x80, 0xc2, 0x38, 0x7e, 0x2e, 0x0c,
|
||||
0x52, 0x5c, 0xea, 0x34, 0xa1, 0x83, 0x32, 0xf3
|
||||
};
|
||||
|
||||
static unsigned char out_g[] = {
|
||||
0x34, 0x73, 0x8b, 0x57, 0x84, 0x8e, 0x55, 0xbf, 0x57, 0xcc, 0x41, 0xbb,
|
||||
0x5e, 0x2b, 0xd5, 0x42, 0xdd, 0x24, 0x22, 0x2a, 0x09, 0xea, 0x26, 0x1e,
|
||||
0x17, 0x65, 0xcb, 0x1a, 0xb3, 0x12, 0x44, 0xa3, 0x9e, 0x99, 0xe9, 0x63,
|
||||
0xeb, 0x30, 0xb1, 0x78, 0x7b, 0x09, 0x40, 0x30, 0xfa, 0x83, 0xc2, 0x35,
|
||||
0xe1, 0xc4, 0x2d, 0x74, 0x1a, 0xb1, 0x83, 0x54, 0xd8, 0x29, 0xf4, 0xcf,
|
||||
0x7f, 0x6f, 0x67, 0x1c, 0x36, 0x49, 0xee, 0x6c, 0xa2, 0x3c, 0x2d, 0x6a,
|
||||
0xe9, 0xd3, 0x9a, 0xf6, 0x57, 0x78, 0x6f, 0xfd, 0x33, 0xcd, 0x3c, 0xed,
|
||||
0xfd, 0xd4, 0x41, 0xe6, 0x5c, 0x8b, 0xe0, 0x68, 0x31, 0x47, 0x47, 0xaf,
|
||||
0x12, 0xa7, 0xf9, 0x32, 0x0d, 0x94, 0x15, 0x48, 0xd0, 0x54, 0x85, 0xb2,
|
||||
0x04, 0xb5, 0x4d, 0xd4, 0x9d, 0x05, 0x22, 0x25, 0xd9, 0xfd, 0x6c, 0x36,
|
||||
0xef, 0xbe, 0x69, 0x6c, 0x55, 0xf4, 0xee, 0xec
|
||||
};
|
||||
|
||||
static const unsigned char str1[]="12345678901234567890";
|
||||
|
||||
void FIPS_corrupt_dsa()
|
||||
{
|
||||
++seed[0];
|
||||
}
|
||||
|
||||
int FIPS_selftest_dsa()
|
||||
{
|
||||
DSA *dsa=NULL;
|
||||
int counter,i,j, ret = 0;
|
||||
unsigned char buf[256];
|
||||
unsigned long h;
|
||||
EVP_MD_CTX mctx;
|
||||
DSA_SIG *dsig = NULL;
|
||||
|
||||
EVP_MD_CTX_init(&mctx);
|
||||
|
||||
dsa = FIPS_dsa_new();
|
||||
|
||||
if(dsa == NULL)
|
||||
goto err;
|
||||
if(!DSA_generate_parameters_ex(dsa, 1024,seed,20,&counter,&h,NULL))
|
||||
goto err;
|
||||
if (counter != 378)
|
||||
goto err;
|
||||
if (h != 2)
|
||||
goto err;
|
||||
i=BN_bn2bin(dsa->q,buf);
|
||||
j=sizeof(out_q);
|
||||
if (i != j || memcmp(buf,out_q,i) != 0)
|
||||
goto err;
|
||||
|
||||
i=BN_bn2bin(dsa->p,buf);
|
||||
j=sizeof(out_p);
|
||||
if (i != j || memcmp(buf,out_p,i) != 0)
|
||||
goto err;
|
||||
|
||||
i=BN_bn2bin(dsa->g,buf);
|
||||
j=sizeof(out_g);
|
||||
if (i != j || memcmp(buf,out_g,i) != 0)
|
||||
goto err;
|
||||
DSA_generate_key(dsa);
|
||||
|
||||
if (!EVP_DigestInit_ex(&mctx, EVP_sha1(), NULL))
|
||||
goto err;
|
||||
if (!EVP_DigestUpdate(&mctx, str1, 20))
|
||||
goto err;
|
||||
dsig = FIPS_dsa_sign_ctx(dsa, &mctx);
|
||||
if (!dsig)
|
||||
goto err;
|
||||
|
||||
if (!EVP_DigestInit_ex(&mctx, EVP_sha1(), NULL))
|
||||
goto err;
|
||||
if (!EVP_DigestUpdate(&mctx, str1, 20))
|
||||
goto err;
|
||||
if (FIPS_dsa_verify_ctx(dsa, &mctx, dsig) != 1)
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
EVP_MD_CTX_cleanup(&mctx);
|
||||
if (dsa)
|
||||
FIPS_dsa_free(dsa);
|
||||
if (dsig)
|
||||
DSA_SIG_free(dsig);
|
||||
if (ret == 0)
|
||||
FIPSerr(FIPS_F_FIPS_SELFTEST_DSA,FIPS_R_SELFTEST_FAILED);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
96
fips/dsa/fips_dsa_sign.c
Normal file
96
fips/dsa/fips_dsa_sign.c
Normal file
@ -0,0 +1,96 @@
|
||||
/* fips_dsa_sign.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2007.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2007 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#define OPENSSL_FIPSEVP
|
||||
|
||||
#include <string.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/dsa.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
|
||||
/* FIPS versions of DSA_sign() and DSA_verify().
|
||||
* Handle DSA_SIG structures to avoid need to handle ASN1.
|
||||
*/
|
||||
|
||||
DSA_SIG * FIPS_dsa_sign_ctx(DSA *dsa, EVP_MD_CTX *ctx)
|
||||
{
|
||||
DSA_SIG *s;
|
||||
unsigned char dig[EVP_MAX_MD_SIZE];
|
||||
unsigned int dlen;
|
||||
EVP_DigestFinal_ex(ctx, dig, &dlen);
|
||||
s = dsa->meth->dsa_do_sign(dig,dlen,dsa);
|
||||
OPENSSL_cleanse(dig, dlen);
|
||||
return s;
|
||||
}
|
||||
|
||||
int FIPS_dsa_verify_ctx(DSA *dsa, EVP_MD_CTX *ctx, DSA_SIG *s)
|
||||
{
|
||||
int ret=-1;
|
||||
unsigned char dig[EVP_MAX_MD_SIZE];
|
||||
unsigned int dlen;
|
||||
EVP_DigestFinal_ex(ctx, dig, &dlen);
|
||||
ret=dsa->meth->dsa_do_verify(dig,dlen,s,dsa);
|
||||
OPENSSL_cleanse(dig, dlen);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
512
fips/dsa/fips_dssvs.c
Normal file
512
fips/dsa/fips_dssvs.c
Normal file
@ -0,0 +1,512 @@
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#ifndef OPENSSL_FIPS
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
printf("No FIPS DSA support\n");
|
||||
return(0);
|
||||
}
|
||||
#else
|
||||
|
||||
#define OPENSSL_FIPSEVP
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/dsa.h>
|
||||
#include <openssl/fips.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "fips_utl.h"
|
||||
|
||||
static void pbn(const char *name, BIGNUM *bn)
|
||||
{
|
||||
int len, i;
|
||||
unsigned char *tmp;
|
||||
len = BN_num_bytes(bn);
|
||||
tmp = OPENSSL_malloc(len);
|
||||
if (!tmp)
|
||||
{
|
||||
fprintf(stderr, "Memory allocation error\n");
|
||||
return;
|
||||
}
|
||||
BN_bn2bin(bn, tmp);
|
||||
printf("%s = ", name);
|
||||
for (i = 0; i < len; i++)
|
||||
printf("%02X", tmp[i]);
|
||||
fputs("\n", stdout);
|
||||
OPENSSL_free(tmp);
|
||||
return;
|
||||
}
|
||||
|
||||
static void primes()
|
||||
{
|
||||
char buf[10240];
|
||||
char lbuf[10240];
|
||||
char *keyword, *value;
|
||||
|
||||
while(fgets(buf,sizeof buf,stdin) != NULL)
|
||||
{
|
||||
fputs(buf,stdout);
|
||||
if (!parse_line(&keyword, &value, lbuf, buf))
|
||||
continue;
|
||||
if(!strcmp(keyword,"Prime"))
|
||||
{
|
||||
BIGNUM *pp;
|
||||
|
||||
pp=BN_new();
|
||||
do_hex2bn(&pp,value);
|
||||
printf("result= %c\n",
|
||||
BN_is_prime_ex(pp,20,NULL,NULL) ? 'P' : 'F');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
|
||||
const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
|
||||
unsigned char *seed_out,
|
||||
int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
|
||||
|
||||
static void pqg()
|
||||
{
|
||||
char buf[1024];
|
||||
char lbuf[1024];
|
||||
char *keyword, *value;
|
||||
int nmod=0;
|
||||
|
||||
while(fgets(buf,sizeof buf,stdin) != NULL)
|
||||
{
|
||||
if (!parse_line(&keyword, &value, lbuf, buf))
|
||||
{
|
||||
fputs(buf,stdout);
|
||||
continue;
|
||||
}
|
||||
if(!strcmp(keyword,"[mod"))
|
||||
nmod=atoi(value);
|
||||
else if(!strcmp(keyword,"N"))
|
||||
{
|
||||
int n=atoi(value);
|
||||
|
||||
printf("[mod = %d]\n\n",nmod);
|
||||
|
||||
while(n--)
|
||||
{
|
||||
unsigned char seed[EVP_MAX_MD_SIZE];
|
||||
DSA *dsa;
|
||||
int counter;
|
||||
unsigned long h;
|
||||
dsa = FIPS_dsa_new();
|
||||
|
||||
if (!dsa_builtin_paramgen(dsa, nmod, 160, NULL, NULL, 0,
|
||||
seed,&counter,&h,NULL))
|
||||
exit(1);
|
||||
pbn("P",dsa->p);
|
||||
pbn("Q",dsa->q);
|
||||
pbn("G",dsa->g);
|
||||
pv("Seed",seed,20);
|
||||
printf("c = %d\n",counter);
|
||||
printf("H = %lx\n",h);
|
||||
putc('\n',stdout);
|
||||
}
|
||||
}
|
||||
else
|
||||
fputs(buf,stdout);
|
||||
}
|
||||
}
|
||||
|
||||
static void pqgver()
|
||||
{
|
||||
char buf[1024];
|
||||
char lbuf[1024];
|
||||
char *keyword, *value;
|
||||
BIGNUM *p = NULL, *q = NULL, *g = NULL;
|
||||
int counter, counter2;
|
||||
unsigned long h, h2;
|
||||
DSA *dsa=NULL;
|
||||
int nmod=0;
|
||||
unsigned char seed[1024];
|
||||
|
||||
while(fgets(buf,sizeof buf,stdin) != NULL)
|
||||
{
|
||||
if (!parse_line(&keyword, &value, lbuf, buf))
|
||||
{
|
||||
fputs(buf,stdout);
|
||||
continue;
|
||||
}
|
||||
fputs(buf, stdout);
|
||||
if(!strcmp(keyword,"[mod"))
|
||||
nmod=atoi(value);
|
||||
else if(!strcmp(keyword,"P"))
|
||||
p=hex2bn(value);
|
||||
else if(!strcmp(keyword,"Q"))
|
||||
q=hex2bn(value);
|
||||
else if(!strcmp(keyword,"G"))
|
||||
g=hex2bn(value);
|
||||
else if(!strcmp(keyword,"Seed"))
|
||||
{
|
||||
int slen = hex2bin(value, seed);
|
||||
if (slen != 20)
|
||||
{
|
||||
fprintf(stderr, "Seed parse length error\n");
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
else if(!strcmp(keyword,"c"))
|
||||
counter =atoi(buf+4);
|
||||
else if(!strcmp(keyword,"H"))
|
||||
{
|
||||
h = atoi(value);
|
||||
if (!p || !q || !g)
|
||||
{
|
||||
fprintf(stderr, "Parse Error\n");
|
||||
exit (1);
|
||||
}
|
||||
dsa = FIPS_dsa_new();
|
||||
if (!DSA_generate_parameters_ex(dsa, nmod,seed,20 ,&counter2,&h2,NULL))
|
||||
exit(1);
|
||||
if (BN_cmp(dsa->p, p) || BN_cmp(dsa->q, q) || BN_cmp(dsa->g, g)
|
||||
|| (counter != counter2) || (h != h2))
|
||||
printf("Result = F\n");
|
||||
else
|
||||
printf("Result = P\n");
|
||||
BN_free(p);
|
||||
BN_free(q);
|
||||
BN_free(g);
|
||||
p = NULL;
|
||||
q = NULL;
|
||||
g = NULL;
|
||||
FIPS_dsa_free(dsa);
|
||||
dsa = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Keypair verification routine. NB: this isn't part of the standard FIPS140-2
|
||||
* algorithm tests. It is an additional test to perform sanity checks on the
|
||||
* output of the KeyPair test.
|
||||
*/
|
||||
|
||||
static int dss_paramcheck(int nmod, BIGNUM *p, BIGNUM *q, BIGNUM *g,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *rem = NULL;
|
||||
if (BN_num_bits(p) != nmod)
|
||||
return 0;
|
||||
if (BN_num_bits(q) != 160)
|
||||
return 0;
|
||||
if (BN_is_prime_ex(p, BN_prime_checks, ctx, NULL) != 1)
|
||||
return 0;
|
||||
if (BN_is_prime_ex(q, BN_prime_checks, ctx, NULL) != 1)
|
||||
return 0;
|
||||
rem = BN_new();
|
||||
if (!BN_mod(rem, p, q, ctx) || !BN_is_one(rem)
|
||||
|| (BN_cmp(g, BN_value_one()) <= 0)
|
||||
|| !BN_mod_exp(rem, g, q, p, ctx) || !BN_is_one(rem))
|
||||
{
|
||||
BN_free(rem);
|
||||
return 0;
|
||||
}
|
||||
/* Todo: check g */
|
||||
BN_free(rem);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void keyver()
|
||||
{
|
||||
char buf[1024];
|
||||
char lbuf[1024];
|
||||
char *keyword, *value;
|
||||
BIGNUM *p = NULL, *q = NULL, *g = NULL, *X = NULL, *Y = NULL;
|
||||
BIGNUM *Y2;
|
||||
BN_CTX *ctx = NULL;
|
||||
int nmod=0, paramcheck = 0;
|
||||
|
||||
ctx = BN_CTX_new();
|
||||
Y2 = BN_new();
|
||||
|
||||
while(fgets(buf,sizeof buf,stdin) != NULL)
|
||||
{
|
||||
if (!parse_line(&keyword, &value, lbuf, buf))
|
||||
{
|
||||
fputs(buf,stdout);
|
||||
continue;
|
||||
}
|
||||
if(!strcmp(keyword,"[mod"))
|
||||
{
|
||||
if (p)
|
||||
BN_free(p);
|
||||
p = NULL;
|
||||
if (q)
|
||||
BN_free(q);
|
||||
q = NULL;
|
||||
if (g)
|
||||
BN_free(g);
|
||||
g = NULL;
|
||||
paramcheck = 0;
|
||||
nmod=atoi(value);
|
||||
}
|
||||
else if(!strcmp(keyword,"P"))
|
||||
p=hex2bn(value);
|
||||
else if(!strcmp(keyword,"Q"))
|
||||
q=hex2bn(value);
|
||||
else if(!strcmp(keyword,"G"))
|
||||
g=hex2bn(value);
|
||||
else if(!strcmp(keyword,"X"))
|
||||
X=hex2bn(value);
|
||||
else if(!strcmp(keyword,"Y"))
|
||||
{
|
||||
Y=hex2bn(value);
|
||||
if (!p || !q || !g || !X || !Y)
|
||||
{
|
||||
fprintf(stderr, "Parse Error\n");
|
||||
exit (1);
|
||||
}
|
||||
pbn("P",p);
|
||||
pbn("Q",q);
|
||||
pbn("G",g);
|
||||
pbn("X",X);
|
||||
pbn("Y",Y);
|
||||
if (!paramcheck)
|
||||
{
|
||||
if (dss_paramcheck(nmod, p, q, g, ctx))
|
||||
paramcheck = 1;
|
||||
else
|
||||
paramcheck = -1;
|
||||
}
|
||||
if (paramcheck != 1)
|
||||
printf("Result = F\n");
|
||||
else
|
||||
{
|
||||
if (!BN_mod_exp(Y2, g, X, p, ctx) || BN_cmp(Y2, Y))
|
||||
printf("Result = F\n");
|
||||
else
|
||||
printf("Result = P\n");
|
||||
}
|
||||
BN_free(X);
|
||||
BN_free(Y);
|
||||
X = NULL;
|
||||
Y = NULL;
|
||||
}
|
||||
}
|
||||
if (p)
|
||||
BN_free(p);
|
||||
if (q)
|
||||
BN_free(q);
|
||||
if (g)
|
||||
BN_free(g);
|
||||
if (Y2)
|
||||
BN_free(Y2);
|
||||
}
|
||||
|
||||
static void keypair()
|
||||
{
|
||||
char buf[1024];
|
||||
char lbuf[1024];
|
||||
char *keyword, *value;
|
||||
int nmod=0;
|
||||
|
||||
while(fgets(buf,sizeof buf,stdin) != NULL)
|
||||
{
|
||||
if (!parse_line(&keyword, &value, lbuf, buf))
|
||||
{
|
||||
fputs(buf,stdout);
|
||||
continue;
|
||||
}
|
||||
if(!strcmp(keyword,"[mod"))
|
||||
nmod=atoi(value);
|
||||
else if(!strcmp(keyword,"N"))
|
||||
{
|
||||
DSA *dsa;
|
||||
int n=atoi(value);
|
||||
|
||||
printf("[mod = %d]\n\n",nmod);
|
||||
dsa = FIPS_dsa_new();
|
||||
if (!DSA_generate_parameters_ex(dsa, nmod,NULL,0,NULL,NULL,NULL))
|
||||
exit(1);
|
||||
pbn("P",dsa->p);
|
||||
pbn("Q",dsa->q);
|
||||
pbn("G",dsa->g);
|
||||
putc('\n',stdout);
|
||||
|
||||
while(n--)
|
||||
{
|
||||
if (!DSA_generate_key(dsa))
|
||||
exit(1);
|
||||
|
||||
pbn("X",dsa->priv_key);
|
||||
pbn("Y",dsa->pub_key);
|
||||
putc('\n',stdout);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void siggen()
|
||||
{
|
||||
char buf[1024];
|
||||
char lbuf[1024];
|
||||
char *keyword, *value;
|
||||
int nmod=0;
|
||||
DSA *dsa=NULL;
|
||||
|
||||
while(fgets(buf,sizeof buf,stdin) != NULL)
|
||||
{
|
||||
if (!parse_line(&keyword, &value, lbuf, buf))
|
||||
{
|
||||
fputs(buf,stdout);
|
||||
continue;
|
||||
}
|
||||
if(!strcmp(keyword,"[mod"))
|
||||
{
|
||||
nmod=atoi(value);
|
||||
printf("[mod = %d]\n\n",nmod);
|
||||
if (dsa)
|
||||
FIPS_dsa_free(dsa);
|
||||
dsa = FIPS_dsa_new();
|
||||
if (!DSA_generate_parameters_ex(dsa, nmod,NULL,0,NULL,NULL,NULL))
|
||||
exit(1);
|
||||
pbn("P",dsa->p);
|
||||
pbn("Q",dsa->q);
|
||||
pbn("G",dsa->g);
|
||||
putc('\n',stdout);
|
||||
}
|
||||
else if(!strcmp(keyword,"Msg"))
|
||||
{
|
||||
unsigned char msg[1024];
|
||||
int n;
|
||||
EVP_MD_CTX mctx;
|
||||
DSA_SIG *sig;
|
||||
EVP_MD_CTX_init(&mctx);
|
||||
|
||||
n=hex2bin(value,msg);
|
||||
pv("Msg",msg,n);
|
||||
|
||||
if (!DSA_generate_key(dsa))
|
||||
exit(1);
|
||||
pbn("Y",dsa->pub_key);
|
||||
|
||||
EVP_DigestInit_ex(&mctx, EVP_sha1(), NULL);
|
||||
EVP_DigestUpdate(&mctx, msg, n);
|
||||
sig = FIPS_dsa_sign_ctx(dsa, &mctx);
|
||||
|
||||
pbn("R",sig->r);
|
||||
pbn("S",sig->s);
|
||||
putc('\n',stdout);
|
||||
DSA_SIG_free(sig);
|
||||
EVP_MD_CTX_cleanup(&mctx);
|
||||
}
|
||||
}
|
||||
if (dsa)
|
||||
FIPS_dsa_free(dsa);
|
||||
}
|
||||
|
||||
static void sigver()
|
||||
{
|
||||
DSA *dsa=NULL;
|
||||
char buf[1024];
|
||||
char lbuf[1024];
|
||||
unsigned char msg[1024];
|
||||
char *keyword, *value;
|
||||
int nmod=0, n=0;
|
||||
DSA_SIG sg, *sig = &sg;
|
||||
|
||||
sig->r = NULL;
|
||||
sig->s = NULL;
|
||||
|
||||
while(fgets(buf,sizeof buf,stdin) != NULL)
|
||||
{
|
||||
if (!parse_line(&keyword, &value, lbuf, buf))
|
||||
{
|
||||
fputs(buf,stdout);
|
||||
continue;
|
||||
}
|
||||
if(!strcmp(keyword,"[mod"))
|
||||
{
|
||||
nmod=atoi(value);
|
||||
if(dsa)
|
||||
FIPS_dsa_free(dsa);
|
||||
dsa=FIPS_dsa_new();
|
||||
}
|
||||
else if(!strcmp(keyword,"P"))
|
||||
dsa->p=hex2bn(value);
|
||||
else if(!strcmp(keyword,"Q"))
|
||||
dsa->q=hex2bn(value);
|
||||
else if(!strcmp(keyword,"G"))
|
||||
{
|
||||
dsa->g=hex2bn(value);
|
||||
|
||||
printf("[mod = %d]\n\n",nmod);
|
||||
pbn("P",dsa->p);
|
||||
pbn("Q",dsa->q);
|
||||
pbn("G",dsa->g);
|
||||
putc('\n',stdout);
|
||||
}
|
||||
else if(!strcmp(keyword,"Msg"))
|
||||
{
|
||||
n=hex2bin(value,msg);
|
||||
pv("Msg",msg,n);
|
||||
}
|
||||
else if(!strcmp(keyword,"Y"))
|
||||
dsa->pub_key=hex2bn(value);
|
||||
else if(!strcmp(keyword,"R"))
|
||||
sig->r=hex2bn(value);
|
||||
else if(!strcmp(keyword,"S"))
|
||||
{
|
||||
EVP_MD_CTX mctx;
|
||||
int r;
|
||||
EVP_MD_CTX_init(&mctx);
|
||||
sig->s=hex2bn(value);
|
||||
|
||||
pbn("Y",dsa->pub_key);
|
||||
pbn("R",sig->r);
|
||||
pbn("S",sig->s);
|
||||
EVP_DigestInit_ex(&mctx, EVP_sha1(), NULL);
|
||||
EVP_DigestUpdate(&mctx, msg, n);
|
||||
no_err = 1;
|
||||
r = FIPS_dsa_verify_ctx(dsa, &mctx, sig);
|
||||
no_err = 0;
|
||||
EVP_MD_CTX_cleanup(&mctx);
|
||||
|
||||
printf("Result = %c\n", r == 1 ? 'P' : 'F');
|
||||
putc('\n',stdout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc,char **argv)
|
||||
{
|
||||
if(argc != 2)
|
||||
{
|
||||
fprintf(stderr,"%s [prime|pqg|pqgver|keypair|siggen|sigver]\n",argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
fips_set_error_print();
|
||||
if(!FIPS_mode_set(1))
|
||||
exit(1);
|
||||
if(!strcmp(argv[1],"prime"))
|
||||
primes();
|
||||
else if(!strcmp(argv[1],"pqg"))
|
||||
pqg();
|
||||
else if(!strcmp(argv[1],"pqgver"))
|
||||
pqgver();
|
||||
else if(!strcmp(argv[1],"keypair"))
|
||||
keypair();
|
||||
else if(!strcmp(argv[1],"keyver"))
|
||||
keyver();
|
||||
else if(!strcmp(argv[1],"siggen"))
|
||||
siggen();
|
||||
else if(!strcmp(argv[1],"sigver"))
|
||||
sigver();
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"Don't know how to %s.\n",argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
558
fips/fips.c
Normal file
558
fips/fips.c
Normal file
@ -0,0 +1,558 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2003 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#define OPENSSL_FIPSEVP
|
||||
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/fips_rand.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/dsa.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include "fips_locl.h"
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
|
||||
#include <openssl/fips.h>
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 1024
|
||||
#endif
|
||||
|
||||
static int fips_selftest_fail;
|
||||
static int fips_mode;
|
||||
static const void *fips_rand_check;
|
||||
|
||||
static void fips_set_mode(int onoff)
|
||||
{
|
||||
int owning_thread = fips_is_owning_thread();
|
||||
|
||||
if (fips_is_started())
|
||||
{
|
||||
if (!owning_thread) fips_w_lock();
|
||||
fips_mode = onoff;
|
||||
if (!owning_thread) fips_w_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
static void fips_set_rand_check(const void *rand_check)
|
||||
{
|
||||
int owning_thread = fips_is_owning_thread();
|
||||
|
||||
if (fips_is_started())
|
||||
{
|
||||
if (!owning_thread) fips_w_lock();
|
||||
fips_rand_check = rand_check;
|
||||
if (!owning_thread) fips_w_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
int FIPS_mode(void)
|
||||
{
|
||||
int ret = 0;
|
||||
int owning_thread = fips_is_owning_thread();
|
||||
|
||||
if (fips_is_started())
|
||||
{
|
||||
if (!owning_thread) fips_r_lock();
|
||||
ret = fips_mode;
|
||||
if (!owning_thread) fips_r_unlock();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
const void *FIPS_rand_check(void)
|
||||
{
|
||||
const void *ret = 0;
|
||||
int owning_thread = fips_is_owning_thread();
|
||||
|
||||
if (fips_is_started())
|
||||
{
|
||||
if (!owning_thread) fips_r_lock();
|
||||
ret = fips_rand_check;
|
||||
if (!owning_thread) fips_r_unlock();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int FIPS_selftest_failed(void)
|
||||
{
|
||||
int ret = 0;
|
||||
if (fips_is_started())
|
||||
{
|
||||
int owning_thread = fips_is_owning_thread();
|
||||
|
||||
if (!owning_thread) fips_r_lock();
|
||||
ret = fips_selftest_fail;
|
||||
if (!owning_thread) fips_r_unlock();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Selftest failure fatal exit routine. This will be called
|
||||
* during *any* cryptographic operation. It has the minimum
|
||||
* overhead possible to avoid too big a performance hit.
|
||||
*/
|
||||
|
||||
void FIPS_selftest_check(void)
|
||||
{
|
||||
if (fips_selftest_fail)
|
||||
{
|
||||
OpenSSLDie(__FILE__,__LINE__, "FATAL FIPS SELFTEST FAILURE");
|
||||
}
|
||||
}
|
||||
|
||||
void fips_set_selftest_fail(void)
|
||||
{
|
||||
fips_selftest_fail = 1;
|
||||
}
|
||||
|
||||
int FIPS_selftest(void)
|
||||
{
|
||||
|
||||
return FIPS_selftest_sha1()
|
||||
&& FIPS_selftest_hmac()
|
||||
&& FIPS_selftest_aes()
|
||||
&& FIPS_selftest_des()
|
||||
&& FIPS_selftest_rsa()
|
||||
&& FIPS_selftest_dsa();
|
||||
}
|
||||
|
||||
extern const void *FIPS_text_start(), *FIPS_text_end();
|
||||
extern const unsigned char FIPS_rodata_start[], FIPS_rodata_end[];
|
||||
unsigned char FIPS_signature [20] = { 0 };
|
||||
static const char FIPS_hmac_key[]="etaonrishdlcupfm";
|
||||
|
||||
unsigned int FIPS_incore_fingerprint(unsigned char *sig,unsigned int len)
|
||||
{
|
||||
const unsigned char *p1 = FIPS_text_start();
|
||||
const unsigned char *p2 = FIPS_text_end();
|
||||
const unsigned char *p3 = FIPS_rodata_start;
|
||||
const unsigned char *p4 = FIPS_rodata_end;
|
||||
HMAC_CTX c;
|
||||
|
||||
HMAC_CTX_init(&c);
|
||||
HMAC_Init(&c,FIPS_hmac_key,strlen(FIPS_hmac_key),EVP_sha1());
|
||||
|
||||
/* detect overlapping regions */
|
||||
if (p1<=p3 && p2>=p3)
|
||||
p3=p1, p4=p2>p4?p2:p4, p1=NULL, p2=NULL;
|
||||
else if (p3<=p1 && p4>=p1)
|
||||
p3=p3, p4=p2>p4?p2:p4, p1=NULL, p2=NULL;
|
||||
|
||||
if (p1)
|
||||
HMAC_Update(&c,p1,(size_t)p2-(size_t)p1);
|
||||
|
||||
if (FIPS_signature>=p3 && FIPS_signature<p4)
|
||||
{
|
||||
/* "punch" hole */
|
||||
HMAC_Update(&c,p3,(size_t)FIPS_signature-(size_t)p3);
|
||||
p3 = FIPS_signature+sizeof(FIPS_signature);
|
||||
if (p3<p4)
|
||||
HMAC_Update(&c,p3,(size_t)p4-(size_t)p3);
|
||||
}
|
||||
else
|
||||
HMAC_Update(&c,p3,(size_t)p4-(size_t)p3);
|
||||
|
||||
HMAC_Final(&c,sig,&len);
|
||||
HMAC_CTX_cleanup(&c);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int FIPS_check_incore_fingerprint(void)
|
||||
{
|
||||
unsigned char sig[EVP_MAX_MD_SIZE];
|
||||
unsigned int len;
|
||||
#if defined(__sgi) && (defined(__mips) || defined(mips))
|
||||
extern int __dso_displacement[];
|
||||
#else
|
||||
extern int OPENSSL_NONPIC_relocated;
|
||||
#endif
|
||||
|
||||
if (FIPS_text_start()==NULL)
|
||||
{
|
||||
FIPSerr(FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT,FIPS_R_UNSUPPORTED_PLATFORM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
len=FIPS_incore_fingerprint (sig,sizeof(sig));
|
||||
|
||||
if (len!=sizeof(FIPS_signature) ||
|
||||
memcmp(FIPS_signature,sig,sizeof(FIPS_signature)))
|
||||
{
|
||||
if (FIPS_signature>=FIPS_rodata_start && FIPS_signature<FIPS_rodata_end)
|
||||
FIPSerr(FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT,FIPS_R_FINGERPRINT_DOES_NOT_MATCH_SEGMENT_ALIASING);
|
||||
#if defined(__sgi) && (defined(__mips) || defined(mips))
|
||||
else if (__dso_displacement!=NULL)
|
||||
#else
|
||||
else if (OPENSSL_NONPIC_relocated)
|
||||
#endif
|
||||
FIPSerr(FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT,FIPS_R_FINGERPRINT_DOES_NOT_MATCH_NONPIC_RELOCATED);
|
||||
else
|
||||
FIPSerr(FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT,FIPS_R_FINGERPRINT_DOES_NOT_MATCH);
|
||||
#ifdef OPENSSL_FIPS_DEBUGGER
|
||||
return 1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int FIPS_mode_set(int onoff)
|
||||
{
|
||||
int fips_set_owning_thread();
|
||||
int fips_clear_owning_thread();
|
||||
int ret = 0;
|
||||
|
||||
fips_w_lock();
|
||||
fips_set_started();
|
||||
fips_set_owning_thread();
|
||||
|
||||
if(onoff)
|
||||
{
|
||||
unsigned char buf[48];
|
||||
|
||||
fips_selftest_fail = 0;
|
||||
|
||||
/* Don't go into FIPS mode twice, just so we can do automagic
|
||||
seeding */
|
||||
if(FIPS_mode())
|
||||
{
|
||||
FIPSerr(FIPS_F_FIPS_MODE_SET,FIPS_R_FIPS_MODE_ALREADY_SET);
|
||||
fips_selftest_fail = 1;
|
||||
ret = 0;
|
||||
goto end;
|
||||
}
|
||||
|
||||
#ifdef OPENSSL_IA32_SSE2
|
||||
if ((OPENSSL_ia32cap & (1<<25|1<<26)) != (1<<25|1<<26))
|
||||
{
|
||||
FIPSerr(FIPS_F_FIPS_MODE_SET,FIPS_R_UNSUPPORTED_PLATFORM);
|
||||
fips_selftest_fail = 1;
|
||||
ret = 0;
|
||||
goto end;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(fips_signature_witness() != FIPS_signature)
|
||||
{
|
||||
FIPSerr(FIPS_F_FIPS_MODE_SET,FIPS_R_CONTRADICTING_EVIDENCE);
|
||||
fips_selftest_fail = 1;
|
||||
ret = 0;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if(!FIPS_check_incore_fingerprint())
|
||||
{
|
||||
fips_selftest_fail = 1;
|
||||
ret = 0;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Perform RNG KAT before seeding */
|
||||
if (!FIPS_selftest_rng())
|
||||
{
|
||||
fips_selftest_fail = 1;
|
||||
ret = 0;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* automagically seed PRNG if not already seeded */
|
||||
if(!FIPS_rand_status())
|
||||
{
|
||||
if(RAND_bytes(buf,sizeof buf) <= 0)
|
||||
{
|
||||
fips_selftest_fail = 1;
|
||||
ret = 0;
|
||||
goto end;
|
||||
}
|
||||
FIPS_rand_set_key(buf,32);
|
||||
FIPS_rand_seed(buf+32,16);
|
||||
}
|
||||
|
||||
/* now switch into FIPS mode */
|
||||
fips_set_rand_check(FIPS_rand_method());
|
||||
RAND_set_rand_method(FIPS_rand_method());
|
||||
if(FIPS_selftest())
|
||||
fips_set_mode(1);
|
||||
else
|
||||
{
|
||||
fips_selftest_fail = 1;
|
||||
ret = 0;
|
||||
goto end;
|
||||
}
|
||||
ret = 1;
|
||||
goto end;
|
||||
}
|
||||
fips_set_mode(0);
|
||||
fips_selftest_fail = 0;
|
||||
ret = 1;
|
||||
end:
|
||||
fips_clear_owning_thread();
|
||||
fips_w_unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void fips_w_lock(void) { CRYPTO_w_lock(CRYPTO_LOCK_FIPS); }
|
||||
void fips_w_unlock(void) { CRYPTO_w_unlock(CRYPTO_LOCK_FIPS); }
|
||||
void fips_r_lock(void) { CRYPTO_r_lock(CRYPTO_LOCK_FIPS); }
|
||||
void fips_r_unlock(void) { CRYPTO_r_unlock(CRYPTO_LOCK_FIPS); }
|
||||
|
||||
static int fips_started = 0;
|
||||
static CRYPTO_THREADID fips_thread;
|
||||
static int fips_thread_set = 0;
|
||||
|
||||
void fips_set_started(void)
|
||||
{
|
||||
fips_started = 1;
|
||||
}
|
||||
|
||||
int fips_is_started(void)
|
||||
{
|
||||
return fips_started;
|
||||
}
|
||||
|
||||
int fips_is_owning_thread(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (fips_is_started())
|
||||
{
|
||||
CRYPTO_r_lock(CRYPTO_LOCK_FIPS2);
|
||||
if (fips_thread_set)
|
||||
{
|
||||
CRYPTO_THREADID cur;
|
||||
CRYPTO_THREADID_current(&cur);
|
||||
if (!CRYPTO_THREADID_cmp(&cur, &fips_thread))
|
||||
ret = 1;
|
||||
}
|
||||
CRYPTO_r_unlock(CRYPTO_LOCK_FIPS2);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int fips_set_owning_thread(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (fips_is_started())
|
||||
{
|
||||
CRYPTO_w_lock(CRYPTO_LOCK_FIPS2);
|
||||
if (!fips_thread_set)
|
||||
{
|
||||
CRYPTO_THREADID_current(&fips_thread);
|
||||
ret = 1;
|
||||
}
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_FIPS2);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int fips_clear_owning_thread(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (fips_is_started())
|
||||
{
|
||||
CRYPTO_w_lock(CRYPTO_LOCK_FIPS2);
|
||||
if (fips_thread_set)
|
||||
{
|
||||
CRYPTO_THREADID cur;
|
||||
CRYPTO_THREADID_current(&cur);
|
||||
if (!CRYPTO_THREADID_cmp(&cur, &fips_thread))
|
||||
fips_thread_set = 0;
|
||||
}
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_FIPS2);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
unsigned char *fips_signature_witness(void)
|
||||
{
|
||||
extern unsigned char FIPS_signature[];
|
||||
return FIPS_signature;
|
||||
}
|
||||
|
||||
/* Generalized public key test routine. Signs and verifies the data
|
||||
* supplied in tbs using mesage digest md and setting RSA padding mode
|
||||
* pad_mode. If the 'kat' parameter is not NULL it will
|
||||
* additionally check the signature matches it: a known answer test
|
||||
* The string "fail_str" is used for identification purposes in case
|
||||
* of failure.
|
||||
*/
|
||||
|
||||
int fips_pkey_signature_test(EVP_PKEY *pkey,
|
||||
const unsigned char *tbs, int tbslen,
|
||||
const unsigned char *kat, unsigned int katlen,
|
||||
const EVP_MD *digest, int pad_mode,
|
||||
const char *fail_str)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char sigtmp[256], *sig = sigtmp;
|
||||
unsigned int siglen;
|
||||
DSA_SIG *dsig = NULL;
|
||||
EVP_MD_CTX mctx;
|
||||
EVP_MD_CTX_init(&mctx);
|
||||
|
||||
if ((pkey->type == EVP_PKEY_RSA)
|
||||
&& ((size_t)RSA_size(pkey->pkey.rsa) > sizeof(sigtmp)))
|
||||
{
|
||||
sig = OPENSSL_malloc(RSA_size(pkey->pkey.rsa));
|
||||
if (!sig)
|
||||
{
|
||||
FIPSerr(FIPS_F_FIPS_PKEY_SIGNATURE_TEST,ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (tbslen == -1)
|
||||
tbslen = strlen((char *)tbs);
|
||||
|
||||
if (!EVP_DigestInit_ex(&mctx, digest, NULL))
|
||||
goto error;
|
||||
if (!EVP_DigestUpdate(&mctx, tbs, tbslen))
|
||||
goto error;
|
||||
if (pkey->type == EVP_PKEY_RSA)
|
||||
{
|
||||
if (!FIPS_rsa_sign_ctx(pkey->pkey.rsa, &mctx,
|
||||
pad_mode, 0, NULL, sig, &siglen))
|
||||
goto error;
|
||||
}
|
||||
else if (pkey->type == EVP_PKEY_DSA)
|
||||
{
|
||||
dsig = FIPS_dsa_sign_ctx(pkey->pkey.dsa, &mctx);
|
||||
if (!dsig)
|
||||
goto error;
|
||||
}
|
||||
#if 0
|
||||
else if (!EVP_SignFinal(&mctx, sig, &siglen, pkey))
|
||||
goto error;
|
||||
#endif
|
||||
|
||||
if (kat && ((siglen != katlen) || memcmp(kat, sig, katlen)))
|
||||
goto error;
|
||||
|
||||
if (!EVP_DigestInit_ex(&mctx, digest, NULL))
|
||||
goto error;
|
||||
if (!EVP_DigestUpdate(&mctx, tbs, tbslen))
|
||||
goto error;
|
||||
if (pkey->type == EVP_PKEY_RSA)
|
||||
{
|
||||
ret = FIPS_rsa_verify_ctx(pkey->pkey.rsa, &mctx,
|
||||
pad_mode, 0, NULL, sig, siglen);
|
||||
}
|
||||
else if (pkey->type == EVP_PKEY_DSA)
|
||||
{
|
||||
ret = FIPS_dsa_verify_ctx(pkey->pkey.dsa, &mctx, dsig);
|
||||
}
|
||||
#if 0
|
||||
else
|
||||
ret = EVP_VerifyFinal(&mctx, sig, siglen, pkey);
|
||||
#endif
|
||||
|
||||
error:
|
||||
if (dsig != NULL)
|
||||
DSA_SIG_free(dsig);
|
||||
if (sig != sigtmp)
|
||||
OPENSSL_free(sig);
|
||||
EVP_MD_CTX_cleanup(&mctx);
|
||||
if (ret != 1)
|
||||
{
|
||||
FIPSerr(FIPS_F_FIPS_PKEY_SIGNATURE_TEST,FIPS_R_TEST_FAILURE);
|
||||
if (fail_str)
|
||||
ERR_add_error_data(2, "Type=", fail_str);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Generalized symmetric cipher test routine. Encrypt data, verify result
|
||||
* against known answer, decrypt and compare with original plaintext.
|
||||
*/
|
||||
|
||||
int fips_cipher_test(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
|
||||
const unsigned char *key,
|
||||
const unsigned char *iv,
|
||||
const unsigned char *plaintext,
|
||||
const unsigned char *ciphertext,
|
||||
int len)
|
||||
{
|
||||
unsigned char pltmp[FIPS_MAX_CIPHER_TEST_SIZE];
|
||||
unsigned char citmp[FIPS_MAX_CIPHER_TEST_SIZE];
|
||||
OPENSSL_assert(len <= FIPS_MAX_CIPHER_TEST_SIZE);
|
||||
if (EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, 1) <= 0)
|
||||
return 0;
|
||||
EVP_Cipher(ctx, citmp, plaintext, len);
|
||||
if (memcmp(citmp, ciphertext, len))
|
||||
return 0;
|
||||
if (EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, 0) <= 0)
|
||||
return 0;
|
||||
EVP_Cipher(ctx, pltmp, citmp, len);
|
||||
if (memcmp(pltmp, plaintext, len))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* The purpose of this is to ensure the error code exists and the function
|
||||
* name is to keep the error checking script quiet
|
||||
*/
|
||||
void hash_final(void)
|
||||
{
|
||||
FIPSerr(FIPS_F_HASH_FINAL,FIPS_R_NON_FIPS_METHOD);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
192
fips/fips.h
Normal file
192
fips/fips.h
Normal file
@ -0,0 +1,192 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2003 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#ifndef OPENSSL_FIPS
|
||||
#error FIPS is disabled.
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct dsa_st;
|
||||
struct evp_pkey_st;
|
||||
struct env_md_st;
|
||||
struct evp_cipher_st;
|
||||
struct evp_cipher_ctx_st;
|
||||
|
||||
int FIPS_mode_set(int onoff);
|
||||
int FIPS_mode(void);
|
||||
const void *FIPS_rand_check(void);
|
||||
int FIPS_selftest(void);
|
||||
int FIPS_selftest_failed(void);
|
||||
void FIPS_selftest_check(void);
|
||||
void FIPS_corrupt_sha1(void);
|
||||
int FIPS_selftest_sha1(void);
|
||||
void FIPS_corrupt_aes(void);
|
||||
int FIPS_selftest_aes(void);
|
||||
void FIPS_corrupt_des(void);
|
||||
int FIPS_selftest_des(void);
|
||||
void FIPS_corrupt_rsa(void);
|
||||
void FIPS_corrupt_rsa_keygen(void);
|
||||
int FIPS_selftest_rsa(void);
|
||||
void FIPS_corrupt_dsa(void);
|
||||
void FIPS_corrupt_dsa_keygen(void);
|
||||
int FIPS_selftest_dsa(void);
|
||||
void FIPS_corrupt_rng(void);
|
||||
void FIPS_rng_stick(void);
|
||||
int FIPS_selftest_rng(void);
|
||||
int FIPS_selftest_hmac(void);
|
||||
|
||||
unsigned int FIPS_incore_fingerprint(unsigned char *sig,unsigned int len);
|
||||
int FIPS_check_incore_fingerprint(void);
|
||||
|
||||
int fips_pkey_signature_test(struct evp_pkey_st *pkey,
|
||||
const unsigned char *tbs, int tbslen,
|
||||
const unsigned char *kat, unsigned int katlen,
|
||||
const struct env_md_st *digest, int pad_mode,
|
||||
const char *fail_str);
|
||||
|
||||
int fips_cipher_test(struct evp_cipher_ctx_st *ctx,
|
||||
const struct evp_cipher_st *cipher,
|
||||
const unsigned char *key,
|
||||
const unsigned char *iv,
|
||||
const unsigned char *plaintext,
|
||||
const unsigned char *ciphertext,
|
||||
int len);
|
||||
|
||||
void fips_set_selftest_fail(void);
|
||||
int fips_check_rsa(struct rsa_st *rsa);
|
||||
|
||||
void FIPS_evp_md_ctx_init(EVP_MD_CTX *ctx);
|
||||
EVP_MD_CTX *FIPS_evp_md_ctx_create(void);
|
||||
int FIPS_evp_digestinit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl);
|
||||
int FIPS_evp_digestupdate(EVP_MD_CTX *ctx, const void *data, size_t count);
|
||||
int FIPS_evp_digestfinal(EVP_MD_CTX *ctx,
|
||||
unsigned char *md, unsigned int *size);
|
||||
int FIPS_evp_digest(const void *data, size_t count,
|
||||
unsigned char *md, unsigned int *size, const EVP_MD *type, ENGINE *impl);
|
||||
void FIPS_evp_md_ctx_destroy(EVP_MD_CTX *ctx);
|
||||
int FIPS_evp_md_ctx_cleanup(EVP_MD_CTX *ctx);
|
||||
|
||||
#ifdef OPENSSL_FIPS_SOURCE
|
||||
#define ENGINE_init FIPS_engine_init
|
||||
#define ENGINE_finish FIPS_engine_finish
|
||||
#define ENGINE_get_digest FIPS_engine_get_digest
|
||||
#define ENGINE_get_digest_engine FIPS_engine_get_digest_engine
|
||||
#define ENGINE_get_RAND FIPS_engine_get_rand
|
||||
#define ENGINE_get_default_RAND FIPS_engine_get_default_rand
|
||||
#define EVP_SignFinal FIPS_evp_signfinal
|
||||
#define EVP_VerifyFinal FIPS_evp_verifyfinal
|
||||
#endif
|
||||
|
||||
/* BEGIN ERROR CODES */
|
||||
/* The following lines are auto generated by the script mkerr.pl. Any changes
|
||||
* made after this point may be overwritten when the script is next run.
|
||||
*/
|
||||
void ERR_load_FIPS_strings(void);
|
||||
|
||||
/* Error codes for the FIPS functions. */
|
||||
|
||||
/* Function codes. */
|
||||
#define FIPS_F_DH_BUILTIN_GENPARAMS 100
|
||||
#define FIPS_F_DSA_BUILTIN_PARAMGEN 101
|
||||
#define FIPS_F_DSA_DO_SIGN 102
|
||||
#define FIPS_F_DSA_DO_VERIFY 103
|
||||
#define FIPS_F_EVP_CIPHERINIT_EX 124
|
||||
#define FIPS_F_EVP_DIGESTINIT_EX 125
|
||||
#define FIPS_F_FIPS_CHECK_DSA 104
|
||||
#define FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT 105
|
||||
#define FIPS_F_FIPS_CHECK_RSA 106
|
||||
#define FIPS_F_FIPS_DSA_CHECK 107
|
||||
#define FIPS_F_FIPS_MODE_SET 108
|
||||
#define FIPS_F_FIPS_PKEY_SIGNATURE_TEST 109
|
||||
#define FIPS_F_FIPS_SELFTEST_AES 110
|
||||
#define FIPS_F_FIPS_SELFTEST_DES 111
|
||||
#define FIPS_F_FIPS_SELFTEST_DSA 112
|
||||
#define FIPS_F_FIPS_SELFTEST_HMAC 113
|
||||
#define FIPS_F_FIPS_SELFTEST_RNG 114
|
||||
#define FIPS_F_FIPS_SELFTEST_SHA1 115
|
||||
#define FIPS_F_HASH_FINAL 123
|
||||
#define FIPS_F_RSA_BUILTIN_KEYGEN 116
|
||||
#define FIPS_F_RSA_EAY_PRIVATE_DECRYPT 117
|
||||
#define FIPS_F_RSA_EAY_PRIVATE_ENCRYPT 118
|
||||
#define FIPS_F_RSA_EAY_PUBLIC_DECRYPT 119
|
||||
#define FIPS_F_RSA_EAY_PUBLIC_ENCRYPT 120
|
||||
#define FIPS_F_RSA_X931_GENERATE_KEY_EX 121
|
||||
#define FIPS_F_SSLEAY_RAND_BYTES 122
|
||||
|
||||
/* Reason codes. */
|
||||
#define FIPS_R_CANNOT_READ_EXE 103
|
||||
#define FIPS_R_CANNOT_READ_EXE_DIGEST 104
|
||||
#define FIPS_R_CONTRADICTING_EVIDENCE 114
|
||||
#define FIPS_R_EXE_DIGEST_DOES_NOT_MATCH 105
|
||||
#define FIPS_R_FINGERPRINT_DOES_NOT_MATCH 110
|
||||
#define FIPS_R_FINGERPRINT_DOES_NOT_MATCH_NONPIC_RELOCATED 111
|
||||
#define FIPS_R_FINGERPRINT_DOES_NOT_MATCH_SEGMENT_ALIASING 112
|
||||
#define FIPS_R_FIPS_MODE_ALREADY_SET 102
|
||||
#define FIPS_R_FIPS_SELFTEST_FAILED 106
|
||||
#define FIPS_R_INVALID_KEY_LENGTH 109
|
||||
#define FIPS_R_KEY_TOO_SHORT 108
|
||||
#define FIPS_R_NON_FIPS_METHOD 100
|
||||
#define FIPS_R_PAIRWISE_TEST_FAILED 107
|
||||
#define FIPS_R_RSA_DECRYPT_ERROR 115
|
||||
#define FIPS_R_RSA_ENCRYPT_ERROR 116
|
||||
#define FIPS_R_SELFTEST_FAILED 101
|
||||
#define FIPS_R_TEST_FAILURE 117
|
||||
#define FIPS_R_UNSUPPORTED_PLATFORM 113
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
190
fips/fips_canister.c
Normal file
190
fips/fips_canister.c
Normal file
@ -0,0 +1,190 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2005 The OpenSSL Project. Rights for redistribution
|
||||
* and usage in source and binary forms are granted according to the
|
||||
* OpenSSL license.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined(__DECC)
|
||||
# include <c_asm.h>
|
||||
# pragma __nostandard
|
||||
#endif
|
||||
|
||||
const void *FIPS_text_start(void);
|
||||
const void *FIPS_text_end(void);
|
||||
|
||||
#include "e_os.h"
|
||||
|
||||
#if !defined(POINTER_TO_FUNCTION_IS_POINTER_TO_1ST_INSTRUCTION)
|
||||
# if (defined(__sun) && (defined(__sparc) || defined(__sparcv9))) || \
|
||||
(defined(__sgi) && (defined(__mips) || defined(mips))) || \
|
||||
(defined(__osf__) && defined(__alpha)) || \
|
||||
(defined(__linux) && (defined(__arm) || defined(__arm__))) || \
|
||||
(defined(__i386) || defined(__i386__)) || \
|
||||
(defined(__x86_64) || defined(__x86_64__)) || \
|
||||
defined(__ANDROID__) || \
|
||||
(defined(vax) || defined(__vax__))
|
||||
# define POINTER_TO_FUNCTION_IS_POINTER_TO_1ST_INSTRUCTION
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__xlC__) && __xlC__>=0x600 && (defined(_POWER) || defined(_ARCH_PPC))
|
||||
static void *instruction_pointer_xlc(void);
|
||||
# pragma mc_func instruction_pointer_xlc {\
|
||||
"7c0802a6" /* mflr r0 */ \
|
||||
"48000005" /* bl $+4 */ \
|
||||
"7c6802a6" /* mflr r3 */ \
|
||||
"7c0803a6" /* mtlr r0 */ }
|
||||
# pragma reg_killed_by instruction_pointer_xlc gr0 gr3
|
||||
# define INSTRUCTION_POINTER_IMPLEMENTED(ret) (ret=instruction_pointer_xlc());
|
||||
#endif
|
||||
|
||||
#ifdef FIPS_START
|
||||
#define FIPS_ref_point FIPS_text_start
|
||||
/* Some compilers put string literals into a separate segment. As we
|
||||
* are mostly interested to hash AES tables in .rodata, we declare
|
||||
* reference points accordingly. In case you wonder, the values are
|
||||
* big-endian encoded variable names, just to prevent these arrays
|
||||
* from being merged by linker. */
|
||||
const unsigned int FIPS_rodata_start[]=
|
||||
{ 0x46495053, 0x5f726f64, 0x6174615f, 0x73746172 };
|
||||
#else
|
||||
#define FIPS_ref_point FIPS_text_end
|
||||
const unsigned int FIPS_rodata_end[]=
|
||||
{ 0x46495053, 0x5f726f64, 0x6174615f, 0x656e645b };
|
||||
#endif
|
||||
|
||||
/*
|
||||
* I declare reference function as static in order to avoid certain
|
||||
* pitfalls in -dynamic linker behaviour...
|
||||
*/
|
||||
static void *instruction_pointer(void)
|
||||
{ void *ret=NULL;
|
||||
/* These are ABI-neutral CPU-specific snippets. ABI-neutrality means
|
||||
* that they are designed to work under any OS running on particular
|
||||
* CPU, which is why you don't find any #ifdef THIS_OR_THAT_OS in
|
||||
* this function. */
|
||||
#if defined(INSTRUCTION_POINTER_IMPLEMENTED)
|
||||
INSTRUCTION_POINTER_IMPLEMENTED(ret);
|
||||
#elif defined(__GNUC__) && __GNUC__>=2
|
||||
# if defined(__alpha) || defined(__alpha__)
|
||||
# define INSTRUCTION_POINTER_IMPLEMENTED
|
||||
__asm __volatile ( "br %0,1f\n1:" : "=r"(ret) );
|
||||
# elif defined(__i386) || defined(__i386__)
|
||||
# define INSTRUCTION_POINTER_IMPLEMENTED
|
||||
__asm __volatile ( "call 1f\n1: popl %0" : "=r"(ret) );
|
||||
ret = (void *)((size_t)ret&~3UL); /* align for better performance */
|
||||
# elif defined(__ia64) || defined(__ia64__)
|
||||
# define INSTRUCTION_POINTER_IMPLEMENTED
|
||||
__asm __volatile ( "mov %0=ip" : "=r"(ret) );
|
||||
# elif defined(__hppa) || defined(__hppa__) || defined(__pa_risc)
|
||||
# define INSTRUCTION_POINTER_IMPLEMENTED
|
||||
__asm __volatile ( "blr %%r0,%0\n\tnop" : "=r"(ret) );
|
||||
ret = (void *)((size_t)ret&~3UL); /* mask privilege level */
|
||||
# elif defined(__mips) || defined(__mips__)
|
||||
# define INSTRUCTION_POINTER_IMPLEMENTED
|
||||
void *scratch;
|
||||
__asm __volatile ( "move %1,$31\n\t" /* save ra */
|
||||
"bal .+8; nop\n\t"
|
||||
"move %0,$31\n\t"
|
||||
"move $31,%1" /* restore ra */
|
||||
: "=r"(ret),"=r"(scratch) );
|
||||
# elif defined(__ppc__) || defined(__powerpc) || defined(__powerpc__) || \
|
||||
defined(__POWERPC__) || defined(_POWER) || defined(__PPC__) || \
|
||||
defined(__PPC64__) || defined(__powerpc64__)
|
||||
# define INSTRUCTION_POINTER_IMPLEMENTED
|
||||
void *scratch;
|
||||
__asm __volatile ( "mfspr %1,8\n\t" /* save lr */
|
||||
"bl $+4\n\t"
|
||||
"mfspr %0,8\n\t" /* mflr ret */
|
||||
"mtspr 8,%1" /* restore lr */
|
||||
: "=r"(ret),"=r"(scratch) );
|
||||
# elif defined(__s390__) || defined(__s390x__)
|
||||
# define INSTRUCTION_POINTER_IMPLEMENTED
|
||||
__asm __volatile ( "bras %0,1f\n1:" : "=r"(ret) );
|
||||
ret = (void *)((size_t)ret&~3UL);
|
||||
# elif defined(__sparc) || defined(__sparc__) || defined(__sparcv9)
|
||||
# define INSTRUCTION_POINTER_IMPLEMENTED
|
||||
void *scratch;
|
||||
__asm __volatile ( "mov %%o7,%1\n\t"
|
||||
"call .+8; nop\n\t"
|
||||
"mov %%o7,%0\n\t"
|
||||
"mov %1,%%o7"
|
||||
: "=r"(ret),"=r"(scratch) );
|
||||
# elif defined(__x86_64) || defined(__x86_64__)
|
||||
# define INSTRUCTION_POINTER_IMPLEMENTED
|
||||
__asm __volatile ( "leaq 0(%%rip),%0" : "=r"(ret) );
|
||||
ret = (void *)((size_t)ret&~3UL); /* align for better performance */
|
||||
# endif
|
||||
#elif defined(__DECC) && defined(__alpha)
|
||||
# define INSTRUCTION_POINTER_IMPLEMENTED
|
||||
ret = (void *)(size_t)asm("br %v0,1f\n1:");
|
||||
#elif defined(_MSC_VER) && defined(_M_IX86)
|
||||
# define INSTRUCTION_POINTER_IMPLEMENTED
|
||||
void *scratch;
|
||||
_asm {
|
||||
call self
|
||||
self: pop eax
|
||||
mov scratch,eax
|
||||
}
|
||||
ret = (void *)((size_t)scratch&~3UL);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function returns pointer to an instruction in the vicinity of
|
||||
* its entry point, but not outside this object module. This guarantees
|
||||
* that sequestered code is covered...
|
||||
*/
|
||||
const void *FIPS_ref_point()
|
||||
{
|
||||
#if defined(INSTRUCTION_POINTER_IMPLEMENTED)
|
||||
return instruction_pointer();
|
||||
/* Below we essentially cover vendor compilers which do not support
|
||||
* inline assembler... */
|
||||
#elif defined(_AIX)
|
||||
struct { void *ip,*gp,*env; } *p = (void *)instruction_pointer;
|
||||
return p->ip;
|
||||
#elif defined(_HPUX_SOURCE)
|
||||
# if defined(__hppa) || defined(__hppa__)
|
||||
struct { void *i[4]; } *p = (void *)FIPS_ref_point;
|
||||
|
||||
if (sizeof(p) == 8) /* 64-bit */
|
||||
return p->i[2];
|
||||
else if ((size_t)p & 2)
|
||||
{ p = (void *)((size_t)p&~3UL);
|
||||
return p->i[0];
|
||||
}
|
||||
else
|
||||
return (void *)p;
|
||||
# elif defined(__ia64) || defined(__ia64__)
|
||||
struct { unsigned long long ip,gp; } *p=(void *)instruction_pointer;
|
||||
return (void *)(size_t)p->ip;
|
||||
# endif
|
||||
#elif (defined(__VMS) || defined(VMS)) && !(defined(vax) || defined(__vax__))
|
||||
/* applies to both alpha and ia64 */
|
||||
struct { unsigned __int64 opaque,ip; } *p=(void *)instruction_pointer;
|
||||
return (void *)(size_t)p->ip;
|
||||
#elif defined(__VOS__)
|
||||
/* applies to both pa-risc and ia32 */
|
||||
struct { void *dp,*ip,*gp; } *p = (void *)instruction_pointer;
|
||||
return p->ip;
|
||||
#elif defined(_WIN32)
|
||||
# if defined(_WIN64) && defined(_M_IA64)
|
||||
struct { void *ip,*gp; } *p = (void *)FIPS_ref_point;
|
||||
return p->ip;
|
||||
# else
|
||||
return (void *)FIPS_ref_point;
|
||||
# endif
|
||||
/*
|
||||
* In case you wonder why there is no #ifdef __linux. All Linux targets
|
||||
* are GCC-based and therefore are covered by instruction_pointer above
|
||||
* [well, some are covered by by the one below]...
|
||||
*/
|
||||
#elif defined(POINTER_TO_FUNCTION_IS_POINTER_TO_1ST_INSTRUCTION)
|
||||
return (void *)instruction_pointer;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
72
fips/fips_locl.h
Normal file
72
fips/fips_locl.h
Normal file
@ -0,0 +1,72 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2003 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void fips_w_lock(void);
|
||||
void fips_w_unlock(void);
|
||||
void fips_r_lock(void);
|
||||
void fips_r_unlock(void);
|
||||
int fips_is_started(void);
|
||||
void fips_set_started(void);
|
||||
int fips_is_owning_thread(void);
|
||||
int fips_set_owning_thread(void);
|
||||
int fips_clear_owning_thread(void);
|
||||
unsigned char *fips_signature_witness(void);
|
||||
|
||||
#define FIPS_MAX_CIPHER_TEST_SIZE 16
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
176
fips/fips_premain.c
Normal file
176
fips/fips_premain.c
Normal file
@ -0,0 +1,176 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2005 The OpenSSL Project. Rights for redistribution
|
||||
* and usage in source and binary forms are granted according to the
|
||||
* OpenSSL license.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#if defined(__unix) || defined(__unix__)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifndef FINGERPRINT_PREMAIN_DSO_LOAD
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__>=2
|
||||
void FINGERPRINT_premain(void) __attribute__((constructor));
|
||||
/* Most commonly this results in pointer to premain to be dropped
|
||||
* to .ctors segment, which is traversed by GCC crtbegin.o upon
|
||||
* program startup. Except on a.out OpenBSD where it results in
|
||||
* _GLOBAL_$I$premain() {premain();} being auto-generated by
|
||||
* compiler... But one way or another this is believed to cover
|
||||
* *all* GCC targets. */
|
||||
#elif defined(_MSC_VER)
|
||||
# ifdef _WINDLL
|
||||
__declspec(dllexport) /* this is essentially cosmetics... */
|
||||
# endif
|
||||
void FINGERPRINT_premain(void);
|
||||
static int premain_wrapper(void) { FINGERPRINT_premain(); return 0; }
|
||||
# ifdef _WIN64
|
||||
# pragma section(".CRT$XCU",read)
|
||||
__declspec(allocate(".CRT$XCU"))
|
||||
# else
|
||||
# pragma data_seg(".CRT$XCU")
|
||||
# endif
|
||||
static int (*p)(void) = premain_wrapper;
|
||||
/* This results in pointer to premain to appear in .CRT segment,
|
||||
* which is traversed by Visual C run-time initialization code.
|
||||
* This applies to both Win32 and [all flavors of] Win64. */
|
||||
# pragma data_seg()
|
||||
#elif defined(__SUNPRO_C)
|
||||
void FINGERPRINT_premain(void);
|
||||
# pragma init(FINGERPRINT_premain)
|
||||
/* This results in a call to premain to appear in .init segment. */
|
||||
#elif defined(__DECC) && (defined(__VMS) || defined(VMS))
|
||||
void FINGERPRINT_premain(void);
|
||||
# pragma __nostandard
|
||||
globaldef { "LIB$INITIALIZ" } readonly _align (LONGWORD)
|
||||
int spare[8] = {0};
|
||||
globaldef { "LIB$INITIALIZE" } readonly _align (LONGWORD)
|
||||
void (*x_FINGERPRINT_premain)(void) = FINGERPRINT_premain;
|
||||
/* Refer to LIB$INITIALIZE to ensure it exists in the image. */
|
||||
int lib$initialize();
|
||||
globaldef int (*lib_init_ref)() = lib$initialize;
|
||||
# pragma __standard
|
||||
#elif 0
|
||||
The rest has to be taken care of through command line:
|
||||
|
||||
-Wl,-init,FINGERPRINT_premain on OSF1 and IRIX
|
||||
-Wl,+init,FINGERPRINT_premain on HP-UX
|
||||
-Wl,-binitfini:FINGERPRINT_premain on AIX
|
||||
|
||||
On ELF platforms this results in a call to premain to appear in
|
||||
.init segment...
|
||||
#endif
|
||||
|
||||
#ifndef HMAC_SHA1_SIG
|
||||
#define HMAC_SHA1_SIG "?have to make sure this string is unique"
|
||||
#endif
|
||||
|
||||
static const unsigned char FINGERPRINT_ascii_value[40] = HMAC_SHA1_SIG;
|
||||
|
||||
#define atox(c) ((c)>='a'?((c)-'a'+10):((c)>='A'?(c)-'A'+10:(c)-'0'))
|
||||
|
||||
extern const void *FIPS_text_start(), *FIPS_text_end();
|
||||
extern const unsigned char FIPS_rodata_start[], FIPS_rodata_end[];
|
||||
extern unsigned char FIPS_signature[20];
|
||||
extern unsigned int FIPS_incore_fingerprint(unsigned char *,unsigned int);
|
||||
|
||||
/*
|
||||
* As name suggests this code is executed prior main(). We use this
|
||||
* opportunity to fingerprint sequestered code in virtual address
|
||||
* space of target application.
|
||||
*/
|
||||
void FINGERPRINT_premain(void)
|
||||
{ unsigned char sig[sizeof(FIPS_signature)];
|
||||
const unsigned char * volatile p=FINGERPRINT_ascii_value;
|
||||
unsigned int len=sizeof(sig),i;
|
||||
|
||||
/* "volatilization" is done to disengage unwanted optimization... */
|
||||
if (*((volatile unsigned char *)p)=='?')
|
||||
{ if (FIPS_text_start()==NULL)
|
||||
{ fprintf(stderr,"FIPS_text_start() returns NULL\n");
|
||||
_exit(1);
|
||||
}
|
||||
#if defined(DEBUG_FINGERPRINT_PREMAIN)
|
||||
fprintf(stderr,".text:%p+%d=%p\n",FIPS_text_start(),
|
||||
(int)((size_t)FIPS_text_end()-(size_t)FIPS_text_start()),
|
||||
FIPS_text_end());
|
||||
fprintf(stderr,".rodata:%p+%d=%p\n",FIPS_rodata_start,
|
||||
(int)((size_t)FIPS_rodata_end-(size_t)FIPS_rodata_start),
|
||||
FIPS_rodata_end);
|
||||
#endif
|
||||
|
||||
len=FIPS_incore_fingerprint(sig,sizeof(sig));
|
||||
|
||||
if (len!=sizeof(sig))
|
||||
{ fprintf(stderr,"fingerprint length mismatch: %u\n",len);
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
for (i=0;i<len;i++) printf("%02x",sig[i]);
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
_exit(0);
|
||||
}
|
||||
else if (FIPS_signature[0]=='\0') do
|
||||
{ for (i=0;i<sizeof(FIPS_signature);i++,p+=2)
|
||||
FIPS_signature[i] = (atox(p[0])<<4)|atox(p[1]);
|
||||
|
||||
#if defined(DEBUG_FINGERPRINT_PREMAIN)
|
||||
if (getenv("OPENSSL_FIPS")==NULL) break;
|
||||
|
||||
len=FIPS_incore_fingerprint(sig,sizeof(sig));
|
||||
|
||||
if (memcmp(FIPS_signature,sig,sizeof(FIPS_signature)))
|
||||
{ fprintf(stderr,"FINGERPRINT_premain: FIPS_signature mismatch\n");
|
||||
_exit(1);
|
||||
}
|
||||
#endif
|
||||
} while(0);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/dso.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{ DSO *dso;
|
||||
DSO_FUNC_TYPE func;
|
||||
BIO *bio_err;
|
||||
|
||||
if (argc < 2)
|
||||
{ fprintf (stderr,"usage: %s libcrypto.dso\n",argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((bio_err=BIO_new(BIO_s_file())) == NULL)
|
||||
{ fprintf (stderr,"unable to allocate BIO\n");
|
||||
return 1;
|
||||
}
|
||||
BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
|
||||
ERR_load_crypto_strings();
|
||||
|
||||
dso = DSO_load(NULL,argv[1],NULL,DSO_FLAG_NO_NAME_TRANSLATION);
|
||||
if (dso == NULL)
|
||||
{ ERR_print_errors(bio_err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* This is not normally reached, because FINGERPRINT_premain should
|
||||
* have executed and terminated application already upon DSO_load... */
|
||||
func = DSO_bind_func(dso,"FINGERPRINT_premain");
|
||||
if (func == NULL)
|
||||
{ ERR_print_errors(bio_err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
(*func)();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
576
fips/fips_test_suite.c
Normal file
576
fips/fips_test_suite.c
Normal file
@ -0,0 +1,576 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2003 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
*
|
||||
* This command is intended as a test driver for the FIPS-140 testing
|
||||
* lab performing FIPS-140 validation. It demonstrates the use of the
|
||||
* OpenSSL library ito perform a variety of common cryptographic
|
||||
* functions. A power-up self test is demonstrated by deliberately
|
||||
* pointing to an invalid executable hash
|
||||
*
|
||||
* Contributed by Steve Marquess.
|
||||
*
|
||||
*/
|
||||
|
||||
#define OPENSSL_FIPSEVP
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#ifndef OPENSSL_FIPS
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
printf("No FIPS support\n");
|
||||
return(0);
|
||||
}
|
||||
#else
|
||||
|
||||
#define ERR_clear_error() while(0)
|
||||
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/dsa.h>
|
||||
#include <openssl/dh.h>
|
||||
|
||||
#include <openssl/fips.h>
|
||||
#include "fips_utl.h"
|
||||
|
||||
/* AES: encrypt and decrypt known plaintext, verify result matches original plaintext
|
||||
*/
|
||||
static int FIPS_aes_test(void)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char pltmp[16];
|
||||
unsigned char citmp[16];
|
||||
unsigned char key[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
|
||||
unsigned char plaintext[16] = "etaonrishdlcu";
|
||||
EVP_CIPHER_CTX ctx;
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
if (EVP_CipherInit_ex(&ctx, EVP_aes_128_ecb(),NULL, key, NULL, 1) <= 0)
|
||||
goto err;
|
||||
EVP_Cipher(&ctx, citmp, plaintext, 16);
|
||||
if (EVP_CipherInit_ex(&ctx, EVP_aes_128_ecb(),NULL, key, NULL, 0) <= 0)
|
||||
goto err;
|
||||
EVP_Cipher(&ctx, pltmp, citmp, 16);
|
||||
if (memcmp(pltmp, plaintext, 16))
|
||||
goto err;
|
||||
ret = 1;
|
||||
err:
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int FIPS_des3_test(void)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char pltmp[8];
|
||||
unsigned char citmp[8];
|
||||
unsigned char key[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,
|
||||
19,20,21,22,23,24};
|
||||
unsigned char plaintext[] = { 'e', 't', 'a', 'o', 'n', 'r', 'i', 's' };
|
||||
EVP_CIPHER_CTX ctx;
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
if (EVP_CipherInit_ex(&ctx, EVP_des_ede3_ecb(),NULL, key, NULL, 1) <= 0)
|
||||
goto err;
|
||||
EVP_Cipher(&ctx, citmp, plaintext, 8);
|
||||
if (EVP_CipherInit_ex(&ctx, EVP_des_ede3_ecb(),NULL, key, NULL, 0) <= 0)
|
||||
goto err;
|
||||
EVP_Cipher(&ctx, pltmp, citmp, 8);
|
||||
if (memcmp(pltmp, plaintext, 8))
|
||||
goto err;
|
||||
ret = 1;
|
||||
err:
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* DSA: generate keys and sign, verify input plaintext.
|
||||
*/
|
||||
static int FIPS_dsa_test(int bad)
|
||||
{
|
||||
DSA *dsa = NULL;
|
||||
unsigned char dgst[] = "etaonrishdlc";
|
||||
int r = 0;
|
||||
EVP_MD_CTX mctx;
|
||||
DSA_SIG *sig = NULL;
|
||||
|
||||
ERR_clear_error();
|
||||
EVP_MD_CTX_init(&mctx);
|
||||
dsa = FIPS_dsa_new();
|
||||
if (!dsa)
|
||||
goto end;
|
||||
if (!DSA_generate_parameters_ex(dsa, 1024,NULL,0,NULL,NULL,NULL))
|
||||
goto end;
|
||||
if (!DSA_generate_key(dsa))
|
||||
goto end;
|
||||
if (bad)
|
||||
BN_add_word(dsa->pub_key, 1);
|
||||
|
||||
if (!EVP_DigestInit_ex(&mctx, EVP_sha1(), NULL))
|
||||
goto end;
|
||||
if (!EVP_DigestUpdate(&mctx, dgst, sizeof(dgst) - 1))
|
||||
goto end;
|
||||
sig = FIPS_dsa_sign_ctx(dsa, &mctx);
|
||||
if (!sig)
|
||||
goto end;
|
||||
|
||||
if (!EVP_DigestInit_ex(&mctx, EVP_sha1(), NULL))
|
||||
goto end;
|
||||
if (!EVP_DigestUpdate(&mctx, dgst, sizeof(dgst) - 1))
|
||||
goto end;
|
||||
r = FIPS_dsa_verify_ctx(dsa, &mctx, sig);
|
||||
end:
|
||||
if (sig)
|
||||
DSA_SIG_free(sig);
|
||||
EVP_MD_CTX_cleanup(&mctx);
|
||||
if (dsa)
|
||||
FIPS_dsa_free(dsa);
|
||||
if (r != 1)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* RSA: generate keys and sign, verify input plaintext.
|
||||
*/
|
||||
static int FIPS_rsa_test(int bad)
|
||||
{
|
||||
RSA *key;
|
||||
unsigned char input_ptext[] = "etaonrishdlc";
|
||||
unsigned char buf[256];
|
||||
unsigned int slen;
|
||||
BIGNUM *bn;
|
||||
EVP_MD_CTX mctx;
|
||||
int r = 0;
|
||||
|
||||
ERR_clear_error();
|
||||
EVP_MD_CTX_init(&mctx);
|
||||
key = FIPS_rsa_new();
|
||||
bn = BN_new();
|
||||
if (!key || !bn)
|
||||
return 0;
|
||||
BN_set_word(bn, 65537);
|
||||
if (!RSA_generate_key_ex(key, 1024,bn,NULL))
|
||||
return 0;
|
||||
BN_free(bn);
|
||||
if (bad)
|
||||
BN_add_word(key->n, 1);
|
||||
|
||||
if (!EVP_DigestInit_ex(&mctx, EVP_sha1(), NULL))
|
||||
goto end;
|
||||
if (!EVP_DigestUpdate(&mctx, input_ptext, sizeof(input_ptext) - 1))
|
||||
goto end;
|
||||
if (!FIPS_rsa_sign_ctx(key, &mctx, RSA_PKCS1_PADDING, 0, NULL, buf, &slen))
|
||||
goto end;
|
||||
|
||||
if (!EVP_DigestInit_ex(&mctx, EVP_sha1(), NULL))
|
||||
goto end;
|
||||
if (!EVP_DigestUpdate(&mctx, input_ptext, sizeof(input_ptext) - 1))
|
||||
goto end;
|
||||
r = FIPS_rsa_verify_ctx(key, &mctx, RSA_PKCS1_PADDING, 0, NULL, buf, slen);
|
||||
end:
|
||||
EVP_MD_CTX_cleanup(&mctx);
|
||||
if (key)
|
||||
FIPS_rsa_free(key);
|
||||
if (r != 1)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* SHA1: generate hash of known digest value and compare to known
|
||||
precomputed correct hash
|
||||
*/
|
||||
static int FIPS_sha1_test()
|
||||
{
|
||||
unsigned char digest[SHA_DIGEST_LENGTH] =
|
||||
{ 0x11, 0xf1, 0x9a, 0x3a, 0xec, 0x1a, 0x1e, 0x8e, 0x65, 0xd4, 0x9a, 0x38, 0x0c, 0x8b, 0x1e, 0x2c, 0xe8, 0xb3, 0xc5, 0x18 };
|
||||
unsigned char str[] = "etaonrishd";
|
||||
|
||||
unsigned char md[SHA_DIGEST_LENGTH];
|
||||
|
||||
ERR_clear_error();
|
||||
if (!EVP_Digest(str,sizeof(str) - 1,md, NULL, EVP_sha1(), NULL)) return 0;
|
||||
if (memcmp(md,digest,sizeof(md)))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* SHA256: generate hash of known digest value and compare to known
|
||||
precomputed correct hash
|
||||
*/
|
||||
static int FIPS_sha256_test()
|
||||
{
|
||||
unsigned char digest[SHA256_DIGEST_LENGTH] =
|
||||
{0xf5, 0x53, 0xcd, 0xb8, 0xcf, 0x1, 0xee, 0x17, 0x9b, 0x93, 0xc9, 0x68, 0xc0, 0xea, 0x40, 0x91,
|
||||
0x6, 0xec, 0x8e, 0x11, 0x96, 0xc8, 0x5d, 0x1c, 0xaf, 0x64, 0x22, 0xe6, 0x50, 0x4f, 0x47, 0x57};
|
||||
unsigned char str[] = "etaonrishd";
|
||||
|
||||
unsigned char md[SHA256_DIGEST_LENGTH];
|
||||
|
||||
ERR_clear_error();
|
||||
if (!EVP_Digest(str,sizeof(str) - 1,md, NULL, EVP_sha256(), NULL)) return 0;
|
||||
if (memcmp(md,digest,sizeof(md)))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* SHA512: generate hash of known digest value and compare to known
|
||||
precomputed correct hash
|
||||
*/
|
||||
static int FIPS_sha512_test()
|
||||
{
|
||||
unsigned char digest[SHA512_DIGEST_LENGTH] =
|
||||
{0x99, 0xc9, 0xe9, 0x5b, 0x88, 0xd4, 0x78, 0x88, 0xdf, 0x88, 0x5f, 0x94, 0x71, 0x64, 0x28, 0xca,
|
||||
0x16, 0x1f, 0x3d, 0xf4, 0x1f, 0xf3, 0x0f, 0xc5, 0x03, 0x99, 0xb2, 0xd0, 0xe7, 0x0b, 0x94, 0x4a,
|
||||
0x45, 0xd2, 0x6c, 0x4f, 0x20, 0x06, 0xef, 0x71, 0xa9, 0x25, 0x7f, 0x24, 0xb1, 0xd9, 0x40, 0x22,
|
||||
0x49, 0x54, 0x10, 0xc2, 0x22, 0x9d, 0x27, 0xfe, 0xbd, 0xd6, 0xd6, 0xeb, 0x2d, 0x42, 0x1d, 0xa3};
|
||||
unsigned char str[] = "etaonrishd";
|
||||
|
||||
unsigned char md[SHA512_DIGEST_LENGTH];
|
||||
|
||||
ERR_clear_error();
|
||||
if (!EVP_Digest(str,sizeof(str) - 1,md, NULL, EVP_sha512(), NULL)) return 0;
|
||||
if (memcmp(md,digest,sizeof(md)))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* HMAC-SHA1: generate hash of known digest value and compare to known
|
||||
precomputed correct hash
|
||||
*/
|
||||
static int FIPS_hmac_sha1_test()
|
||||
{
|
||||
unsigned char key[] = "etaonrishd";
|
||||
unsigned char iv[] = "Sample text";
|
||||
unsigned char kaval[EVP_MAX_MD_SIZE] =
|
||||
{0x73, 0xf7, 0xa0, 0x48, 0xf8, 0x94, 0xed, 0xdd, 0x0a, 0xea, 0xea, 0x56, 0x1b, 0x61, 0x2e, 0x70,
|
||||
0xb2, 0xfb, 0xec, 0xc6};
|
||||
|
||||
unsigned char out[EVP_MAX_MD_SIZE];
|
||||
unsigned int outlen;
|
||||
|
||||
ERR_clear_error();
|
||||
if (!HMAC(EVP_sha1(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0;
|
||||
if (memcmp(out,kaval,outlen))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* HMAC-SHA224: generate hash of known digest value and compare to known
|
||||
precomputed correct hash
|
||||
*/
|
||||
static int FIPS_hmac_sha224_test()
|
||||
{
|
||||
unsigned char key[] = "etaonrishd";
|
||||
unsigned char iv[] = "Sample text";
|
||||
unsigned char kaval[EVP_MAX_MD_SIZE] =
|
||||
{0x75, 0x58, 0xd5, 0xbd, 0x55, 0x6d, 0x87, 0x0f, 0x75, 0xff, 0xbe, 0x1c, 0xb2, 0xf0, 0x20, 0x35,
|
||||
0xe5, 0x62, 0x49, 0xb6, 0x94, 0xb9, 0xfc, 0x65, 0x34, 0x33, 0x3a, 0x19};
|
||||
|
||||
unsigned char out[EVP_MAX_MD_SIZE];
|
||||
unsigned int outlen;
|
||||
|
||||
ERR_clear_error();
|
||||
if (!HMAC(EVP_sha224(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0;
|
||||
if (memcmp(out,kaval,outlen))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* HMAC-SHA256: generate hash of known digest value and compare to known
|
||||
precomputed correct hash
|
||||
*/
|
||||
static int FIPS_hmac_sha256_test()
|
||||
{
|
||||
unsigned char key[] = "etaonrishd";
|
||||
unsigned char iv[] = "Sample text";
|
||||
unsigned char kaval[EVP_MAX_MD_SIZE] =
|
||||
{0xe9, 0x17, 0xc1, 0x7b, 0x4c, 0x6b, 0x77, 0xda, 0xd2, 0x30, 0x36, 0x02, 0xf5, 0x72, 0x33, 0x87,
|
||||
0x9f, 0xc6, 0x6e, 0x7b, 0x7e, 0xa8, 0xea, 0xaa, 0x9f, 0xba, 0xee, 0x51, 0xff, 0xda, 0x24, 0xf4};
|
||||
|
||||
unsigned char out[EVP_MAX_MD_SIZE];
|
||||
unsigned int outlen;
|
||||
|
||||
ERR_clear_error();
|
||||
if (!HMAC(EVP_sha256(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0;
|
||||
if (memcmp(out,kaval,outlen))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* HMAC-SHA384: generate hash of known digest value and compare to known
|
||||
precomputed correct hash
|
||||
*/
|
||||
static int FIPS_hmac_sha384_test()
|
||||
{
|
||||
unsigned char key[] = "etaonrishd";
|
||||
unsigned char iv[] = "Sample text";
|
||||
unsigned char kaval[EVP_MAX_MD_SIZE] =
|
||||
{0xb2, 0x9d, 0x40, 0x58, 0x32, 0xc4, 0xe3, 0x31, 0xb6, 0x63, 0x08, 0x26, 0x99, 0xef, 0x3b, 0x10,
|
||||
0xe2, 0xdf, 0xf8, 0xff, 0xc6, 0xe1, 0x03, 0x29, 0x81, 0x2a, 0x1b, 0xac, 0xb0, 0x07, 0x39, 0x08,
|
||||
0xf3, 0x91, 0x35, 0x11, 0x76, 0xd6, 0x4c, 0x20, 0xfb, 0x4d, 0xc3, 0xf3, 0xb8, 0x9b, 0x88, 0x1c};
|
||||
|
||||
unsigned char out[EVP_MAX_MD_SIZE];
|
||||
unsigned int outlen;
|
||||
|
||||
ERR_clear_error();
|
||||
if (!HMAC(EVP_sha384(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0;
|
||||
if (memcmp(out,kaval,outlen))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* HMAC-SHA512: generate hash of known digest value and compare to known
|
||||
precomputed correct hash
|
||||
*/
|
||||
static int FIPS_hmac_sha512_test()
|
||||
{
|
||||
unsigned char key[] = "etaonrishd";
|
||||
unsigned char iv[] = "Sample text";
|
||||
unsigned char kaval[EVP_MAX_MD_SIZE] =
|
||||
{0xcd, 0x3e, 0xb9, 0x51, 0xb8, 0xbc, 0x7f, 0x9a, 0x23, 0xaf, 0xf3, 0x77, 0x59, 0x85, 0xa9, 0xe6,
|
||||
0xf7, 0xd1, 0x51, 0x96, 0x17, 0xe0, 0x92, 0xd8, 0xa6, 0x3b, 0xc1, 0xad, 0x7e, 0x24, 0xca, 0xb1,
|
||||
0xd7, 0x79, 0x0a, 0xa5, 0xea, 0x2c, 0x02, 0x58, 0x0b, 0xa6, 0x52, 0x6b, 0x61, 0x7f, 0xeb, 0x9c,
|
||||
0x47, 0x86, 0x5d, 0x74, 0x2b, 0x88, 0xdf, 0xee, 0x46, 0x69, 0x96, 0x3d, 0xa6, 0xd9, 0x2a, 0x53};
|
||||
|
||||
unsigned char out[EVP_MAX_MD_SIZE];
|
||||
unsigned int outlen;
|
||||
|
||||
ERR_clear_error();
|
||||
if (!HMAC(EVP_sha512(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0;
|
||||
if (memcmp(out,kaval,outlen))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* DH: generate shared parameters
|
||||
*/
|
||||
static int dh_test()
|
||||
{
|
||||
DH *dh;
|
||||
ERR_clear_error();
|
||||
dh = FIPS_dh_new();
|
||||
if (!dh)
|
||||
return 0;
|
||||
if (!DH_generate_parameters_ex(dh, 1024, 2, NULL))
|
||||
return 0;
|
||||
FIPS_dh_free(dh);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Zeroize
|
||||
*/
|
||||
static int Zeroize()
|
||||
{
|
||||
RSA *key;
|
||||
BIGNUM *bn;
|
||||
unsigned char userkey[16] =
|
||||
{ 0x48, 0x50, 0xf0, 0xa3, 0x3a, 0xed, 0xd3, 0xaf, 0x6e, 0x47, 0x7f, 0x83, 0x02, 0xb1, 0x09, 0x68 };
|
||||
size_t i;
|
||||
int n;
|
||||
|
||||
key = FIPS_rsa_new();
|
||||
bn = BN_new();
|
||||
if (!key || !bn)
|
||||
return 0;
|
||||
BN_set_word(bn, 65537);
|
||||
if (!RSA_generate_key_ex(key, 1024,bn,NULL))
|
||||
return 0;
|
||||
BN_free(bn);
|
||||
|
||||
n = BN_num_bytes(key->d);
|
||||
printf(" Generated %d byte RSA private key\n", n);
|
||||
printf("\tBN key before overwriting:\n");
|
||||
do_bn_print(stdout, key->d);
|
||||
BN_rand(key->d,n*8,-1,0);
|
||||
printf("\tBN key after overwriting:\n");
|
||||
do_bn_print(stdout, key->d);
|
||||
|
||||
printf("\tchar buffer key before overwriting: \n\t\t");
|
||||
for(i = 0; i < sizeof(userkey); i++) printf("%02x", userkey[i]);
|
||||
printf("\n");
|
||||
RAND_bytes(userkey, sizeof userkey);
|
||||
printf("\tchar buffer key after overwriting: \n\t\t");
|
||||
for(i = 0; i < sizeof(userkey); i++) printf("%02x", userkey[i]);
|
||||
printf("\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int Error;
|
||||
static const char * Fail(const char *msg)
|
||||
{
|
||||
Error++;
|
||||
return msg;
|
||||
}
|
||||
|
||||
static void test_msg(const char *msg, int result)
|
||||
{
|
||||
printf("%s...%s\n", msg, result ? "successful" : Fail("Failed!"));
|
||||
}
|
||||
|
||||
int main(int argc,char **argv)
|
||||
{
|
||||
|
||||
int do_corrupt_rsa_keygen = 0, do_corrupt_dsa_keygen = 0;
|
||||
int bad_rsa = 0, bad_dsa = 0;
|
||||
int do_rng_stick = 0;
|
||||
int no_exit = 0;
|
||||
|
||||
fips_set_error_print();
|
||||
|
||||
printf("\tFIPS-mode test application\n\n");
|
||||
|
||||
/* Load entropy from external file, if any */
|
||||
RAND_load_file(".rnd", 1024);
|
||||
|
||||
if (argv[1]) {
|
||||
/* Corrupted KAT tests */
|
||||
if (!strcmp(argv[1], "aes")) {
|
||||
FIPS_corrupt_aes();
|
||||
printf("AES encryption/decryption with corrupted KAT...\n");
|
||||
} else if (!strcmp(argv[1], "des")) {
|
||||
FIPS_corrupt_des();
|
||||
printf("DES3-ECB encryption/decryption with corrupted KAT...\n");
|
||||
} else if (!strcmp(argv[1], "dsa")) {
|
||||
FIPS_corrupt_dsa();
|
||||
printf("DSA key generation and signature validation with corrupted KAT...\n");
|
||||
} else if (!strcmp(argv[1], "rsa")) {
|
||||
FIPS_corrupt_rsa();
|
||||
printf("RSA key generation and signature validation with corrupted KAT...\n");
|
||||
} else if (!strcmp(argv[1], "rsakey")) {
|
||||
printf("RSA key generation and signature validation with corrupted key...\n");
|
||||
bad_rsa = 1;
|
||||
no_exit = 1;
|
||||
} else if (!strcmp(argv[1], "rsakeygen")) {
|
||||
do_corrupt_rsa_keygen = 1;
|
||||
no_exit = 1;
|
||||
printf("RSA key generation and signature validation with corrupted keygen...\n");
|
||||
} else if (!strcmp(argv[1], "dsakey")) {
|
||||
printf("DSA key generation and signature validation with corrupted key...\n");
|
||||
bad_dsa = 1;
|
||||
no_exit = 1;
|
||||
} else if (!strcmp(argv[1], "dsakeygen")) {
|
||||
do_corrupt_dsa_keygen = 1;
|
||||
no_exit = 1;
|
||||
printf("DSA key generation and signature validation with corrupted keygen...\n");
|
||||
} else if (!strcmp(argv[1], "sha1")) {
|
||||
FIPS_corrupt_sha1();
|
||||
printf("SHA-1 hash with corrupted KAT...\n");
|
||||
} else if (!strcmp(argv[1], "rng")) {
|
||||
FIPS_corrupt_rng();
|
||||
} else if (!strcmp(argv[1], "rngstick")) {
|
||||
do_rng_stick = 1;
|
||||
no_exit = 1;
|
||||
printf("RNG test with stuck continuous test...\n");
|
||||
} else {
|
||||
printf("Bad argument \"%s\"\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
if (!no_exit) {
|
||||
if (!FIPS_mode_set(1)) {
|
||||
printf("Power-up self test failed\n");
|
||||
exit(1);
|
||||
}
|
||||
printf("Power-up self test successful\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Non-Approved cryptographic operation
|
||||
*/
|
||||
printf("1. Non-Approved cryptographic operation test...\n");
|
||||
test_msg("\ta. Included algorithm (D-H)...", dh_test());
|
||||
|
||||
/* Power-up self test
|
||||
*/
|
||||
ERR_clear_error();
|
||||
test_msg("2. Automatic power-up self test", FIPS_mode_set(1));
|
||||
if (!FIPS_mode())
|
||||
exit(1);
|
||||
if (do_corrupt_dsa_keygen)
|
||||
FIPS_corrupt_dsa_keygen();
|
||||
if (do_corrupt_rsa_keygen)
|
||||
FIPS_corrupt_rsa_keygen();
|
||||
if (do_rng_stick)
|
||||
FIPS_rng_stick();
|
||||
|
||||
/* AES encryption/decryption
|
||||
*/
|
||||
test_msg("3. AES encryption/decryption", FIPS_aes_test());
|
||||
|
||||
/* RSA key generation and encryption/decryption
|
||||
*/
|
||||
test_msg("4. RSA key generation and encryption/decryption",
|
||||
FIPS_rsa_test(bad_rsa));
|
||||
|
||||
/* DES-CBC encryption/decryption
|
||||
*/
|
||||
test_msg("5. DES-ECB encryption/decryption", FIPS_des3_test());
|
||||
|
||||
/* DSA key generation and signature validation
|
||||
*/
|
||||
test_msg("6. DSA key generation and signature validation",
|
||||
FIPS_dsa_test(bad_dsa));
|
||||
|
||||
/* SHA-1 hash
|
||||
*/
|
||||
test_msg("7a. SHA-1 hash", FIPS_sha1_test());
|
||||
|
||||
/* SHA-256 hash
|
||||
*/
|
||||
test_msg("7b. SHA-256 hash", FIPS_sha256_test());
|
||||
|
||||
/* SHA-512 hash
|
||||
*/
|
||||
test_msg("7c. SHA-512 hash", FIPS_sha512_test());
|
||||
|
||||
/* HMAC-SHA-1 hash
|
||||
*/
|
||||
test_msg("7d. HMAC-SHA-1 hash", FIPS_hmac_sha1_test());
|
||||
|
||||
/* HMAC-SHA-224 hash
|
||||
*/
|
||||
test_msg("7e. HMAC-SHA-224 hash", FIPS_hmac_sha224_test());
|
||||
|
||||
/* HMAC-SHA-256 hash
|
||||
*/
|
||||
test_msg("7f. HMAC-SHA-256 hash", FIPS_hmac_sha256_test());
|
||||
|
||||
/* HMAC-SHA-384 hash
|
||||
*/
|
||||
test_msg("7g. HMAC-SHA-384 hash", FIPS_hmac_sha384_test());
|
||||
|
||||
/* HMAC-SHA-512 hash
|
||||
*/
|
||||
test_msg("7h. HMAC-SHA-512 hash", FIPS_hmac_sha512_test());
|
||||
|
||||
/* Non-Approved cryptographic operation
|
||||
*/
|
||||
printf("8. Non-Approved cryptographic operation test...\n");
|
||||
printf("\ta. Included algorithm (D-H)...%s\n",
|
||||
dh_test() ? "successful as expected"
|
||||
: Fail("failed INCORRECTLY!") );
|
||||
|
||||
/* Zeroization
|
||||
*/
|
||||
printf("9. Zero-ization...\n\t%s\n",
|
||||
Zeroize() ? "successful as expected"
|
||||
: Fail("failed INCORRECTLY!") );
|
||||
|
||||
printf("\nAll tests completed with %d errors\n", Error);
|
||||
return Error ? 1 : 0;
|
||||
}
|
||||
|
||||
#endif
|
376
fips/fips_utl.h
Normal file
376
fips/fips_utl.h
Normal file
@ -0,0 +1,376 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2007 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
int hex2bin(const char *in, unsigned char *out);
|
||||
unsigned char *hex2bin_m(const char *in, long *plen);
|
||||
int do_hex2bn(BIGNUM **pr, const char *in);
|
||||
int do_bn_print(FILE *out, BIGNUM *bn);
|
||||
int do_bn_print_name(FILE *out, const char *name, BIGNUM *bn);
|
||||
int parse_line(char **pkw, char **pval, char *linebuf, char *olinebuf);
|
||||
BIGNUM *hex2bn(const char *in);
|
||||
int bin2hex(const unsigned char *in,int len,char *out);
|
||||
void pv(const char *tag,const unsigned char *val,int len);
|
||||
int tidy_line(char *linebuf, char *olinebuf);
|
||||
int bint2bin(const char *in, int len, unsigned char *out);
|
||||
int bin2bint(const unsigned char *in,int len,char *out);
|
||||
void PrintValue(char *tag, unsigned char *val, int len);
|
||||
void OutputValue(char *tag, unsigned char *val, int len, FILE *rfp,int bitmode);
|
||||
|
||||
static int no_err;
|
||||
|
||||
static void put_err_cb(int lib, int func,int reason,const char *file,int line)
|
||||
{
|
||||
if (no_err)
|
||||
return;
|
||||
fprintf(stderr, "ERROR:lib=%d,func=%d,reason=%d"
|
||||
":file=%s:line=%d\n",
|
||||
lib, func, reason, file, line);
|
||||
}
|
||||
|
||||
static void add_err_cb(int num, va_list args)
|
||||
{
|
||||
int i;
|
||||
char *str;
|
||||
if (no_err)
|
||||
return;
|
||||
fputs("\t", stderr);
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
str = va_arg(args, char *);
|
||||
if (str)
|
||||
fputs(str, stderr);
|
||||
}
|
||||
fputs("\n", stderr);
|
||||
}
|
||||
|
||||
static void fips_set_error_print(void)
|
||||
{
|
||||
FIPS_set_error_callbacks(put_err_cb, add_err_cb);
|
||||
}
|
||||
|
||||
int hex2bin(const char *in, unsigned char *out)
|
||||
{
|
||||
int n1, n2;
|
||||
unsigned char ch;
|
||||
|
||||
for (n1=0,n2=0 ; in[n1] && in[n1] != '\n' ; )
|
||||
{ /* first byte */
|
||||
if ((in[n1] >= '0') && (in[n1] <= '9'))
|
||||
ch = in[n1++] - '0';
|
||||
else if ((in[n1] >= 'A') && (in[n1] <= 'F'))
|
||||
ch = in[n1++] - 'A' + 10;
|
||||
else if ((in[n1] >= 'a') && (in[n1] <= 'f'))
|
||||
ch = in[n1++] - 'a' + 10;
|
||||
else
|
||||
return -1;
|
||||
if(!in[n1])
|
||||
{
|
||||
out[n2++]=ch;
|
||||
break;
|
||||
}
|
||||
out[n2] = ch << 4;
|
||||
/* second byte */
|
||||
if ((in[n1] >= '0') && (in[n1] <= '9'))
|
||||
ch = in[n1++] - '0';
|
||||
else if ((in[n1] >= 'A') && (in[n1] <= 'F'))
|
||||
ch = in[n1++] - 'A' + 10;
|
||||
else if ((in[n1] >= 'a') && (in[n1] <= 'f'))
|
||||
ch = in[n1++] - 'a' + 10;
|
||||
else
|
||||
return -1;
|
||||
out[n2++] |= ch;
|
||||
}
|
||||
return n2;
|
||||
}
|
||||
|
||||
unsigned char *hex2bin_m(const char *in, long *plen)
|
||||
{
|
||||
unsigned char *p;
|
||||
p = OPENSSL_malloc((strlen(in) + 1)/2);
|
||||
*plen = hex2bin(in, p);
|
||||
return p;
|
||||
}
|
||||
|
||||
int do_hex2bn(BIGNUM **pr, const char *in)
|
||||
{
|
||||
unsigned char *p;
|
||||
long plen;
|
||||
int r = 0;
|
||||
p = hex2bin_m(in, &plen);
|
||||
if (!p)
|
||||
return 0;
|
||||
if (!*pr)
|
||||
*pr = BN_new();
|
||||
if (!*pr)
|
||||
return 0;
|
||||
if (BN_bin2bn(p, plen, *pr))
|
||||
r = 1;
|
||||
OPENSSL_free(p);
|
||||
return r;
|
||||
}
|
||||
|
||||
int do_bn_print(FILE *out, BIGNUM *bn)
|
||||
{
|
||||
int len, i;
|
||||
unsigned char *tmp;
|
||||
len = BN_num_bytes(bn);
|
||||
if (len == 0)
|
||||
{
|
||||
fputs("00", out);
|
||||
return 1;
|
||||
}
|
||||
|
||||
tmp = OPENSSL_malloc(len);
|
||||
if (!tmp)
|
||||
{
|
||||
fprintf(stderr, "Memory allocation error\n");
|
||||
return 0;
|
||||
}
|
||||
BN_bn2bin(bn, tmp);
|
||||
for (i = 0; i < len; i++)
|
||||
fprintf(out, "%02x", tmp[i]);
|
||||
OPENSSL_free(tmp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int do_bn_print_name(FILE *out, const char *name, BIGNUM *bn)
|
||||
{
|
||||
int r;
|
||||
fprintf(out, "%s = ", name);
|
||||
r = do_bn_print(out, bn);
|
||||
if (!r)
|
||||
return 0;
|
||||
fputs("\n", out);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int parse_line(char **pkw, char **pval, char *linebuf, char *olinebuf)
|
||||
{
|
||||
char *keyword, *value, *p, *q;
|
||||
strcpy(linebuf, olinebuf);
|
||||
keyword = linebuf;
|
||||
/* Skip leading space */
|
||||
while (isspace((unsigned char)*keyword))
|
||||
keyword++;
|
||||
|
||||
/* Look for = sign */
|
||||
p = strchr(linebuf, '=');
|
||||
|
||||
/* If no '=' exit */
|
||||
if (!p)
|
||||
return 0;
|
||||
|
||||
q = p - 1;
|
||||
|
||||
/* Remove trailing space */
|
||||
while (isspace((unsigned char)*q))
|
||||
*q-- = 0;
|
||||
|
||||
*p = 0;
|
||||
value = p + 1;
|
||||
|
||||
/* Remove leading space from value */
|
||||
while (isspace((unsigned char)*value))
|
||||
value++;
|
||||
|
||||
/* Remove trailing space from value */
|
||||
p = value + strlen(value) - 1;
|
||||
|
||||
while (*p == '\n' || isspace((unsigned char)*p))
|
||||
*p-- = 0;
|
||||
|
||||
*pkw = keyword;
|
||||
*pval = value;
|
||||
return 1;
|
||||
}
|
||||
|
||||
BIGNUM *hex2bn(const char *in)
|
||||
{
|
||||
BIGNUM *p=NULL;
|
||||
|
||||
if (!do_hex2bn(&p, in))
|
||||
return NULL;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
int bin2hex(const unsigned char *in,int len,char *out)
|
||||
{
|
||||
int n1, n2;
|
||||
unsigned char ch;
|
||||
|
||||
for (n1=0,n2=0 ; n1 < len ; ++n1)
|
||||
{
|
||||
ch=in[n1] >> 4;
|
||||
if (ch <= 0x09)
|
||||
out[n2++]=ch+'0';
|
||||
else
|
||||
out[n2++]=ch-10+'a';
|
||||
ch=in[n1] & 0x0f;
|
||||
if(ch <= 0x09)
|
||||
out[n2++]=ch+'0';
|
||||
else
|
||||
out[n2++]=ch-10+'a';
|
||||
}
|
||||
out[n2]='\0';
|
||||
return n2;
|
||||
}
|
||||
|
||||
void pv(const char *tag,const unsigned char *val,int len)
|
||||
{
|
||||
char obuf[2048];
|
||||
|
||||
bin2hex(val,len,obuf);
|
||||
printf("%s = %s\n",tag,obuf);
|
||||
}
|
||||
|
||||
/* To avoid extensive changes to test program at this stage just convert
|
||||
* the input line into an acceptable form. Keyword lines converted to form
|
||||
* "keyword = value\n" no matter what white space present, all other lines
|
||||
* just have leading and trailing space removed.
|
||||
*/
|
||||
|
||||
int tidy_line(char *linebuf, char *olinebuf)
|
||||
{
|
||||
char *keyword, *value, *p, *q;
|
||||
strcpy(linebuf, olinebuf);
|
||||
keyword = linebuf;
|
||||
/* Skip leading space */
|
||||
while (isspace((unsigned char)*keyword))
|
||||
keyword++;
|
||||
/* Look for = sign */
|
||||
p = strchr(linebuf, '=');
|
||||
|
||||
/* If no '=' just chop leading, trailing ws */
|
||||
if (!p)
|
||||
{
|
||||
p = keyword + strlen(keyword) - 1;
|
||||
while (*p == '\n' || isspace((unsigned char)*p))
|
||||
*p-- = 0;
|
||||
strcpy(olinebuf, keyword);
|
||||
strcat(olinebuf, "\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
q = p - 1;
|
||||
|
||||
/* Remove trailing space */
|
||||
while (isspace((unsigned char)*q))
|
||||
*q-- = 0;
|
||||
|
||||
*p = 0;
|
||||
value = p + 1;
|
||||
|
||||
/* Remove leading space from value */
|
||||
while (isspace((unsigned char)*value))
|
||||
value++;
|
||||
|
||||
/* Remove trailing space from value */
|
||||
p = value + strlen(value) - 1;
|
||||
|
||||
while (*p == '\n' || isspace((unsigned char)*p))
|
||||
*p-- = 0;
|
||||
|
||||
strcpy(olinebuf, keyword);
|
||||
strcat(olinebuf, " = ");
|
||||
strcat(olinebuf, value);
|
||||
strcat(olinebuf, "\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* NB: this return the number of _bits_ read */
|
||||
int bint2bin(const char *in, int len, unsigned char *out)
|
||||
{
|
||||
int n;
|
||||
|
||||
memset(out,0,len);
|
||||
for(n=0 ; n < len ; ++n)
|
||||
if(in[n] == '1')
|
||||
out[n/8]|=(0x80 >> (n%8));
|
||||
return len;
|
||||
}
|
||||
|
||||
int bin2bint(const unsigned char *in,int len,char *out)
|
||||
{
|
||||
int n;
|
||||
|
||||
for(n=0 ; n < len ; ++n)
|
||||
out[n]=(in[n/8]&(0x80 >> (n%8))) ? '1' : '0';
|
||||
return n;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------*/
|
||||
|
||||
void PrintValue(char *tag, unsigned char *val, int len)
|
||||
{
|
||||
#if VERBOSE
|
||||
char obuf[2048];
|
||||
int olen;
|
||||
olen = bin2hex(val, len, obuf);
|
||||
printf("%s = %.*s\n", tag, olen, obuf);
|
||||
#endif
|
||||
}
|
||||
|
||||
void OutputValue(char *tag, unsigned char *val, int len, FILE *rfp,int bitmode)
|
||||
{
|
||||
char obuf[2048];
|
||||
int olen;
|
||||
|
||||
if(bitmode)
|
||||
olen=bin2bint(val,len,obuf);
|
||||
else
|
||||
olen=bin2hex(val,len,obuf);
|
||||
|
||||
fprintf(rfp, "%s = %.*s\n", tag, olen, obuf);
|
||||
#if VERBOSE
|
||||
printf("%s = %.*s\n", tag, olen, obuf);
|
||||
#endif
|
||||
}
|
||||
|
887
fips/fipsalgtest.pl
Normal file
887
fips/fipsalgtest.pl
Normal file
@ -0,0 +1,887 @@
|
||||
#!/usr/bin/perl -w
|
||||
# Perl utility to run or verify FIPS 140-2 CMVP algorithm tests based on the
|
||||
# pathnames of input algorithm test files actually present (the unqualified
|
||||
# file names are consistent but the pathnames are not).
|
||||
#
|
||||
|
||||
# FIPS test definitions
|
||||
# List of all the unqualified file names we expect and command lines to run
|
||||
|
||||
# DSA tests
|
||||
my @fips_dsa_test_list = (
|
||||
|
||||
"DSA",
|
||||
|
||||
[ "PQGGen", "fips_dssvs pqg" ],
|
||||
[ "KeyPair", "fips_dssvs keypair" ],
|
||||
[ "SigGen", "fips_dssvs siggen" ],
|
||||
[ "SigVer", "fips_dssvs sigver" ]
|
||||
|
||||
);
|
||||
|
||||
my @fips_dsa_pqgver_test_list = (
|
||||
|
||||
[ "PQGVer", "fips_dssvs pqgver" ]
|
||||
|
||||
);
|
||||
|
||||
# RSA tests
|
||||
|
||||
my @fips_rsa_test_list = (
|
||||
|
||||
"RSA",
|
||||
|
||||
[ "SigGen15", "fips_rsastest" ],
|
||||
[ "SigVer15", "fips_rsavtest" ],
|
||||
[ "SigVerRSA", "fips_rsavtest -x931" ],
|
||||
[ "KeyGenRSA", "fips_rsagtest" ],
|
||||
[ "SigGenRSA", "fips_rsastest -x931" ]
|
||||
|
||||
);
|
||||
|
||||
# Special cases for PSS. The filename itself is
|
||||
# not sufficient to determine the test. Addditionally we
|
||||
# need to examine the file contents to determine the salt length
|
||||
# In these cases the test filename has (saltlen) appended.
|
||||
|
||||
# RSA PSS salt length 0 tests
|
||||
|
||||
my @fips_rsa_pss0_test_list = (
|
||||
|
||||
[ "SigGenPSS(0)", "fips_rsastest -saltlen 0" ],
|
||||
[ "SigVerPSS(0)", "fips_rsavtest -saltlen 0" ]
|
||||
|
||||
);
|
||||
|
||||
# RSA PSS salt length 62 tests
|
||||
|
||||
my @fips_rsa_pss62_test_list = (
|
||||
[ "SigGenPSS(62)", "fips_rsastest -saltlen 62" ],
|
||||
[ "SigVerPSS(62)", "fips_rsavtest -saltlen 62" ]
|
||||
|
||||
);
|
||||
|
||||
# SHA tests
|
||||
|
||||
my @fips_sha_test_list = (
|
||||
|
||||
"SHA",
|
||||
|
||||
[ "SHA1LongMsg", "fips_shatest" ],
|
||||
[ "SHA1Monte", "fips_shatest" ],
|
||||
[ "SHA1ShortMsg", "fips_shatest" ],
|
||||
[ "SHA224LongMsg", "fips_shatest" ],
|
||||
[ "SHA224Monte", "fips_shatest" ],
|
||||
[ "SHA224ShortMsg", "fips_shatest" ],
|
||||
[ "SHA256LongMsg", "fips_shatest" ],
|
||||
[ "SHA256Monte", "fips_shatest" ],
|
||||
[ "SHA256ShortMsg", "fips_shatest" ],
|
||||
[ "SHA384LongMsg", "fips_shatest" ],
|
||||
[ "SHA384Monte", "fips_shatest" ],
|
||||
[ "SHA384ShortMsg", "fips_shatest" ],
|
||||
[ "SHA512LongMsg", "fips_shatest" ],
|
||||
[ "SHA512Monte", "fips_shatest" ],
|
||||
[ "SHA512ShortMsg", "fips_shatest" ]
|
||||
|
||||
);
|
||||
|
||||
# HMAC
|
||||
|
||||
my @fips_hmac_test_list = (
|
||||
|
||||
"HMAC",
|
||||
|
||||
[ "HMAC", "fips_hmactest" ]
|
||||
|
||||
);
|
||||
|
||||
# RAND tests, AES version
|
||||
|
||||
my @fips_rand_aes_test_list = (
|
||||
|
||||
"RAND (AES)",
|
||||
|
||||
[ "ANSI931_AES128MCT", "fips_rngvs mct" ],
|
||||
[ "ANSI931_AES192MCT", "fips_rngvs mct" ],
|
||||
[ "ANSI931_AES256MCT", "fips_rngvs mct" ],
|
||||
[ "ANSI931_AES128VST", "fips_rngvs vst" ],
|
||||
[ "ANSI931_AES192VST", "fips_rngvs vst" ],
|
||||
[ "ANSI931_AES256VST", "fips_rngvs vst" ]
|
||||
|
||||
);
|
||||
|
||||
# RAND tests, DES2 version
|
||||
|
||||
my @fips_rand_des2_test_list = (
|
||||
|
||||
"RAND (DES2)",
|
||||
|
||||
[ "ANSI931_TDES2MCT", "fips_rngvs mct" ],
|
||||
[ "ANSI931_TDES2VST", "fips_rngvs vst" ]
|
||||
|
||||
);
|
||||
|
||||
# AES tests
|
||||
|
||||
my @fips_aes_test_list = (
|
||||
|
||||
"AES",
|
||||
|
||||
[ "CBCGFSbox128", "fips_aesavs -f" ],
|
||||
[ "CBCGFSbox192", "fips_aesavs -f" ],
|
||||
[ "CBCGFSbox256", "fips_aesavs -f" ],
|
||||
[ "CBCKeySbox128", "fips_aesavs -f" ],
|
||||
[ "CBCKeySbox192", "fips_aesavs -f" ],
|
||||
[ "CBCKeySbox256", "fips_aesavs -f" ],
|
||||
[ "CBCMCT128", "fips_aesavs -f" ],
|
||||
[ "CBCMCT192", "fips_aesavs -f" ],
|
||||
[ "CBCMCT256", "fips_aesavs -f" ],
|
||||
[ "CBCMMT128", "fips_aesavs -f" ],
|
||||
[ "CBCMMT192", "fips_aesavs -f" ],
|
||||
[ "CBCMMT256", "fips_aesavs -f" ],
|
||||
[ "CBCVarKey128", "fips_aesavs -f" ],
|
||||
[ "CBCVarKey192", "fips_aesavs -f" ],
|
||||
[ "CBCVarKey256", "fips_aesavs -f" ],
|
||||
[ "CBCVarTxt128", "fips_aesavs -f" ],
|
||||
[ "CBCVarTxt192", "fips_aesavs -f" ],
|
||||
[ "CBCVarTxt256", "fips_aesavs -f" ],
|
||||
[ "CFB128GFSbox128", "fips_aesavs -f" ],
|
||||
[ "CFB128GFSbox192", "fips_aesavs -f" ],
|
||||
[ "CFB128GFSbox256", "fips_aesavs -f" ],
|
||||
[ "CFB128KeySbox128", "fips_aesavs -f" ],
|
||||
[ "CFB128KeySbox192", "fips_aesavs -f" ],
|
||||
[ "CFB128KeySbox256", "fips_aesavs -f" ],
|
||||
[ "CFB128MCT128", "fips_aesavs -f" ],
|
||||
[ "CFB128MCT192", "fips_aesavs -f" ],
|
||||
[ "CFB128MCT256", "fips_aesavs -f" ],
|
||||
[ "CFB128MMT128", "fips_aesavs -f" ],
|
||||
[ "CFB128MMT192", "fips_aesavs -f" ],
|
||||
[ "CFB128MMT256", "fips_aesavs -f" ],
|
||||
[ "CFB128VarKey128", "fips_aesavs -f" ],
|
||||
[ "CFB128VarKey192", "fips_aesavs -f" ],
|
||||
[ "CFB128VarKey256", "fips_aesavs -f" ],
|
||||
[ "CFB128VarTxt128", "fips_aesavs -f" ],
|
||||
[ "CFB128VarTxt192", "fips_aesavs -f" ],
|
||||
[ "CFB128VarTxt256", "fips_aesavs -f" ],
|
||||
[ "CFB8GFSbox128", "fips_aesavs -f" ],
|
||||
[ "CFB8GFSbox192", "fips_aesavs -f" ],
|
||||
[ "CFB8GFSbox256", "fips_aesavs -f" ],
|
||||
[ "CFB8KeySbox128", "fips_aesavs -f" ],
|
||||
[ "CFB8KeySbox192", "fips_aesavs -f" ],
|
||||
[ "CFB8KeySbox256", "fips_aesavs -f" ],
|
||||
[ "CFB8MCT128", "fips_aesavs -f" ],
|
||||
[ "CFB8MCT192", "fips_aesavs -f" ],
|
||||
[ "CFB8MCT256", "fips_aesavs -f" ],
|
||||
[ "CFB8MMT128", "fips_aesavs -f" ],
|
||||
[ "CFB8MMT192", "fips_aesavs -f" ],
|
||||
[ "CFB8MMT256", "fips_aesavs -f" ],
|
||||
[ "CFB8VarKey128", "fips_aesavs -f" ],
|
||||
[ "CFB8VarKey192", "fips_aesavs -f" ],
|
||||
[ "CFB8VarKey256", "fips_aesavs -f" ],
|
||||
[ "CFB8VarTxt128", "fips_aesavs -f" ],
|
||||
[ "CFB8VarTxt192", "fips_aesavs -f" ],
|
||||
[ "CFB8VarTxt256", "fips_aesavs -f" ],
|
||||
|
||||
[ "ECBGFSbox128", "fips_aesavs -f" ],
|
||||
[ "ECBGFSbox192", "fips_aesavs -f" ],
|
||||
[ "ECBGFSbox256", "fips_aesavs -f" ],
|
||||
[ "ECBKeySbox128", "fips_aesavs -f" ],
|
||||
[ "ECBKeySbox192", "fips_aesavs -f" ],
|
||||
[ "ECBKeySbox256", "fips_aesavs -f" ],
|
||||
[ "ECBMCT128", "fips_aesavs -f" ],
|
||||
[ "ECBMCT192", "fips_aesavs -f" ],
|
||||
[ "ECBMCT256", "fips_aesavs -f" ],
|
||||
[ "ECBMMT128", "fips_aesavs -f" ],
|
||||
[ "ECBMMT192", "fips_aesavs -f" ],
|
||||
[ "ECBMMT256", "fips_aesavs -f" ],
|
||||
[ "ECBVarKey128", "fips_aesavs -f" ],
|
||||
[ "ECBVarKey192", "fips_aesavs -f" ],
|
||||
[ "ECBVarKey256", "fips_aesavs -f" ],
|
||||
[ "ECBVarTxt128", "fips_aesavs -f" ],
|
||||
[ "ECBVarTxt192", "fips_aesavs -f" ],
|
||||
[ "ECBVarTxt256", "fips_aesavs -f" ],
|
||||
[ "OFBGFSbox128", "fips_aesavs -f" ],
|
||||
[ "OFBGFSbox192", "fips_aesavs -f" ],
|
||||
[ "OFBGFSbox256", "fips_aesavs -f" ],
|
||||
[ "OFBKeySbox128", "fips_aesavs -f" ],
|
||||
[ "OFBKeySbox192", "fips_aesavs -f" ],
|
||||
[ "OFBKeySbox256", "fips_aesavs -f" ],
|
||||
[ "OFBMCT128", "fips_aesavs -f" ],
|
||||
[ "OFBMCT192", "fips_aesavs -f" ],
|
||||
[ "OFBMCT256", "fips_aesavs -f" ],
|
||||
[ "OFBMMT128", "fips_aesavs -f" ],
|
||||
[ "OFBMMT192", "fips_aesavs -f" ],
|
||||
[ "OFBMMT256", "fips_aesavs -f" ],
|
||||
[ "OFBVarKey128", "fips_aesavs -f" ],
|
||||
[ "OFBVarKey192", "fips_aesavs -f" ],
|
||||
[ "OFBVarKey256", "fips_aesavs -f" ],
|
||||
[ "OFBVarTxt128", "fips_aesavs -f" ],
|
||||
[ "OFBVarTxt192", "fips_aesavs -f" ],
|
||||
[ "OFBVarTxt256", "fips_aesavs -f" ]
|
||||
|
||||
);
|
||||
|
||||
my @fips_aes_cfb1_test_list = (
|
||||
|
||||
# AES CFB1 tests
|
||||
|
||||
[ "CFB1GFSbox128", "fips_aesavs -f" ],
|
||||
[ "CFB1GFSbox192", "fips_aesavs -f" ],
|
||||
[ "CFB1GFSbox256", "fips_aesavs -f" ],
|
||||
[ "CFB1KeySbox128", "fips_aesavs -f" ],
|
||||
[ "CFB1KeySbox192", "fips_aesavs -f" ],
|
||||
[ "CFB1KeySbox256", "fips_aesavs -f" ],
|
||||
[ "CFB1MCT128", "fips_aesavs -f" ],
|
||||
[ "CFB1MCT192", "fips_aesavs -f" ],
|
||||
[ "CFB1MCT256", "fips_aesavs -f" ],
|
||||
[ "CFB1MMT128", "fips_aesavs -f" ],
|
||||
[ "CFB1MMT192", "fips_aesavs -f" ],
|
||||
[ "CFB1MMT256", "fips_aesavs -f" ],
|
||||
[ "CFB1VarKey128", "fips_aesavs -f" ],
|
||||
[ "CFB1VarKey192", "fips_aesavs -f" ],
|
||||
[ "CFB1VarKey256", "fips_aesavs -f" ],
|
||||
[ "CFB1VarTxt128", "fips_aesavs -f" ],
|
||||
[ "CFB1VarTxt192", "fips_aesavs -f" ],
|
||||
[ "CFB1VarTxt256", "fips_aesavs -f" ]
|
||||
|
||||
);
|
||||
|
||||
# Triple DES tests
|
||||
|
||||
my @fips_des3_test_list = (
|
||||
|
||||
"Triple DES",
|
||||
|
||||
[ "TCBCinvperm", "fips_desmovs -f" ],
|
||||
[ "TCBCMMT1", "fips_desmovs -f" ],
|
||||
[ "TCBCMMT2", "fips_desmovs -f" ],
|
||||
[ "TCBCMMT3", "fips_desmovs -f" ],
|
||||
[ "TCBCMonte1", "fips_desmovs -f" ],
|
||||
[ "TCBCMonte2", "fips_desmovs -f" ],
|
||||
[ "TCBCMonte3", "fips_desmovs -f" ],
|
||||
[ "TCBCpermop", "fips_desmovs -f" ],
|
||||
[ "TCBCsubtab", "fips_desmovs -f" ],
|
||||
[ "TCBCvarkey", "fips_desmovs -f" ],
|
||||
[ "TCBCvartext", "fips_desmovs -f" ],
|
||||
[ "TCFB64invperm", "fips_desmovs -f" ],
|
||||
[ "TCFB64MMT1", "fips_desmovs -f" ],
|
||||
[ "TCFB64MMT2", "fips_desmovs -f" ],
|
||||
[ "TCFB64MMT3", "fips_desmovs -f" ],
|
||||
[ "TCFB64Monte1", "fips_desmovs -f" ],
|
||||
[ "TCFB64Monte2", "fips_desmovs -f" ],
|
||||
[ "TCFB64Monte3", "fips_desmovs -f" ],
|
||||
[ "TCFB64permop", "fips_desmovs -f" ],
|
||||
[ "TCFB64subtab", "fips_desmovs -f" ],
|
||||
[ "TCFB64varkey", "fips_desmovs -f" ],
|
||||
[ "TCFB64vartext", "fips_desmovs -f" ],
|
||||
[ "TCFB8invperm", "fips_desmovs -f" ],
|
||||
[ "TCFB8MMT1", "fips_desmovs -f" ],
|
||||
[ "TCFB8MMT2", "fips_desmovs -f" ],
|
||||
[ "TCFB8MMT3", "fips_desmovs -f" ],
|
||||
[ "TCFB8Monte1", "fips_desmovs -f" ],
|
||||
[ "TCFB8Monte2", "fips_desmovs -f" ],
|
||||
[ "TCFB8Monte3", "fips_desmovs -f" ],
|
||||
[ "TCFB8permop", "fips_desmovs -f" ],
|
||||
[ "TCFB8subtab", "fips_desmovs -f" ],
|
||||
[ "TCFB8varkey", "fips_desmovs -f" ],
|
||||
[ "TCFB8vartext", "fips_desmovs -f" ],
|
||||
[ "TECBinvperm", "fips_desmovs -f" ],
|
||||
[ "TECBMMT1", "fips_desmovs -f" ],
|
||||
[ "TECBMMT2", "fips_desmovs -f" ],
|
||||
[ "TECBMMT3", "fips_desmovs -f" ],
|
||||
[ "TECBMonte1", "fips_desmovs -f" ],
|
||||
[ "TECBMonte2", "fips_desmovs -f" ],
|
||||
[ "TECBMonte3", "fips_desmovs -f" ],
|
||||
[ "TECBpermop", "fips_desmovs -f" ],
|
||||
[ "TECBsubtab", "fips_desmovs -f" ],
|
||||
[ "TECBvarkey", "fips_desmovs -f" ],
|
||||
[ "TECBvartext", "fips_desmovs -f" ],
|
||||
[ "TOFBinvperm", "fips_desmovs -f" ],
|
||||
[ "TOFBMMT1", "fips_desmovs -f" ],
|
||||
[ "TOFBMMT2", "fips_desmovs -f" ],
|
||||
[ "TOFBMMT3", "fips_desmovs -f" ],
|
||||
[ "TOFBMonte1", "fips_desmovs -f" ],
|
||||
[ "TOFBMonte2", "fips_desmovs -f" ],
|
||||
[ "TOFBMonte3", "fips_desmovs -f" ],
|
||||
[ "TOFBpermop", "fips_desmovs -f" ],
|
||||
[ "TOFBsubtab", "fips_desmovs -f" ],
|
||||
[ "TOFBvarkey", "fips_desmovs -f" ],
|
||||
[ "TOFBvartext", "fips_desmovs -f" ]
|
||||
|
||||
);
|
||||
|
||||
my @fips_des3_cfb1_test_list = (
|
||||
|
||||
# DES3 CFB1 tests
|
||||
|
||||
[ "TCFB1invperm", "fips_desmovs -f" ],
|
||||
[ "TCFB1MMT1", "fips_desmovs -f" ],
|
||||
[ "TCFB1MMT2", "fips_desmovs -f" ],
|
||||
[ "TCFB1MMT3", "fips_desmovs -f" ],
|
||||
[ "TCFB1Monte1", "fips_desmovs -f" ],
|
||||
[ "TCFB1Monte2", "fips_desmovs -f" ],
|
||||
[ "TCFB1Monte3", "fips_desmovs -f" ],
|
||||
[ "TCFB1permop", "fips_desmovs -f" ],
|
||||
[ "TCFB1subtab", "fips_desmovs -f" ],
|
||||
[ "TCFB1varkey", "fips_desmovs -f" ],
|
||||
[ "TCFB1vartext", "fips_desmovs -f" ],
|
||||
|
||||
);
|
||||
|
||||
# Verification special cases.
|
||||
# In most cases the output of a test is deterministic and
|
||||
# it can be compared to a known good result. A few involve
|
||||
# the genration and use of random keys and the output will
|
||||
# be different each time. In thoses cases we perform special tests
|
||||
# to simply check their consistency. For example signature generation
|
||||
# output will be run through signature verification to see if all outputs
|
||||
# show as valid.
|
||||
#
|
||||
|
||||
my %verify_special = (
|
||||
"PQGGen" => "fips_dssvs pqgver",
|
||||
"KeyPair" => "fips_dssvs keyver",
|
||||
"SigGen" => "fips_dssvs sigver",
|
||||
"SigGen15" => "fips_rsavtest",
|
||||
"SigGenRSA" => "fips_rsavtest -x931",
|
||||
"SigGenPSS(0)" => "fips_rsavtest -saltlen 0",
|
||||
"SigGenPSS(62)" => "fips_rsavtest -saltlen 62",
|
||||
);
|
||||
|
||||
my $win32 = $^O =~ m/mswin/i;
|
||||
my $onedir = 0;
|
||||
my $filter = "";
|
||||
my $tvdir;
|
||||
my $tprefix;
|
||||
my $shwrap_prefix;
|
||||
my $debug = 0;
|
||||
my $quiet = 0;
|
||||
my $notest = 0;
|
||||
my $verify = 1;
|
||||
my $rspdir = "rsp";
|
||||
my $ignore_missing = 0;
|
||||
my $ignore_bogus = 0;
|
||||
my $bufout = '';
|
||||
my $list_tests = 0;
|
||||
|
||||
my %fips_enabled = (
|
||||
dsa => 1,
|
||||
"dsa-pqgver" => 0,
|
||||
rsa => 1,
|
||||
"rsa-pss0" => 0,
|
||||
"rsa-pss62" => 1,
|
||||
sha => 1,
|
||||
hmac => 1,
|
||||
"rand-aes" => 1,
|
||||
"rand-des2" => 0,
|
||||
aes => 1,
|
||||
"aes-cfb1" => 0,
|
||||
des3 => 1,
|
||||
"des3-cfb1" => 0
|
||||
);
|
||||
|
||||
foreach (@ARGV) {
|
||||
if ( $_ eq "--win32" ) {
|
||||
$win32 = 1;
|
||||
}
|
||||
elsif ( $_ eq "--onedir" ) {
|
||||
$onedir = 1;
|
||||
}
|
||||
elsif ( $_ eq "--debug" ) {
|
||||
$debug = 1;
|
||||
}
|
||||
elsif ( $_ eq "--ignore-missing" ) {
|
||||
$ignore_missing = 1;
|
||||
}
|
||||
elsif ( $_ eq "--ignore-bogus" ) {
|
||||
$ignore_bogus = 1;
|
||||
}
|
||||
elsif ( $_ eq "--generate" ) {
|
||||
$verify = 0;
|
||||
}
|
||||
elsif ( $_ eq "--notest" ) {
|
||||
$notest = 1;
|
||||
}
|
||||
elsif ( $_ eq "--quiet" ) {
|
||||
$quiet = 1;
|
||||
}
|
||||
elsif (/--dir=(.*)$/) {
|
||||
$tvdir = $1;
|
||||
}
|
||||
elsif (/--rspdir=(.*)$/) {
|
||||
$rspdir = $1;
|
||||
}
|
||||
elsif (/--tprefix=(.*)$/) {
|
||||
$tprefix = $1;
|
||||
}
|
||||
elsif (/--shwrap_prefix=(.*)$/) {
|
||||
$shwrap_prefix = $1;
|
||||
}
|
||||
elsif (/^--(enable|disable)-(.*)$/) {
|
||||
if ( !exists $fips_enabled{$2} ) {
|
||||
print STDERR "Unknown test $2\n";
|
||||
}
|
||||
if ( $1 eq "enable" ) {
|
||||
$fips_enabled{$2} = 1;
|
||||
}
|
||||
else {
|
||||
$fips_enabled{$2} = 0;
|
||||
}
|
||||
}
|
||||
elsif (/--filter=(.*)$/) {
|
||||
$filter = $1;
|
||||
}
|
||||
elsif (/^--list-tests$/) {
|
||||
$list_tests = 1;
|
||||
}
|
||||
else {
|
||||
Help();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
my @fips_test_list;
|
||||
|
||||
push @fips_test_list, @fips_dsa_test_list if $fips_enabled{"dsa"};
|
||||
push @fips_test_list, @fips_dsa_pqgver_test_list if $fips_enabled{"dsa-pqgver"};
|
||||
push @fips_test_list, @fips_rsa_test_list if $fips_enabled{"rsa"};
|
||||
push @fips_test_list, @fips_rsa_pss0_test_list if $fips_enabled{"rsa-pss0"};
|
||||
push @fips_test_list, @fips_rsa_pss62_test_list if $fips_enabled{"rsa-pss62"};
|
||||
push @fips_test_list, @fips_sha_test_list if $fips_enabled{"sha"};
|
||||
push @fips_test_list, @fips_hmac_test_list if $fips_enabled{"hmac"};
|
||||
push @fips_test_list, @fips_rand_aes_test_list if $fips_enabled{"rand-aes"};
|
||||
push @fips_test_list, @fips_rand_des2_test_list if $fips_enabled{"rand-des2"};
|
||||
push @fips_test_list, @fips_aes_test_list if $fips_enabled{"aes"};
|
||||
push @fips_test_list, @fips_aes_cfb1_test_list if $fips_enabled{"aes-cfb1"};
|
||||
push @fips_test_list, @fips_des3_test_list if $fips_enabled{"des3"};
|
||||
push @fips_test_list, @fips_des3_cfb1_test_list if $fips_enabled{"des3-cfb1"};
|
||||
|
||||
if ($list_tests) {
|
||||
my ( $test, $en );
|
||||
print "=====TEST LIST=====\n";
|
||||
foreach $test ( sort keys %fips_enabled ) {
|
||||
$en = $fips_enabled{$test};
|
||||
$test =~ tr/[a-z]/[A-Z]/;
|
||||
printf "%-10s %s\n", $test, $en ? "enabled" : "disabled";
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
foreach (@fips_test_list) {
|
||||
next unless ref($_);
|
||||
my $nm = $_->[0];
|
||||
$_->[2] = "";
|
||||
$_->[3] = "";
|
||||
print STDERR "Duplicate test $nm\n" if exists $fips_tests{$nm};
|
||||
$fips_tests{$nm} = $_;
|
||||
}
|
||||
|
||||
$tvdir = "." unless defined $tvdir;
|
||||
|
||||
if ($win32) {
|
||||
if ( !defined $tprefix ) {
|
||||
if ($onedir) {
|
||||
$tprefix = ".\\";
|
||||
}
|
||||
else {
|
||||
$tprefix = "..\\out32dll\\";
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ($onedir) {
|
||||
$tprefix = "./" unless defined $tprefix;
|
||||
$shwrap_prefix = "./" unless defined $shwrap_prefix;
|
||||
}
|
||||
else {
|
||||
$tprefix = "../test/" unless defined $tprefix;
|
||||
$shwrap_prefix = "../util/" unless defined $shwrap_prefix;
|
||||
}
|
||||
}
|
||||
|
||||
sanity_check_exe( $win32, $tprefix, $shwrap_prefix );
|
||||
|
||||
my $cmd_prefix = $win32 ? "" : "${shwrap_prefix}shlib_wrap.sh ";
|
||||
|
||||
find_files( $filter, $tvdir );
|
||||
|
||||
sanity_check_files();
|
||||
|
||||
my ( $runerr, $cmperr, $cmpok, $scheckrunerr, $scheckerr, $scheckok, $skipcnt )
|
||||
= ( 0, 0, 0, 0, 0, 0, 0 );
|
||||
|
||||
exit(0) if $notest;
|
||||
|
||||
run_tests( $verify, $win32, $tprefix, $filter, $tvdir );
|
||||
|
||||
if ($verify) {
|
||||
print "ALGORITHM TEST VERIFY SUMMARY REPORT:\n";
|
||||
print "Tests skipped due to missing files: $skipcnt\n";
|
||||
print "Algorithm test program execution failures: $runerr\n";
|
||||
print "Test comparisons successful: $cmpok\n";
|
||||
print "Test comparisons failed: $cmperr\n";
|
||||
print "Test sanity checks successful: $scheckok\n";
|
||||
print "Test sanity checks failed: $scheckerr\n";
|
||||
print "Sanity check program execution failures: $scheckrunerr\n";
|
||||
|
||||
if ( $runerr || $cmperr || $scheckrunerr || $scheckerr ) {
|
||||
print "***TEST FAILURE***\n";
|
||||
}
|
||||
else {
|
||||
print "***ALL TESTS SUCCESSFUL***\n";
|
||||
}
|
||||
}
|
||||
else {
|
||||
print "ALGORITHM TEST SUMMARY REPORT:\n";
|
||||
print "Tests skipped due to missing files: $skipcnt\n";
|
||||
print "Algorithm test program execution failures: $runerr\n";
|
||||
|
||||
if ($runerr) {
|
||||
print "***TEST FAILURE***\n";
|
||||
}
|
||||
else {
|
||||
print "***ALL TESTS SUCCESSFUL***\n";
|
||||
}
|
||||
}
|
||||
|
||||
#--------------------------------
|
||||
sub Help {
|
||||
( my $cmd ) = ( $0 =~ m#([^/]+)$# );
|
||||
print <<EOF;
|
||||
$cmd: generate run CMVP algorithm tests
|
||||
--debug Enable debug output
|
||||
--dir=<dirname> Optional root for *.req file search
|
||||
--filter=<regexp>
|
||||
--onedir <dirname> Assume all components in current directory
|
||||
--rspdir=<dirname> Name of subdirectories containing *.rsp files, default "rsp"
|
||||
--shwrap_prefix=<prefix>
|
||||
--tprefix=<prefix>
|
||||
--ignore-bogus Ignore duplicate or bogus files
|
||||
--ignore-missing Ignore missing test files
|
||||
--quiet Shhh....
|
||||
--generate Generate algorithm test output
|
||||
--win32 Win32 environment
|
||||
--enable-<alg> Enable algorithm set <alg>.
|
||||
--disable-<alg> Disable algorithm set <alg>.
|
||||
Where <alg> can be one of:
|
||||
EOF
|
||||
|
||||
while (my ($key, $value) = each %fips_enabled)
|
||||
{
|
||||
printf "\t\t%-20s(%s by default)\n", $key ,
|
||||
$value ? "enabled" : "disabled";
|
||||
}
|
||||
}
|
||||
|
||||
# Sanity check to see if all necessary executables exist
|
||||
|
||||
sub sanity_check_exe {
|
||||
my ( $win32, $tprefix, $shwrap_prefix ) = @_;
|
||||
my %exe_list;
|
||||
my $bad = 0;
|
||||
$exe_list{ $shwrap_prefix . "shlib_wrap.sh" } = 1 unless $win32;
|
||||
foreach (@fips_test_list) {
|
||||
next unless ref($_);
|
||||
my $cmd = $_->[1];
|
||||
$cmd =~ s/ .*$//;
|
||||
$cmd = $tprefix . $cmd;
|
||||
$cmd .= ".exe" if $win32;
|
||||
$exe_list{$cmd} = 1;
|
||||
}
|
||||
|
||||
foreach ( sort keys %exe_list ) {
|
||||
if ( !-f $_ ) {
|
||||
print STDERR "ERROR: can't find executable $_\n";
|
||||
$bad = 1;
|
||||
}
|
||||
}
|
||||
if ($bad) {
|
||||
print STDERR "FATAL ERROR: executables missing\n";
|
||||
exit(1);
|
||||
}
|
||||
elsif ($debug) {
|
||||
print STDERR "Executable sanity check passed OK\n";
|
||||
}
|
||||
}
|
||||
|
||||
# Search for all request and response files
|
||||
|
||||
sub find_files {
|
||||
my ( $filter, $dir ) = @_;
|
||||
my ( $dirh, $testname );
|
||||
opendir( $dirh, $dir );
|
||||
while ( $_ = readdir($dirh) ) {
|
||||
next if ( $_ eq "." || $_ eq ".." );
|
||||
$_ = "$dir/$_";
|
||||
if ( -f "$_" ) {
|
||||
if (/\/([^\/]*)\.rsp$/) {
|
||||
$testname = fix_pss( $1, $_ );
|
||||
if ( exists $fips_tests{$testname} ) {
|
||||
if ( $fips_tests{$testname}->[3] eq "" ) {
|
||||
$fips_tests{$testname}->[3] = $_;
|
||||
}
|
||||
else {
|
||||
print STDERR
|
||||
"WARNING: duplicate response file $_ for test $testname\n";
|
||||
$nbogus++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
print STDERR "WARNING: bogus file $_\n";
|
||||
$nbogus++;
|
||||
}
|
||||
}
|
||||
next unless /$filter.*\.req$/i;
|
||||
if (/\/([^\/]*)\.req$/) {
|
||||
$testname = fix_pss( $1, $_ );
|
||||
if ( exists $fips_tests{$testname} ) {
|
||||
if ( $fips_tests{$testname}->[2] eq "" ) {
|
||||
$fips_tests{$testname}->[2] = $_;
|
||||
}
|
||||
else {
|
||||
print STDERR
|
||||
"WARNING: duplicate request file $_ for test $testname\n";
|
||||
$nbogus++;
|
||||
}
|
||||
|
||||
}
|
||||
elsif ( !/SHAmix\.req$/ ) {
|
||||
print STDERR "WARNING: unrecognized filename $_\n";
|
||||
$nbogus++;
|
||||
}
|
||||
}
|
||||
}
|
||||
elsif ( -d "$_" ) {
|
||||
find_files( $filter, $_ );
|
||||
}
|
||||
}
|
||||
closedir($dirh);
|
||||
}
|
||||
|
||||
sub fix_pss {
|
||||
my ( $test, $path ) = @_;
|
||||
my $sl = "";
|
||||
local $_;
|
||||
if ( $test =~ /PSS/ ) {
|
||||
open( IN, $path ) || die "Can't Open File $path";
|
||||
while (<IN>) {
|
||||
if (/^\s*#\s*salt\s+len:\s+(\d+)\s*$/i) {
|
||||
$sl = $1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
close IN;
|
||||
if ( $sl eq "" ) {
|
||||
print STDERR "WARNING: No Salt length detected for file $path\n";
|
||||
}
|
||||
else {
|
||||
return $test . "($sl)";
|
||||
}
|
||||
}
|
||||
return $test;
|
||||
}
|
||||
|
||||
sub sanity_check_files {
|
||||
my $bad = 0;
|
||||
foreach (@fips_test_list) {
|
||||
next unless ref($_);
|
||||
my ( $tst, $cmd, $req, $resp ) = @$_;
|
||||
|
||||
#print STDERR "FILES $tst, $cmd, $req, $resp\n";
|
||||
if ( $req eq "" ) {
|
||||
print STDERR "WARNING: missing request file for $tst\n";
|
||||
$bad = 1;
|
||||
next;
|
||||
}
|
||||
if ( $verify && $resp eq "" ) {
|
||||
print STDERR "WARNING: no response file for test $tst\n";
|
||||
$bad = 1;
|
||||
}
|
||||
elsif ( !$verify && $resp ne "" ) {
|
||||
print STDERR "WARNING: response file $resp will be overwritten\n";
|
||||
}
|
||||
}
|
||||
if ($bad) {
|
||||
print STDERR "ERROR: test vector file set not complete\n";
|
||||
exit(1) unless $ignore_missing;
|
||||
}
|
||||
if ($nbogus) {
|
||||
print STDERR
|
||||
"ERROR: $nbogus bogus or duplicate request and response files\n";
|
||||
exit(1) unless $ignore_bogus;
|
||||
}
|
||||
if ( $debug && !$nbogus && !$bad ) {
|
||||
print STDERR "test vector file set complete\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub run_tests {
|
||||
my ( $verify, $win32, $tprefix, $filter, $tvdir ) = @_;
|
||||
my ( $tname, $tref );
|
||||
my $bad = 0;
|
||||
foreach (@fips_test_list) {
|
||||
if ( !ref($_) ) {
|
||||
print "Running $_ tests\n" unless $quiet;
|
||||
next;
|
||||
}
|
||||
my ( $tname, $tcmd, $req, $rsp ) = @$_;
|
||||
my $out = $rsp;
|
||||
if ($verify) {
|
||||
$out =~ s/\.rsp$/.tst/;
|
||||
}
|
||||
if ( $req eq "" ) {
|
||||
print STDERR
|
||||
"WARNING: Request file for $tname missing: test skipped\n";
|
||||
$skipcnt++;
|
||||
next;
|
||||
}
|
||||
if ( $verify && $rsp eq "" ) {
|
||||
print STDERR
|
||||
"WARNING: Response file for $tname missing: test skipped\n";
|
||||
$skipcnt++;
|
||||
next;
|
||||
}
|
||||
elsif ( !$verify ) {
|
||||
if ( $rsp ne "" ) {
|
||||
print STDERR "WARNING: Response file for $tname deleted\n";
|
||||
unlink $rsp;
|
||||
}
|
||||
$out = $req;
|
||||
$out =~ s|/req/(\S+)\.req|/$rspdir/$1.rsp|;
|
||||
my $outdir = $out;
|
||||
$outdir =~ s|/[^/]*$||;
|
||||
if ( !-d $outdir ) {
|
||||
print STDERR "DEBUG: Creating directory $outdir\n" if $debug;
|
||||
mkdir($outdir) || die "Can't create directory $outdir";
|
||||
}
|
||||
}
|
||||
my $cmd = "$cmd_prefix$tprefix$tcmd ";
|
||||
if ( $tcmd =~ /-f$/ ) {
|
||||
$cmd .= "\"$req\" \"$out\"";
|
||||
}
|
||||
else {
|
||||
$cmd .= "<\"$req\" >\"$out\"";
|
||||
}
|
||||
print STDERR "DEBUG: running test $tname\n" if ( $debug && !$verify );
|
||||
system($cmd);
|
||||
if ( $? != 0 ) {
|
||||
print STDERR
|
||||
"WARNING: error executing test $tname for command: $cmd\n";
|
||||
$runerr++;
|
||||
next;
|
||||
}
|
||||
if ($verify) {
|
||||
if ( exists $verify_special{$tname} ) {
|
||||
my $vout = $rsp;
|
||||
$vout =~ s/\.rsp$/.ver/;
|
||||
$tcmd = $verify_special{$tname};
|
||||
$cmd = "$cmd_prefix$tprefix$tcmd ";
|
||||
$cmd .= "<\"$out\" >\"$vout\"";
|
||||
system($cmd);
|
||||
if ( $? != 0 ) {
|
||||
print STDERR
|
||||
"WARNING: error executing verify test $tname $cmd\n";
|
||||
$scheckrunerr++;
|
||||
next;
|
||||
}
|
||||
my ( $fcount, $pcount ) = ( 0, 0 );
|
||||
open VER, "$vout";
|
||||
while (<VER>) {
|
||||
if (/^Result\s*=\s*(\S*)\s*$/i)
|
||||
|
||||
{
|
||||
if ( $1 eq "F" ) {
|
||||
$fcount++;
|
||||
}
|
||||
else {
|
||||
$pcount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
close VER;
|
||||
|
||||
unlink $vout;
|
||||
if ( $fcount || $debug ) {
|
||||
print STDERR "DEBUG: $tname, Pass=$pcount, Fail=$fcount\n";
|
||||
}
|
||||
if ( $fcount || !$pcount ) {
|
||||
$scheckerr++;
|
||||
}
|
||||
else {
|
||||
$scheckok++;
|
||||
}
|
||||
|
||||
}
|
||||
elsif ( !cmp_file( $tname, $rsp, $out ) ) {
|
||||
$cmperr++;
|
||||
}
|
||||
else {
|
||||
$cmpok++;
|
||||
}
|
||||
unlink $out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub cmp_file {
|
||||
my ( $tname, $rsp, $tst ) = @_;
|
||||
my ( $rspf, $tstf );
|
||||
my ( $rspline, $tstline );
|
||||
if ( !open( $rspf, $rsp ) ) {
|
||||
print STDERR "ERROR: can't open request file $rsp\n";
|
||||
return 0;
|
||||
}
|
||||
if ( !open( $tstf, $tst ) ) {
|
||||
print STDERR "ERROR: can't open output file $tst\n";
|
||||
return 0;
|
||||
}
|
||||
for ( ; ; ) {
|
||||
$rspline = next_line($rspf);
|
||||
$tstline = next_line($tstf);
|
||||
if ( !defined($rspline) && !defined($tstline) ) {
|
||||
print STDERR "DEBUG: $tname file comparison OK\n" if $debug;
|
||||
return 1;
|
||||
}
|
||||
if ( !defined($rspline) ) {
|
||||
print STDERR "ERROR: $tname EOF on $rsp\n";
|
||||
return 0;
|
||||
}
|
||||
if ( !defined($tstline) ) {
|
||||
print STDERR "ERROR: $tname EOF on $tst\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
# Workaround for bug in RAND des2 test output */
|
||||
if ( $tstline =~ /^Key2 =/ && $rspline =~ /^Key1 =/ ) {
|
||||
$rspline =~ s/^Key1/Key2/;
|
||||
}
|
||||
|
||||
if ( $tstline ne $rspline ) {
|
||||
print STDERR "ERROR: $tname mismatch:\n";
|
||||
print STDERR "\t \"$tstline\" != \"$rspline\"\n";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub next_line {
|
||||
my ($in) = @_;
|
||||
|
||||
while (<$in>) {
|
||||
chomp;
|
||||
|
||||
# Delete comments
|
||||
s/#.*$//;
|
||||
|
||||
# Ignore blank lines
|
||||
next if (/^\s*$/);
|
||||
|
||||
# Translate multiple space into one
|
||||
s/\s+/ /g;
|
||||
# Delete trailing whitespace
|
||||
s/\s+$//;
|
||||
return $_;
|
||||
}
|
||||
return undef;
|
||||
}
|
178
fips/fipsld
Executable file
178
fips/fipsld
Executable file
@ -0,0 +1,178 @@
|
||||
#!/bin/sh -e
|
||||
#
|
||||
# Copyright (c) 2005-2007 The OpenSSL Project.
|
||||
#
|
||||
# Depending on output file name, the script either embeds fingerprint
|
||||
# into libcrypto.so or static application. "Static" refers to static
|
||||
# libcrypto.a, not [necessarily] application per se.
|
||||
#
|
||||
# Even though this script is called fipsld, it expects C compiler
|
||||
# command line syntax and $FIPSLD_CC or $CC environment variable set
|
||||
# and can even be used to compile source files.
|
||||
|
||||
#set -x
|
||||
|
||||
CC=${FIPSLD_CC:-${CC}}
|
||||
[ -n "${CC}" ] || { echo '$CC is not defined'; exit 1; }
|
||||
|
||||
# Initially -c wasn't intended to be interpreted here, but it might
|
||||
# make life easier for those who want to build FIPS-ified applications
|
||||
# with minimal [if any] modifications to their Makefiles...
|
||||
( while [ "x$1" != "x" -a "x$1" != "x-c" -a "x$1" != "x-E" ]; do shift; done;
|
||||
[ $# -ge 1 ]
|
||||
) && exec ${CC} "$@"
|
||||
|
||||
TARGET=`(while [ "x$1" != "x" -a "x$1" != "x-o" ]; do shift; done; echo $2)`
|
||||
|
||||
# If using an auto-tooled (autoconf/automake/libtool) project,
|
||||
# configure will fail when testing the compiler or even performing
|
||||
# simple checks. Pass-through to compiler directly if application is
|
||||
# is not being linked with libcrypto, allowing auto-tooled applications
|
||||
# to utilize fipsld (e.g. CC=/usr/local/ssl/bin/fipsld FIPSLD_CC=gcc
|
||||
# ./configure && make). But keep in mind[!] that if certified code
|
||||
# resides in a shared library, then fipsld *may not* be used and
|
||||
# end-developer should not modify application configuration and build
|
||||
# procedures. This is because in-core fingerprint and associated
|
||||
# procedures are already embedded into and executed in shared library
|
||||
# context.
|
||||
case `basename "${TARGET}"` in
|
||||
libcrypto*|libfips*|*.dll) ;;
|
||||
*) case "$*" in
|
||||
*libcrypto.a*|*-lcrypto*|*fipscanister.o*) ;;
|
||||
*) exec ${CC} "$@" ;;
|
||||
esac
|
||||
esac
|
||||
|
||||
[ -n "${TARGET}" ] || { echo 'no -o specified'; exit 1; }
|
||||
|
||||
# Turn on debugging output?
|
||||
( while [ "x$1" != "x" -a "x$1" != "x-DDEBUG_FINGERPRINT_PREMAIN" ]; do shift; done;
|
||||
[ $# -ge 1 ]
|
||||
) && set -x
|
||||
|
||||
THERE="`echo $0 | sed -e 's|[^/]*$||'`"..
|
||||
|
||||
# fipscanister.o can appear in command line
|
||||
CANISTER_O=`(while [ "x$1" != "x" ]; do case "$1" in *fipscanister.o) echo $1; exit;; esac; shift; done)`
|
||||
if [ -z "${CANISTER_O}" ]; then
|
||||
# If set, FIPSLIBDIR is location of installed validated FIPS module
|
||||
if [ -n "${FIPSLIBDIR}" ]; then
|
||||
CANISTER_O="${FIPSLIBDIR}/fipscanister.o"
|
||||
elif [ -f "${THERE}/fips/fipscanister.o" ]; then
|
||||
CANISTER_O="${THERE}/fips/fipscanister.o"
|
||||
elif [ -f "${THERE}/lib/fipscanister.o" ]; then
|
||||
CANISTER_O="${THERE}/lib/fipscanister.o"
|
||||
fi
|
||||
CANISTER_O_CMD="${CANISTER_O}"
|
||||
fi
|
||||
[ -f ${CANISTER_O} ] || { echo "unable to find ${CANISTER_O}"; exit 1; }
|
||||
|
||||
PREMAIN_C=`dirname "${CANISTER_O}"`/fips_premain.c
|
||||
|
||||
HMAC_KEY="etaonrishdlcupfm"
|
||||
|
||||
case "`(uname -s) 2>/dev/null`" in
|
||||
OSF1|IRIX*) _WL_PREMAIN="-Wl,-init,FINGERPRINT_premain" ;;
|
||||
HP-UX) _WL_PREMAIN="-Wl,+init,FINGERPRINT_premain" ;;
|
||||
AIX) _WL_PREMAIN="-Wl,-binitfini:FINGERPRINT_premain,-bnoobjreorder";;
|
||||
Darwin) ( while [ "x$1" != "x" -a "x$1" != "x-dynamiclib" ]; do shift; done;
|
||||
[ $# -ge 1 ]
|
||||
) && _WL_PREMAIN="-Wl,-init,_FINGERPRINT_premain" ;;
|
||||
esac
|
||||
|
||||
case "${TARGET}" in
|
||||
[!/]*) TARGET=./${TARGET} ;;
|
||||
esac
|
||||
|
||||
case `basename "${TARGET}"` in
|
||||
lib*|*.dll) # must be linking a shared lib...
|
||||
# Shared lib creation can be taking place in the source
|
||||
# directory only, but fipscanister.o can reside elsewhere...
|
||||
FINGERTYPE="${THERE}/fips/fips_standalone_sha1"
|
||||
|
||||
# verify fipspremain.c against its detached signature...
|
||||
${FINGERTYPE} "${PREMAIN_C}" | sed "s/(.*\//(/" | \
|
||||
diff -w "${PREMAIN_C}.sha1" - || \
|
||||
{ echo "${PREMAIN_C} fingerprint mismatch"; exit 1; }
|
||||
# verify fipscanister.o against its detached signature...
|
||||
${FINGERTYPE} "${CANISTER_O}" | sed "s/(.*\//(/" | \
|
||||
diff -w "${CANISTER_O}.sha1" - || \
|
||||
{ echo "${CANISTER_O} fingerprint mismatch"; exit 1; }
|
||||
|
||||
# Temporarily remove fipscanister.o from libcrypto.a!
|
||||
# We are required to use the standalone copy...
|
||||
if [ -f "${THERE}/libcrypto.a" ]; then
|
||||
if ar d "${THERE}/libcrypto.a" fipscanister.o; then
|
||||
(ranlib "${THERE}/libcrypto.a") 2>/dev/null || :
|
||||
trap 'ar r "${THERE}/libcrypto.a" "${CANISTER_O}";
|
||||
(ranlib "${THERE}/libcrypto.a") 2>/dev/null || :;
|
||||
sleep 1;
|
||||
touch -c "${TARGET}"' 0
|
||||
fi
|
||||
fi
|
||||
|
||||
/bin/rm -f "${TARGET}"
|
||||
${CC} ${CANISTER_O_CMD:+"${CANISTER_O_CMD}"} \
|
||||
"${PREMAIN_C}" \
|
||||
${_WL_PREMAIN} "$@"
|
||||
|
||||
# generate signature...
|
||||
if [ -z "${FIPS_SIG}" ]; then
|
||||
SIG=`"${THERE}/fips/fips_premain_dso" "${TARGET}"`
|
||||
else
|
||||
SIG=`"${FIPS_SIG}" -dso "${TARGET}"`
|
||||
fi
|
||||
/bin/rm -f "${TARGET}"
|
||||
if [ -z "${SIG}" ]; then
|
||||
echo "unable to collect signature"; exit 1
|
||||
fi
|
||||
|
||||
# recompile with signature...
|
||||
${CC} ${CANISTER_O_CMD:+"${CANISTER_O_CMD}"} \
|
||||
-DHMAC_SHA1_SIG=\"${SIG}\" "${PREMAIN_C}" \
|
||||
${_WL_PREMAIN} "$@"
|
||||
;;
|
||||
|
||||
*) # must be linking statically...
|
||||
# Static linking can be taking place either in the source
|
||||
# directory or off the installed binary target destination.
|
||||
if [ -x "${THERE}/fips/fips_standalone_sha1" ]; then
|
||||
FINGERTYPE="${THERE}/fips/fips_standalone_sha1"
|
||||
else # Installed tree is expected to contain
|
||||
# lib/fipscanister.o, lib/fipscanister.o.sha1 and
|
||||
# lib/fips_premain.c [not to mention bin/openssl].
|
||||
FINGERTYPE="${THERE}/bin/openssl sha1 -hmac ${HMAC_KEY}"
|
||||
fi
|
||||
|
||||
# verify fipscanister.o against its detached signature...
|
||||
${FINGERTYPE} "${CANISTER_O}" | sed "s/(.*\//(/" | \
|
||||
diff -w "${CANISTER_O}.sha1" - || \
|
||||
{ echo "${CANISTER_O} fingerprint mismatch"; exit 1; }
|
||||
|
||||
# verify fips_premain.c against its detached signature...
|
||||
${FINGERTYPE} "${PREMAIN_C}" | sed "s/(.*\//(/" | \
|
||||
diff -w "${PREMAIN_C}.sha1" - || \
|
||||
{ echo "${PREMAIN_C} fingerprint mismatch"; exit 1; }
|
||||
|
||||
/bin/rm -f "${TARGET}"
|
||||
${CC} ${CANISTER_O_CMD:+"${CANISTER_O_CMD}"} \
|
||||
"${PREMAIN_C}" \
|
||||
${_WL_PREMAIN} "$@"
|
||||
|
||||
# generate signature...
|
||||
if [ -z "${FIPS_SIG}" ]; then
|
||||
SIG=`"${TARGET}"`
|
||||
else
|
||||
SIG=`"${FIPS_SIG}" -exe "${TARGET}"`
|
||||
fi
|
||||
/bin/rm -f "${TARGET}"
|
||||
if [ -z "${SIG}" ]; then
|
||||
echo "unable to collect signature"; exit 1
|
||||
fi
|
||||
|
||||
# recompile with signature...
|
||||
${CC} ${CANISTER_O_CMD:+"${CANISTER_O_CMD}"} \
|
||||
-DHMAC_SHA1_SIG=\"${SIG}\" "${PREMAIN_C}" \
|
||||
${_WL_PREMAIN} "$@"
|
||||
;;
|
||||
esac
|
4
fips/hmac/.cvsignore
Normal file
4
fips/hmac/.cvsignore
Normal file
@ -0,0 +1,4 @@
|
||||
lib
|
||||
Makefile.save
|
||||
*.flc
|
||||
semantic.cache
|
123
fips/hmac/Makefile
Normal file
123
fips/hmac/Makefile
Normal file
@ -0,0 +1,123 @@
|
||||
#
|
||||
# OpenSSL/fips/hmac/Makefile
|
||||
#
|
||||
|
||||
DIR= hmac
|
||||
TOP= ../..
|
||||
CC= cc
|
||||
INCLUDES=
|
||||
CFLAG=-g
|
||||
INSTALL_PREFIX=
|
||||
OPENSSLDIR= /usr/local/ssl
|
||||
INSTALLTOP=/usr/local/ssl
|
||||
MAKEDEPPROG= makedepend
|
||||
MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
|
||||
MAKEFILE= Makefile
|
||||
AR= ar r
|
||||
|
||||
CFLAGS= $(INCLUDES) $(CFLAG)
|
||||
|
||||
GENERAL=Makefile
|
||||
TEST=fips_hmactest.c
|
||||
APPS=
|
||||
|
||||
LIB=$(TOP)/libcrypto.a
|
||||
LIBSRC= fips_hmac_selftest.c
|
||||
LIBOBJ= fips_hmac_selftest.o
|
||||
|
||||
SRC= $(LIBSRC)
|
||||
|
||||
EXHEADER=
|
||||
HEADER= $(EXHEADER)
|
||||
|
||||
ALL= $(GENERAL) $(SRC) $(HEADER)
|
||||
|
||||
top:
|
||||
(cd $(TOP); $(MAKE) DIRS=fips FDIRS=$(DIR) sub_all)
|
||||
|
||||
all: lib
|
||||
|
||||
lib: $(LIBOBJ)
|
||||
@echo $(LIBOBJ) > lib
|
||||
|
||||
files:
|
||||
$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
|
||||
|
||||
links:
|
||||
@$(PERL) $(TOP)/util/mklink.pl $(TOP)/include/openssl $(EXHEADER)
|
||||
@$(PERL) $(TOP)/util/mklink.pl $(TOP)/test $(TEST)
|
||||
@$(PERL) $(TOP)/util/mklink.pl $(TOP)/apps $(APPS)
|
||||
|
||||
install:
|
||||
@headerlist="$(EXHEADER)"; for i in $$headerlist; \
|
||||
do \
|
||||
(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
|
||||
chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
|
||||
done
|
||||
|
||||
tags:
|
||||
ctags $(SRC)
|
||||
|
||||
tests:
|
||||
|
||||
Q=../testvectors/hmac/req
|
||||
A=../testvectors/hmac/rsp
|
||||
|
||||
fips_test:
|
||||
-rm -rf $(A)
|
||||
mkdir $(A)
|
||||
if [ -f $(Q)/HMAC.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_hmactest < $(Q)/HMAC.req > $(A)/HMAC.rsp; fi
|
||||
|
||||
lint:
|
||||
lint -DLINT $(INCLUDES) $(SRC)>fluff
|
||||
|
||||
depend:
|
||||
$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(SRC) $(TEST)
|
||||
|
||||
dclean:
|
||||
$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
|
||||
mv -f Makefile.new $(MAKEFILE)
|
||||
|
||||
clean:
|
||||
rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
|
||||
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
||||
|
||||
fips_hmac.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
|
||||
fips_hmac.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
|
||||
fips_hmac.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
|
||||
fips_hmac.o: ../../include/openssl/hmac.h ../../include/openssl/obj_mac.h
|
||||
fips_hmac.o: ../../include/openssl/objects.h
|
||||
fips_hmac.o: ../../include/openssl/opensslconf.h
|
||||
fips_hmac.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
|
||||
fips_hmac.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
|
||||
fips_hmac.o: ../../include/openssl/symhacks.h fips_hmac.c
|
||||
fips_hmac_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
|
||||
fips_hmac_selftest.o: ../../include/openssl/crypto.h
|
||||
fips_hmac_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
|
||||
fips_hmac_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
|
||||
fips_hmac_selftest.o: ../../include/openssl/hmac.h
|
||||
fips_hmac_selftest.o: ../../include/openssl/lhash.h
|
||||
fips_hmac_selftest.o: ../../include/openssl/obj_mac.h
|
||||
fips_hmac_selftest.o: ../../include/openssl/objects.h
|
||||
fips_hmac_selftest.o: ../../include/openssl/opensslconf.h
|
||||
fips_hmac_selftest.o: ../../include/openssl/opensslv.h
|
||||
fips_hmac_selftest.o: ../../include/openssl/ossl_typ.h
|
||||
fips_hmac_selftest.o: ../../include/openssl/safestack.h
|
||||
fips_hmac_selftest.o: ../../include/openssl/stack.h
|
||||
fips_hmac_selftest.o: ../../include/openssl/symhacks.h fips_hmac_selftest.c
|
||||
fips_hmactest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
|
||||
fips_hmactest.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
|
||||
fips_hmactest.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
|
||||
fips_hmactest.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
|
||||
fips_hmactest.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
|
||||
fips_hmactest.o: ../../include/openssl/err.h ../../include/openssl/evp.h
|
||||
fips_hmactest.o: ../../include/openssl/fips.h ../../include/openssl/hmac.h
|
||||
fips_hmactest.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
|
||||
fips_hmactest.o: ../../include/openssl/objects.h
|
||||
fips_hmactest.o: ../../include/openssl/opensslconf.h
|
||||
fips_hmactest.o: ../../include/openssl/opensslv.h
|
||||
fips_hmactest.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
|
||||
fips_hmactest.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
|
||||
fips_hmactest.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
|
||||
fips_hmactest.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
|
||||
fips_hmactest.o: ../../include/openssl/x509v3.h ../fips_utl.h fips_hmactest.c
|
135
fips/hmac/fips_hmac_selftest.c
Normal file
135
fips/hmac/fips_hmac_selftest.c
Normal file
@ -0,0 +1,135 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2005 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/fips.h>
|
||||
#include <openssl/hmac.h>
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
typedef struct {
|
||||
const EVP_MD *(*alg)(void);
|
||||
const char *key, *iv;
|
||||
unsigned char kaval[EVP_MAX_MD_SIZE];
|
||||
} HMAC_KAT;
|
||||
|
||||
static const HMAC_KAT vector[] = {
|
||||
{ EVP_sha1,
|
||||
/* from http://csrc.nist.gov/publications/fips/fips198/fips-198a.pdf */
|
||||
"0123456789:;<=>?@ABC",
|
||||
"Sample #2",
|
||||
{ 0x09,0x22,0xd3,0x40,0x5f,0xaa,0x3d,0x19,
|
||||
0x4f,0x82,0xa4,0x58,0x30,0x73,0x7d,0x5c,
|
||||
0xc6,0xc7,0x5d,0x24 }
|
||||
},
|
||||
{ EVP_sha224,
|
||||
/* just keep extending the above... */
|
||||
"0123456789:;<=>?@ABC",
|
||||
"Sample #2",
|
||||
{ 0xdd,0xef,0x0a,0x40,0xcb,0x7d,0x50,0xfb,
|
||||
0x6e,0xe6,0xce,0xa1,0x20,0xba,0x26,0xaa,
|
||||
0x08,0xf3,0x07,0x75,0x87,0xb8,0xad,0x1b,
|
||||
0x8c,0x8d,0x12,0xc7 }
|
||||
},
|
||||
{ EVP_sha256,
|
||||
"0123456789:;<=>?@ABC",
|
||||
"Sample #2",
|
||||
{ 0xb8,0xf2,0x0d,0xb5,0x41,0xea,0x43,0x09,
|
||||
0xca,0x4e,0xa9,0x38,0x0c,0xd0,0xe8,0x34,
|
||||
0xf7,0x1f,0xbe,0x91,0x74,0xa2,0x61,0x38,
|
||||
0x0d,0xc1,0x7e,0xae,0x6a,0x34,0x51,0xd9 }
|
||||
},
|
||||
{ EVP_sha384,
|
||||
"0123456789:;<=>?@ABC",
|
||||
"Sample #2",
|
||||
{ 0x08,0xbc,0xb0,0xda,0x49,0x1e,0x87,0xad,
|
||||
0x9a,0x1d,0x6a,0xce,0x23,0xc5,0x0b,0xf6,
|
||||
0xb7,0x18,0x06,0xa5,0x77,0xcd,0x49,0x04,
|
||||
0x89,0xf1,0xe6,0x23,0x44,0x51,0x51,0x9f,
|
||||
0x85,0x56,0x80,0x79,0x0c,0xbd,0x4d,0x50,
|
||||
0xa4,0x5f,0x29,0xe3,0x93,0xf0,0xe8,0x7f }
|
||||
},
|
||||
{ EVP_sha512,
|
||||
"0123456789:;<=>?@ABC",
|
||||
"Sample #2",
|
||||
{ 0x80,0x9d,0x44,0x05,0x7c,0x5b,0x95,0x41,
|
||||
0x05,0xbd,0x04,0x13,0x16,0xdb,0x0f,0xac,
|
||||
0x44,0xd5,0xa4,0xd5,0xd0,0x89,0x2b,0xd0,
|
||||
0x4e,0x86,0x64,0x12,0xc0,0x90,0x77,0x68,
|
||||
0xf1,0x87,0xb7,0x7c,0x4f,0xae,0x2c,0x2f,
|
||||
0x21,0xa5,0xb5,0x65,0x9a,0x4f,0x4b,0xa7,
|
||||
0x47,0x02,0xa3,0xde,0x9b,0x51,0xf1,0x45,
|
||||
0xbd,0x4f,0x25,0x27,0x42,0x98,0x99,0x05 }
|
||||
},
|
||||
};
|
||||
|
||||
int FIPS_selftest_hmac()
|
||||
{
|
||||
size_t n;
|
||||
unsigned int outlen;
|
||||
unsigned char out[EVP_MAX_MD_SIZE];
|
||||
const EVP_MD *md;
|
||||
const HMAC_KAT *t;
|
||||
|
||||
for(n=0,t=vector; n<sizeof(vector)/sizeof(vector[0]); n++,t++)
|
||||
{
|
||||
md = (*t->alg)();
|
||||
HMAC(md,t->key,strlen(t->key),
|
||||
(const unsigned char *)t->iv,strlen(t->iv),
|
||||
out,&outlen);
|
||||
|
||||
if(memcmp(out,t->kaval,outlen))
|
||||
{
|
||||
FIPSerr(FIPS_F_FIPS_SELFTEST_HMAC,FIPS_R_SELFTEST_FAILED);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif
|
322
fips/hmac/fips_hmactest.c
Normal file
322
fips/hmac/fips_hmactest.c
Normal file
@ -0,0 +1,322 @@
|
||||
/* fips_hmactest.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2005.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2005 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
#ifndef OPENSSL_FIPS
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
printf("No FIPS HMAC support\n");
|
||||
return(0);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <openssl/fips.h>
|
||||
#include "fips_utl.h"
|
||||
|
||||
static int hmac_test(const EVP_MD *md, FILE *out, FILE *in);
|
||||
static int print_hmac(const EVP_MD *md, FILE *out,
|
||||
unsigned char *Key, int Klen,
|
||||
unsigned char *Msg, int Msglen, int Tlen);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
FILE *in = NULL, *out = NULL;
|
||||
|
||||
int ret = 1;
|
||||
fips_set_error_print();
|
||||
if(!FIPS_mode_set(1))
|
||||
goto end;
|
||||
|
||||
if (argc == 1)
|
||||
in = stdin;
|
||||
else
|
||||
in = fopen(argv[1], "r");
|
||||
|
||||
if (argc < 2)
|
||||
out = stdout;
|
||||
else
|
||||
out = fopen(argv[2], "w");
|
||||
|
||||
if (!in)
|
||||
{
|
||||
fprintf(stderr, "FATAL input initialization error\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!out)
|
||||
{
|
||||
fprintf(stderr, "FATAL output initialization error\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!hmac_test(EVP_sha1(), out, in))
|
||||
{
|
||||
fprintf(stderr, "FATAL hmac file processing error\n");
|
||||
goto end;
|
||||
}
|
||||
else
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
|
||||
if (in && (in != stdin))
|
||||
fclose(in);
|
||||
if (out && (out != stdout))
|
||||
fclose(out);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
#define HMAC_TEST_MAXLINELEN 1024
|
||||
|
||||
int hmac_test(const EVP_MD *md, FILE *out, FILE *in)
|
||||
{
|
||||
char *linebuf, *olinebuf, *p, *q;
|
||||
char *keyword, *value;
|
||||
unsigned char *Key = NULL, *Msg = NULL;
|
||||
int Count, Klen, Tlen;
|
||||
long Keylen, Msglen;
|
||||
int ret = 0;
|
||||
int lnum = 0;
|
||||
|
||||
olinebuf = OPENSSL_malloc(HMAC_TEST_MAXLINELEN);
|
||||
linebuf = OPENSSL_malloc(HMAC_TEST_MAXLINELEN);
|
||||
|
||||
if (!linebuf || !olinebuf)
|
||||
goto error;
|
||||
|
||||
Count = -1;
|
||||
Klen = -1;
|
||||
Tlen = -1;
|
||||
|
||||
while (fgets(olinebuf, HMAC_TEST_MAXLINELEN, in))
|
||||
{
|
||||
lnum++;
|
||||
strcpy(linebuf, olinebuf);
|
||||
keyword = linebuf;
|
||||
/* Skip leading space */
|
||||
while (isspace((unsigned char)*keyword))
|
||||
keyword++;
|
||||
|
||||
/* Look for = sign */
|
||||
p = strchr(linebuf, '=');
|
||||
|
||||
/* If no = or starts with [ (for [L=20] line) just copy */
|
||||
if (!p)
|
||||
{
|
||||
if (fputs(olinebuf, out) < 0)
|
||||
goto error;
|
||||
continue;
|
||||
}
|
||||
|
||||
q = p - 1;
|
||||
|
||||
/* Remove trailing space */
|
||||
while (isspace((unsigned char)*q))
|
||||
*q-- = 0;
|
||||
|
||||
*p = 0;
|
||||
value = p + 1;
|
||||
|
||||
/* Remove leading space from value */
|
||||
while (isspace((unsigned char)*value))
|
||||
value++;
|
||||
|
||||
/* Remove trailing space from value */
|
||||
p = value + strlen(value) - 1;
|
||||
|
||||
while (*p == '\n' || isspace((unsigned char)*p))
|
||||
*p-- = 0;
|
||||
|
||||
if (!strcmp(keyword,"[L") && *p==']')
|
||||
{
|
||||
switch (atoi(value))
|
||||
{
|
||||
case 20: md=EVP_sha1(); break;
|
||||
case 28: md=EVP_sha224(); break;
|
||||
case 32: md=EVP_sha256(); break;
|
||||
case 48: md=EVP_sha384(); break;
|
||||
case 64: md=EVP_sha512(); break;
|
||||
default: goto parse_error;
|
||||
}
|
||||
}
|
||||
else if (!strcmp(keyword, "Count"))
|
||||
{
|
||||
if (Count != -1)
|
||||
goto parse_error;
|
||||
Count = atoi(value);
|
||||
if (Count < 0)
|
||||
goto parse_error;
|
||||
}
|
||||
else if (!strcmp(keyword, "Klen"))
|
||||
{
|
||||
if (Klen != -1)
|
||||
goto parse_error;
|
||||
Klen = atoi(value);
|
||||
if (Klen < 0)
|
||||
goto parse_error;
|
||||
}
|
||||
else if (!strcmp(keyword, "Tlen"))
|
||||
{
|
||||
if (Tlen != -1)
|
||||
goto parse_error;
|
||||
Tlen = atoi(value);
|
||||
if (Tlen < 0)
|
||||
goto parse_error;
|
||||
}
|
||||
else if (!strcmp(keyword, "Msg"))
|
||||
{
|
||||
if (Msg)
|
||||
goto parse_error;
|
||||
Msg = hex2bin_m(value, &Msglen);
|
||||
if (!Msg)
|
||||
goto parse_error;
|
||||
}
|
||||
else if (!strcmp(keyword, "Key"))
|
||||
{
|
||||
if (Key)
|
||||
goto parse_error;
|
||||
Key = hex2bin_m(value, &Keylen);
|
||||
if (!Key)
|
||||
goto parse_error;
|
||||
}
|
||||
else if (!strcmp(keyword, "Mac"))
|
||||
continue;
|
||||
else
|
||||
goto parse_error;
|
||||
|
||||
fputs(olinebuf, out);
|
||||
|
||||
if (Key && Msg && (Tlen > 0) && (Klen > 0))
|
||||
{
|
||||
if (!print_hmac(md, out, Key, Klen, Msg, Msglen, Tlen))
|
||||
goto error;
|
||||
OPENSSL_free(Key);
|
||||
Key = NULL;
|
||||
OPENSSL_free(Msg);
|
||||
Msg = NULL;
|
||||
Klen = -1;
|
||||
Tlen = -1;
|
||||
Count = -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
ret = 1;
|
||||
|
||||
|
||||
error:
|
||||
|
||||
if (olinebuf)
|
||||
OPENSSL_free(olinebuf);
|
||||
if (linebuf)
|
||||
OPENSSL_free(linebuf);
|
||||
if (Key)
|
||||
OPENSSL_free(Key);
|
||||
if (Msg)
|
||||
OPENSSL_free(Msg);
|
||||
|
||||
return ret;
|
||||
|
||||
parse_error:
|
||||
|
||||
fprintf(stderr, "FATAL parse error processing line %d\n", lnum);
|
||||
|
||||
goto error;
|
||||
|
||||
}
|
||||
|
||||
static int print_hmac(const EVP_MD *emd, FILE *out,
|
||||
unsigned char *Key, int Klen,
|
||||
unsigned char *Msg, int Msglen, int Tlen)
|
||||
{
|
||||
int i, mdlen;
|
||||
unsigned char md[EVP_MAX_MD_SIZE];
|
||||
if (!HMAC(emd, Key, Klen, Msg, Msglen, md,
|
||||
(unsigned int *)&mdlen))
|
||||
{
|
||||
fputs("Error calculating HMAC\n", stderr);
|
||||
return 0;
|
||||
}
|
||||
if (Tlen > mdlen)
|
||||
{
|
||||
fputs("Parameter error, Tlen > HMAC length\n", stderr);
|
||||
return 0;
|
||||
}
|
||||
fputs("Mac = ", out);
|
||||
for (i = 0; i < Tlen; i++)
|
||||
fprintf(out, "%02x", md[i]);
|
||||
fputs("\n", out);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
657
fips/mkfipsscr.pl
Normal file
657
fips/mkfipsscr.pl
Normal file
@ -0,0 +1,657 @@
|
||||
#!/usr/local/bin/perl -w
|
||||
# Quick & dirty utility to generate a script for executing the
|
||||
# FIPS 140-2 CMVP algorithm tests based on the pathnames of
|
||||
# input algorithm test files actually present (the unqualified
|
||||
# file names are consistent but the pathnames are not).
|
||||
#
|
||||
|
||||
# List of all the unqualified file names we expect.
|
||||
my %fips_tests = (
|
||||
|
||||
# FIPS test definitions
|
||||
|
||||
# DSA tests
|
||||
|
||||
"PQGGen" => "fips_dssvs pqg",
|
||||
"KeyPair" => "fips_dssvs keypair",
|
||||
"SigGen" => "fips_dssvs siggen",
|
||||
"SigVer" => "fips_dssvs sigver",
|
||||
|
||||
# SHA tests
|
||||
|
||||
"SHA1LongMsg" => "fips_shatest",
|
||||
"SHA1Monte" => "fips_shatest",
|
||||
"SHA1ShortMsg" => "fips_shatest",
|
||||
"SHA224LongMsg" => "fips_shatest",
|
||||
"SHA224Monte" => "fips_shatest",
|
||||
"SHA224ShortMsg" => "fips_shatest",
|
||||
"SHA256LongMsg" => "fips_shatest",
|
||||
"SHA256Monte" => "fips_shatest",
|
||||
"SHA256ShortMsg" => "fips_shatest",
|
||||
"SHA384LongMsg" => "fips_shatest",
|
||||
"SHA384Monte" => "fips_shatest",
|
||||
"SHA384ShortMsg" => "fips_shatest",
|
||||
"SHA512LongMsg" => "fips_shatest",
|
||||
"SHA512Monte" => "fips_shatest",
|
||||
"SHA512ShortMsg" => "fips_shatest",
|
||||
|
||||
# HMAC
|
||||
|
||||
"HMAC" => "fips_hmactest",
|
||||
|
||||
# RAND tests
|
||||
|
||||
"ANSI931_AES128MCT" => "fips_rngvs mct",
|
||||
"ANSI931_AES192MCT" => "fips_rngvs mct",
|
||||
"ANSI931_AES256MCT" => "fips_rngvs mct",
|
||||
"ANSI931_AES128VST" => "fips_rngvs vst",
|
||||
"ANSI931_AES192VST" => "fips_rngvs vst",
|
||||
"ANSI931_AES256VST" => "fips_rngvs vst",
|
||||
|
||||
# RSA tests
|
||||
|
||||
"SigGen15" => "fips_rsastest",
|
||||
"SigVer15" => "fips_rsavtest",
|
||||
"SigGenPSS" => "fips_rsastest -saltlen SALT",
|
||||
"SigVerPSS" => "fips_rsavtest -saltlen SALT",
|
||||
"SigGenRSA" => "fips_rsastest -x931",
|
||||
"SigVerRSA" => "fips_rsavtest -x931",
|
||||
"KeyGenRSA" => "fips_rsagtest",
|
||||
|
||||
# AES tests
|
||||
|
||||
"CBCGFSbox128" => "fips_aesavs -f",
|
||||
"CBCGFSbox192" => "fips_aesavs -f",
|
||||
"CBCGFSbox256" => "fips_aesavs -f",
|
||||
"CBCKeySbox128" => "fips_aesavs -f",
|
||||
"CBCKeySbox192" => "fips_aesavs -f",
|
||||
"CBCKeySbox256" => "fips_aesavs -f",
|
||||
"CBCMCT128" => "fips_aesavs -f",
|
||||
"CBCMCT192" => "fips_aesavs -f",
|
||||
"CBCMCT256" => "fips_aesavs -f",
|
||||
"CBCMMT128" => "fips_aesavs -f",
|
||||
"CBCMMT192" => "fips_aesavs -f",
|
||||
"CBCMMT256" => "fips_aesavs -f",
|
||||
"CBCVarKey128" => "fips_aesavs -f",
|
||||
"CBCVarKey192" => "fips_aesavs -f",
|
||||
"CBCVarKey256" => "fips_aesavs -f",
|
||||
"CBCVarTxt128" => "fips_aesavs -f",
|
||||
"CBCVarTxt192" => "fips_aesavs -f",
|
||||
"CBCVarTxt256" => "fips_aesavs -f",
|
||||
"CFB128GFSbox128" => "fips_aesavs -f",
|
||||
"CFB128GFSbox192" => "fips_aesavs -f",
|
||||
"CFB128GFSbox256" => "fips_aesavs -f",
|
||||
"CFB128KeySbox128" => "fips_aesavs -f",
|
||||
"CFB128KeySbox192" => "fips_aesavs -f",
|
||||
"CFB128KeySbox256" => "fips_aesavs -f",
|
||||
"CFB128MCT128" => "fips_aesavs -f",
|
||||
"CFB128MCT192" => "fips_aesavs -f",
|
||||
"CFB128MCT256" => "fips_aesavs -f",
|
||||
"CFB128MMT128" => "fips_aesavs -f",
|
||||
"CFB128MMT192" => "fips_aesavs -f",
|
||||
"CFB128MMT256" => "fips_aesavs -f",
|
||||
"CFB128VarKey128" => "fips_aesavs -f",
|
||||
"CFB128VarKey192" => "fips_aesavs -f",
|
||||
"CFB128VarKey256" => "fips_aesavs -f",
|
||||
"CFB128VarTxt128" => "fips_aesavs -f",
|
||||
"CFB128VarTxt192" => "fips_aesavs -f",
|
||||
"CFB128VarTxt256" => "fips_aesavs -f",
|
||||
"CFB8GFSbox128" => "fips_aesavs -f",
|
||||
"CFB8GFSbox192" => "fips_aesavs -f",
|
||||
"CFB8GFSbox256" => "fips_aesavs -f",
|
||||
"CFB8KeySbox128" => "fips_aesavs -f",
|
||||
"CFB8KeySbox192" => "fips_aesavs -f",
|
||||
"CFB8KeySbox256" => "fips_aesavs -f",
|
||||
"CFB8MCT128" => "fips_aesavs -f",
|
||||
"CFB8MCT192" => "fips_aesavs -f",
|
||||
"CFB8MCT256" => "fips_aesavs -f",
|
||||
"CFB8MMT128" => "fips_aesavs -f",
|
||||
"CFB8MMT192" => "fips_aesavs -f",
|
||||
"CFB8MMT256" => "fips_aesavs -f",
|
||||
"CFB8VarKey128" => "fips_aesavs -f",
|
||||
"CFB8VarKey192" => "fips_aesavs -f",
|
||||
"CFB8VarKey256" => "fips_aesavs -f",
|
||||
"CFB8VarTxt128" => "fips_aesavs -f",
|
||||
"CFB8VarTxt192" => "fips_aesavs -f",
|
||||
"CFB8VarTxt256" => "fips_aesavs -f",
|
||||
#"CFB1GFSbox128" => "fips_aesavs -f",
|
||||
#"CFB1GFSbox192" => "fips_aesavs -f",
|
||||
#"CFB1GFSbox256" => "fips_aesavs -f",
|
||||
#"CFB1KeySbox128" => "fips_aesavs -f",
|
||||
#"CFB1KeySbox192" => "fips_aesavs -f",
|
||||
#"CFB1KeySbox256" => "fips_aesavs -f",
|
||||
#"CFB1MCT128" => "fips_aesavs -f",
|
||||
#"CFB1MCT192" => "fips_aesavs -f",
|
||||
#"CFB1MCT256" => "fips_aesavs -f",
|
||||
#"CFB1MMT128" => "fips_aesavs -f",
|
||||
#"CFB1MMT192" => "fips_aesavs -f",
|
||||
#"CFB1MMT256" => "fips_aesavs -f",
|
||||
#"CFB1VarKey128" => "fips_aesavs -f",
|
||||
#"CFB1VarKey192" => "fips_aesavs -f",
|
||||
#"CFB1VarKey256" => "fips_aesavs -f",
|
||||
#"CFB1VarTxt128" => "fips_aesavs -f",
|
||||
#"CFB1VarTxt192" => "fips_aesavs -f",
|
||||
#"CFB1VarTxt256" => "fips_aesavs -f",
|
||||
"ECBGFSbox128" => "fips_aesavs -f",
|
||||
"ECBGFSbox192" => "fips_aesavs -f",
|
||||
"ECBGFSbox256" => "fips_aesavs -f",
|
||||
"ECBKeySbox128" => "fips_aesavs -f",
|
||||
"ECBKeySbox192" => "fips_aesavs -f",
|
||||
"ECBKeySbox256" => "fips_aesavs -f",
|
||||
"ECBMCT128" => "fips_aesavs -f",
|
||||
"ECBMCT192" => "fips_aesavs -f",
|
||||
"ECBMCT256" => "fips_aesavs -f",
|
||||
"ECBMMT128" => "fips_aesavs -f",
|
||||
"ECBMMT192" => "fips_aesavs -f",
|
||||
"ECBMMT256" => "fips_aesavs -f",
|
||||
"ECBVarKey128" => "fips_aesavs -f",
|
||||
"ECBVarKey192" => "fips_aesavs -f",
|
||||
"ECBVarKey256" => "fips_aesavs -f",
|
||||
"ECBVarTxt128" => "fips_aesavs -f",
|
||||
"ECBVarTxt192" => "fips_aesavs -f",
|
||||
"ECBVarTxt256" => "fips_aesavs -f",
|
||||
"OFBGFSbox128" => "fips_aesavs -f",
|
||||
"OFBGFSbox192" => "fips_aesavs -f",
|
||||
"OFBGFSbox256" => "fips_aesavs -f",
|
||||
"OFBKeySbox128" => "fips_aesavs -f",
|
||||
"OFBKeySbox192" => "fips_aesavs -f",
|
||||
"OFBKeySbox256" => "fips_aesavs -f",
|
||||
"OFBMCT128" => "fips_aesavs -f",
|
||||
"OFBMCT192" => "fips_aesavs -f",
|
||||
"OFBMCT256" => "fips_aesavs -f",
|
||||
"OFBMMT128" => "fips_aesavs -f",
|
||||
"OFBMMT192" => "fips_aesavs -f",
|
||||
"OFBMMT256" => "fips_aesavs -f",
|
||||
"OFBVarKey128" => "fips_aesavs -f",
|
||||
"OFBVarKey192" => "fips_aesavs -f",
|
||||
"OFBVarKey256" => "fips_aesavs -f",
|
||||
"OFBVarTxt128" => "fips_aesavs -f",
|
||||
"OFBVarTxt192" => "fips_aesavs -f",
|
||||
"OFBVarTxt256" => "fips_aesavs -f",
|
||||
|
||||
# Triple DES tests
|
||||
|
||||
"TCBCinvperm" => "fips_desmovs -f",
|
||||
"TCBCMMT1" => "fips_desmovs -f",
|
||||
"TCBCMMT2" => "fips_desmovs -f",
|
||||
"TCBCMMT3" => "fips_desmovs -f",
|
||||
"TCBCMonte1" => "fips_desmovs -f",
|
||||
"TCBCMonte2" => "fips_desmovs -f",
|
||||
"TCBCMonte3" => "fips_desmovs -f",
|
||||
"TCBCpermop" => "fips_desmovs -f",
|
||||
"TCBCsubtab" => "fips_desmovs -f",
|
||||
"TCBCvarkey" => "fips_desmovs -f",
|
||||
"TCBCvartext" => "fips_desmovs -f",
|
||||
"TCFB64invperm" => "fips_desmovs -f",
|
||||
"TCFB64MMT1" => "fips_desmovs -f",
|
||||
"TCFB64MMT2" => "fips_desmovs -f",
|
||||
"TCFB64MMT3" => "fips_desmovs -f",
|
||||
"TCFB64Monte1" => "fips_desmovs -f",
|
||||
"TCFB64Monte2" => "fips_desmovs -f",
|
||||
"TCFB64Monte3" => "fips_desmovs -f",
|
||||
"TCFB64permop" => "fips_desmovs -f",
|
||||
"TCFB64subtab" => "fips_desmovs -f",
|
||||
"TCFB64varkey" => "fips_desmovs -f",
|
||||
"TCFB64vartext" => "fips_desmovs -f",
|
||||
"TCFB8invperm" => "fips_desmovs -f",
|
||||
"TCFB8MMT1" => "fips_desmovs -f",
|
||||
"TCFB8MMT2" => "fips_desmovs -f",
|
||||
"TCFB8MMT3" => "fips_desmovs -f",
|
||||
"TCFB8Monte1" => "fips_desmovs -f",
|
||||
"TCFB8Monte2" => "fips_desmovs -f",
|
||||
"TCFB8Monte3" => "fips_desmovs -f",
|
||||
"TCFB8permop" => "fips_desmovs -f",
|
||||
"TCFB8subtab" => "fips_desmovs -f",
|
||||
"TCFB8varkey" => "fips_desmovs -f",
|
||||
"TCFB8vartext" => "fips_desmovs -f",
|
||||
"TECBinvperm" => "fips_desmovs -f",
|
||||
"TECBMMT1" => "fips_desmovs -f",
|
||||
"TECBMMT2" => "fips_desmovs -f",
|
||||
"TECBMMT3" => "fips_desmovs -f",
|
||||
"TECBMonte1" => "fips_desmovs -f",
|
||||
"TECBMonte2" => "fips_desmovs -f",
|
||||
"TECBMonte3" => "fips_desmovs -f",
|
||||
"TECBpermop" => "fips_desmovs -f",
|
||||
"TECBsubtab" => "fips_desmovs -f",
|
||||
"TECBvarkey" => "fips_desmovs -f",
|
||||
"TECBvartext" => "fips_desmovs -f",
|
||||
"TOFBinvperm" => "fips_desmovs -f",
|
||||
"TOFBMMT1" => "fips_desmovs -f",
|
||||
"TOFBMMT2" => "fips_desmovs -f",
|
||||
"TOFBMMT3" => "fips_desmovs -f",
|
||||
"TOFBMonte1" => "fips_desmovs -f",
|
||||
"TOFBMonte2" => "fips_desmovs -f",
|
||||
"TOFBMonte3" => "fips_desmovs -f",
|
||||
"TOFBpermop" => "fips_desmovs -f",
|
||||
"TOFBsubtab" => "fips_desmovs -f",
|
||||
"TOFBvarkey" => "fips_desmovs -f",
|
||||
"TOFBvartext" => "fips_desmovs -f",
|
||||
"TCBCinvperm" => "fips_desmovs -f",
|
||||
"TCBCMMT1" => "fips_desmovs -f",
|
||||
"TCBCMMT2" => "fips_desmovs -f",
|
||||
"TCBCMMT3" => "fips_desmovs -f",
|
||||
"TCBCMonte1" => "fips_desmovs -f",
|
||||
"TCBCMonte2" => "fips_desmovs -f",
|
||||
"TCBCMonte3" => "fips_desmovs -f",
|
||||
"TCBCpermop" => "fips_desmovs -f",
|
||||
"TCBCsubtab" => "fips_desmovs -f",
|
||||
"TCBCvarkey" => "fips_desmovs -f",
|
||||
"TCBCvartext" => "fips_desmovs -f",
|
||||
"TCFB64invperm" => "fips_desmovs -f",
|
||||
"TCFB64MMT1" => "fips_desmovs -f",
|
||||
"TCFB64MMT2" => "fips_desmovs -f",
|
||||
"TCFB64MMT3" => "fips_desmovs -f",
|
||||
"TCFB64Monte1" => "fips_desmovs -f",
|
||||
"TCFB64Monte2" => "fips_desmovs -f",
|
||||
"TCFB64Monte3" => "fips_desmovs -f",
|
||||
"TCFB64permop" => "fips_desmovs -f",
|
||||
"TCFB64subtab" => "fips_desmovs -f",
|
||||
"TCFB64varkey" => "fips_desmovs -f",
|
||||
"TCFB64vartext" => "fips_desmovs -f",
|
||||
"TCFB8invperm" => "fips_desmovs -f",
|
||||
"TCFB8MMT1" => "fips_desmovs -f",
|
||||
"TCFB8MMT2" => "fips_desmovs -f",
|
||||
"TCFB8MMT3" => "fips_desmovs -f",
|
||||
"TCFB8Monte1" => "fips_desmovs -f",
|
||||
"TCFB8Monte2" => "fips_desmovs -f",
|
||||
"TCFB8Monte3" => "fips_desmovs -f",
|
||||
"TCFB8permop" => "fips_desmovs -f",
|
||||
"TCFB8subtab" => "fips_desmovs -f",
|
||||
"TCFB8varkey" => "fips_desmovs -f",
|
||||
"TCFB8vartext" => "fips_desmovs -f",
|
||||
"TECBinvperm" => "fips_desmovs -f",
|
||||
"TECBMMT1" => "fips_desmovs -f",
|
||||
"TECBMMT2" => "fips_desmovs -f",
|
||||
"TECBMMT3" => "fips_desmovs -f",
|
||||
"TECBMonte1" => "fips_desmovs -f",
|
||||
"TECBMonte2" => "fips_desmovs -f",
|
||||
"TECBMonte3" => "fips_desmovs -f",
|
||||
"TECBpermop" => "fips_desmovs -f",
|
||||
"TECBsubtab" => "fips_desmovs -f",
|
||||
"TECBvarkey" => "fips_desmovs -f",
|
||||
"TECBvartext" => "fips_desmovs -f",
|
||||
"TOFBinvperm" => "fips_desmovs -f",
|
||||
"TOFBMMT1" => "fips_desmovs -f",
|
||||
"TOFBMMT2" => "fips_desmovs -f",
|
||||
"TOFBMMT3" => "fips_desmovs -f",
|
||||
"TOFBMonte1" => "fips_desmovs -f",
|
||||
"TOFBMonte2" => "fips_desmovs -f",
|
||||
"TOFBMonte3" => "fips_desmovs -f",
|
||||
"TOFBpermop" => "fips_desmovs -f",
|
||||
"TOFBsubtab" => "fips_desmovs -f",
|
||||
"TOFBvarkey" => "fips_desmovs -f",
|
||||
"TOFBvartext" => "fips_desmovs -f"
|
||||
|
||||
);
|
||||
my %salt_names = (
|
||||
"SigVerPSS (salt 0)" => "SigVerPSS",
|
||||
"SigVerPSS (salt 62)" => "SigVerPSS",
|
||||
"SigGenPSS (salt 0)" => "SigGenPSS",
|
||||
"SigGenPSS (salt 62)" => "SigGenPSS",
|
||||
);
|
||||
|
||||
|
||||
my $win32 = $^O =~ m/mswin/i;
|
||||
my $onedir = 0;
|
||||
my $filter = "";
|
||||
my $tvdir;
|
||||
my $tprefix;
|
||||
my $shwrap_prefix;
|
||||
my $shwrap;
|
||||
my $rmcmd = "rm -rf";
|
||||
my $mkcmd = "mkdir";
|
||||
my $debug = 0;
|
||||
my $quiet = 0;
|
||||
my $rspdir = "rsp";
|
||||
my $rspignore = 0;
|
||||
my @bogus = (); # list of unmatched *.rsp files
|
||||
my $bufout = '';
|
||||
my $bufdir = '';
|
||||
my %_programs = (); # list of external programs to check
|
||||
|
||||
foreach (@ARGV)
|
||||
{
|
||||
if ($_ eq "--win32")
|
||||
{
|
||||
$win32 = 1;
|
||||
}
|
||||
elsif ($_ eq "--onedir")
|
||||
{
|
||||
$onedir = 1;
|
||||
}
|
||||
elsif ($_ eq "--debug")
|
||||
{
|
||||
$debug = 1;
|
||||
}
|
||||
elsif ($_ eq "--quiet")
|
||||
{
|
||||
$quiet = 1;
|
||||
}
|
||||
elsif (/--dir=(.*)$/)
|
||||
{
|
||||
$tvdir = $1;
|
||||
}
|
||||
elsif (/--rspdir=(.*)$/)
|
||||
{
|
||||
$rspdir = $1;
|
||||
}
|
||||
elsif (/--noshwrap$/)
|
||||
{
|
||||
$shwrap = "";
|
||||
}
|
||||
elsif (/--rspignore$/)
|
||||
{
|
||||
$rspignore = 1;
|
||||
}
|
||||
elsif (/--tprefix=(.*)$/)
|
||||
{
|
||||
$tprefix = $1;
|
||||
}
|
||||
elsif (/--shwrap_prefix=(.*)$/)
|
||||
{
|
||||
$shwrap_prefix = $1;
|
||||
}
|
||||
elsif (/--filter=(.*)$/)
|
||||
{
|
||||
$filter = $1;
|
||||
}
|
||||
elsif (/--mkdir=(.*)$/)
|
||||
{
|
||||
$mkcmd = $1;
|
||||
}
|
||||
elsif (/--rm=(.*)$/)
|
||||
{
|
||||
$rmcmd = $1;
|
||||
}
|
||||
elsif (/--outfile=(.*)$/)
|
||||
{
|
||||
$outfile = $1;
|
||||
}
|
||||
else
|
||||
{
|
||||
&Help();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
$tvdir = "." unless defined $tvdir;
|
||||
|
||||
if ($win32)
|
||||
{
|
||||
if (!defined $tprefix)
|
||||
{
|
||||
if ($onedir)
|
||||
{
|
||||
$tprefix = ".\\";
|
||||
}
|
||||
else
|
||||
{
|
||||
$tprefix = "..\\out32dll\\";
|
||||
}
|
||||
}
|
||||
|
||||
$bufinit .= <<END;
|
||||
\@echo off
|
||||
rem Test vector run script
|
||||
rem Auto generated by mkfipsscr.pl script
|
||||
rem Do not edit
|
||||
|
||||
END
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($onedir)
|
||||
{
|
||||
$tprefix = "./" unless defined $tprefix;
|
||||
$shwrap_prefix = "./" unless defined $shwrap_prefix;
|
||||
}
|
||||
else
|
||||
{
|
||||
$tprefix = "../test/" unless defined $tprefix;
|
||||
$shwrap_prefix = "../util/" unless defined $shwrap_prefix;
|
||||
}
|
||||
|
||||
$shwrap = "${shwrap_prefix}shlib_wrap.sh " unless defined $shwrap;
|
||||
|
||||
$bufinit .= <<END;
|
||||
#!/bin/sh
|
||||
|
||||
# Test vector run script
|
||||
# Auto generated by mkfipsscr.pl script
|
||||
# Do not edit
|
||||
|
||||
RM="$rmcmd"
|
||||
MKDIR="$mkcmd"
|
||||
TPREFIX=$tprefix
|
||||
END
|
||||
|
||||
}
|
||||
my %fips_found;
|
||||
foreach (keys %fips_tests)
|
||||
{
|
||||
$fips_found{$_} = 0;
|
||||
}
|
||||
my %saltPSS;
|
||||
for (keys %salt_names)
|
||||
{
|
||||
$salt_found{$_} = 0;
|
||||
}
|
||||
|
||||
recurse_test($win32, $tprefix, $filter, $tvdir);
|
||||
|
||||
while (($key, $value) = each %salt_found)
|
||||
{
|
||||
&countentry($key, $value);
|
||||
delete $fips_found{$salt_names{$key}};
|
||||
}
|
||||
while (($key, $value) = each %fips_found)
|
||||
{
|
||||
&countentry($key, $value);
|
||||
}
|
||||
|
||||
# If no fatal errors write out the script file
|
||||
$outfile = "fipstests.sh" unless defined $outfile;
|
||||
open(OUT, ">$outfile") || die "Error opening $outfile: $!";
|
||||
print OUT $bufinit;
|
||||
if (!$rspignore && @bogus)
|
||||
{
|
||||
print STDERR "ERROR: please remove bogus *.rsp files\n";
|
||||
print OUT <<EOF;
|
||||
echo $outfile generation failed due to presence of bogus *.rsp files
|
||||
EOF
|
||||
}
|
||||
else
|
||||
{
|
||||
print OUT $bufout;
|
||||
}
|
||||
close OUT;
|
||||
|
||||
# Check for external programs
|
||||
for (keys %_programs)
|
||||
{
|
||||
s/ .*$//;
|
||||
-x $_ || print STDERR "WARNING: program $_ not found\n";
|
||||
}
|
||||
|
||||
#--------------------------------
|
||||
sub Help {
|
||||
(my $cmd) = ($0 =~ m#([^/]+)$#);
|
||||
print <<EOF;
|
||||
$cmd: generate script for CMVP algorithm tests
|
||||
--debug Enable debug output
|
||||
--dir=<dirname> Optional root for *.req file search
|
||||
--filter=<regexp>
|
||||
--onedir <dirname> Assume all components in current directory
|
||||
--outfile=<filename> Optional name of output script, default fipstests.{sh|bat}
|
||||
--rspdir=<dirname> Name of subdirectories containing *.rsp files, default "resp"
|
||||
--rspignore Ignore any bogus *.rsp files
|
||||
--shwrap_prefix=<prefix>
|
||||
--tprefix=<prefix>
|
||||
--quiet Shhh....
|
||||
--win32 Generate script for Win32 environment
|
||||
EOF
|
||||
}
|
||||
|
||||
#--------------------------------
|
||||
sub countentry {
|
||||
my ($key,$value) = @_;
|
||||
if ($value == 0)
|
||||
{
|
||||
print STDERR "WARNING: test file $key not found\n" unless $quiet;
|
||||
}
|
||||
elsif ($value > 1)
|
||||
{
|
||||
print STDERR "WARNING: test file $key found $value times\n" unless $quiet;
|
||||
}
|
||||
else
|
||||
{
|
||||
print STDERR "Found test file $key\n" if $debug;
|
||||
}
|
||||
}
|
||||
|
||||
#--------------------------------
|
||||
sub recurse_test
|
||||
{
|
||||
my ($win32, $tprefix, $filter, $dir) = @_;
|
||||
my $dirh;
|
||||
opendir($dirh, $dir);
|
||||
while ($_ = readdir($dirh))
|
||||
{
|
||||
next if ($_ eq "." || $_ eq "..");
|
||||
$_ = "$dir/$_";
|
||||
if (-f "$_")
|
||||
{
|
||||
if (/\/([^\/]*)\.rsp$/)
|
||||
{
|
||||
if (exists $fips_tests{$1})
|
||||
{
|
||||
$debug && print "DEBUG: $1 found, will be overwritten\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
print STDERR "ERROR: bogus file $_\n";
|
||||
push @bogus, $_;
|
||||
}
|
||||
}
|
||||
next unless /$filter.*\.req$/i;
|
||||
if (/\/([^\/]*)\.req$/ && exists $fips_tests{$1})
|
||||
{
|
||||
$fips_found{$1}++;
|
||||
test_line($win32, $_, $tprefix, $1);
|
||||
}
|
||||
elsif (! /SHAmix\.req$/)
|
||||
{
|
||||
print STDERR "WARNING: unrecognized filename $_\n";
|
||||
}
|
||||
}
|
||||
elsif (-d "$_")
|
||||
{
|
||||
if (/$filter.*req$/i)
|
||||
{
|
||||
test_dir($win32, $_);
|
||||
}
|
||||
recurse_test($win32, $tprefix, $filter, $_);
|
||||
}
|
||||
}
|
||||
closedir($dirh);
|
||||
}
|
||||
|
||||
#--------------------------------
|
||||
sub test_dir
|
||||
{
|
||||
my ($win32, $req) = @_;
|
||||
my $rsp = $req;
|
||||
$rsp =~ s/req$/$rspdir/;
|
||||
if ($win32)
|
||||
{
|
||||
$rsp =~ tr|/|\\|;
|
||||
$req =~ tr|/|\\|;
|
||||
$bufdir = <<END;
|
||||
|
||||
echo Running tests in $req
|
||||
if exist "$rsp" rd /s /q "$rsp"
|
||||
md "$rsp"
|
||||
END
|
||||
}
|
||||
else
|
||||
{
|
||||
$bufdir = <<END;
|
||||
|
||||
echo Running tests in "$req"
|
||||
\$RM "$rsp"
|
||||
\$MKDIR "$rsp"
|
||||
|
||||
END
|
||||
}
|
||||
}
|
||||
|
||||
#--------------------------------
|
||||
sub test_line
|
||||
{
|
||||
my ($win32, $req, $tprefix, $tnam) = @_;
|
||||
my $rsp = $req;
|
||||
my $tcmd = $fips_tests{$tnam};
|
||||
|
||||
$bufout .= $bufdir;
|
||||
$bufdir = "";
|
||||
|
||||
$rsp =~ s/req\/([^\/]*).req$/$rspdir\/$1.rsp/;
|
||||
if ($tcmd =~ /-f$/)
|
||||
{
|
||||
if ($win32)
|
||||
{
|
||||
$req =~ tr|/|\\|;
|
||||
$rsp =~ tr|/|\\|;
|
||||
$bufout .= "$tprefix$tcmd \"$req\" \"$rsp\"\n";
|
||||
$_programs{"$tprefix$tcmd.exe"} = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$bufout .= <<END;
|
||||
${shwrap}\${TPREFIX}$tcmd "$req" "$rsp" || { echo "$req failure" ; exit 1
|
||||
}
|
||||
END
|
||||
$_programs{"${shwrap_prefix}shlib_wrap.sh"} = 1;
|
||||
$_programs{"$tprefix$tcmd"} = 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if ($tcmd =~ /SALT$/)
|
||||
{
|
||||
open (IN, $req) || die "Can't Open File $req";
|
||||
my $saltlen;
|
||||
while (<IN>)
|
||||
{
|
||||
if (/^\s*#\s*salt\s+len:\s+(\d+)\s*$/i)
|
||||
{
|
||||
my $sl = $1;
|
||||
print STDERR "$req salt length $sl\n" if $debug;
|
||||
$tcmd =~ s/SALT$/$sl/;
|
||||
$salt_found{"$tnam (salt $sl)"}++;
|
||||
last;
|
||||
}
|
||||
}
|
||||
close IN;
|
||||
if ($tcmd =~ /SALT$/)
|
||||
{
|
||||
die "Can't detect salt length for $req";
|
||||
}
|
||||
}
|
||||
|
||||
if ($win32)
|
||||
{
|
||||
$req =~ tr|/|\\|;
|
||||
$rsp =~ tr|/|\\|;
|
||||
$bufout .= "$tprefix$tcmd < \"$req\" > \"$rsp\"\n";
|
||||
$_programs{"$tprefix$tcmd.exe"} = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$bufout .= <<END;
|
||||
${shwrap}\${TPREFIX}$tcmd < "$req" > "$rsp" || { echo "$req failure" ; exit 1; }
|
||||
END
|
||||
$_programs{"$tprefix$tcmd"} = 1;
|
||||
}
|
||||
}
|
||||
|
4
fips/rand/.cvsignore
Normal file
4
fips/rand/.cvsignore
Normal file
@ -0,0 +1,4 @@
|
||||
lib
|
||||
Makefile.save
|
||||
*.flc
|
||||
semantic.cache
|
149
fips/rand/Makefile
Normal file
149
fips/rand/Makefile
Normal file
@ -0,0 +1,149 @@
|
||||
#
|
||||
# OpenSSL/fips/rand/Makefile
|
||||
#
|
||||
|
||||
DIR= rand
|
||||
TOP= ../..
|
||||
CC= cc
|
||||
INCLUDES=
|
||||
CFLAG=-g
|
||||
INSTALL_PREFIX=
|
||||
OPENSSLDIR= /usr/local/ssl
|
||||
INSTALLTOP=/usr/local/ssl
|
||||
MAKEDEPPROG= makedepend
|
||||
MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
|
||||
MAKEFILE= Makefile
|
||||
AR= ar r
|
||||
|
||||
CFLAGS= $(INCLUDES) $(CFLAG)
|
||||
|
||||
GENERAL=Makefile
|
||||
TEST= fips_randtest.c fips_rngvs.c
|
||||
APPS=
|
||||
|
||||
LIB=$(TOP)/libcrypto.a
|
||||
LIBSRC=fips_rand.c fips_rand_selftest.c
|
||||
LIBOBJ=fips_rand.o fips_rand_selftest.o
|
||||
|
||||
SRC= $(LIBSRC)
|
||||
|
||||
EXHEADER= fips_rand.h
|
||||
HEADER= $(EXHEADER)
|
||||
|
||||
ALL= $(GENERAL) $(SRC) $(HEADER)
|
||||
|
||||
top:
|
||||
(cd $(TOP); $(MAKE) DIRS=fips SDIRS=$(DIR) sub_all)
|
||||
|
||||
all: lib
|
||||
|
||||
lib: $(LIBOBJ)
|
||||
@echo $(LIBOBJ) > lib
|
||||
|
||||
files:
|
||||
$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
|
||||
|
||||
links:
|
||||
@$(PERL) $(TOP)/util/mklink.pl $(TOP)/include/openssl $(EXHEADER)
|
||||
@$(PERL) $(TOP)/util/mklink.pl $(TOP)/test $(TEST)
|
||||
@$(PERL) $(TOP)/util/mklink.pl $(TOP)/apps $(APPS)
|
||||
|
||||
install:
|
||||
@headerlist="$(EXHEADER)"; for i in $$headerlist; \
|
||||
do \
|
||||
(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
|
||||
chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
|
||||
done
|
||||
|
||||
tags:
|
||||
ctags $(SRC)
|
||||
|
||||
tests:
|
||||
|
||||
Q=../testvectors/rng/req
|
||||
A=../testvectors/rng/rsp
|
||||
|
||||
fips_test:
|
||||
-rm -rf $(A)
|
||||
mkdir $(A)
|
||||
if [ -f $(Q)/ANSI931_AES128MCT.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rngvs mct < $(Q)/ANSI931_AES128MCT.req > $(A)/ANSI931_AES128MCT.rsp; fi
|
||||
if [ -f $(Q)/ANSI931_AES192MCT.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rngvs mct < $(Q)/ANSI931_AES192MCT.req > $(A)/ANSI931_AES192MCT.rsp; fi
|
||||
if [ -f $(Q)/ANSI931_AES256MCT.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rngvs mct < $(Q)/ANSI931_AES256MCT.req > $(A)/ANSI931_AES256MCT.rsp; fi
|
||||
if [ -f $(Q)/ANSI931_AES128VST.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rngvs vst < $(Q)/ANSI931_AES128VST.req > $(A)/ANSI931_AES128VST.rsp; fi
|
||||
if [ -f $(Q)/ANSI931_AES192VST.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rngvs vst < $(Q)/ANSI931_AES192VST.req > $(A)/ANSI931_AES192VST.rsp; fi
|
||||
if [ -f $(Q)/ANSI931_AES256VST.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rngvs vst < $(Q)/ANSI931_AES256VST.req > $(A)/ANSI931_AES256VST.rsp; fi
|
||||
|
||||
lint:
|
||||
lint -DLINT $(INCLUDES) $(SRC)>fluff
|
||||
|
||||
depend:
|
||||
$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(SRC) $(TEST)
|
||||
|
||||
dclean:
|
||||
$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
|
||||
mv -f Makefile.new $(MAKEFILE)
|
||||
|
||||
clean:
|
||||
rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
|
||||
|
||||
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
||||
|
||||
fips_rand.o: ../../e_os.h ../../include/openssl/aes.h
|
||||
fips_rand.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
|
||||
fips_rand.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
|
||||
fips_rand.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
|
||||
fips_rand.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h
|
||||
fips_rand.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
|
||||
fips_rand.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
|
||||
fips_rand.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
|
||||
fips_rand.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
|
||||
fips_rand.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
|
||||
fips_rand.o: ../fips_locl.h fips_rand.c
|
||||
fips_rand_selftest.o: ../../include/openssl/bio.h
|
||||
fips_rand_selftest.o: ../../include/openssl/crypto.h
|
||||
fips_rand_selftest.o: ../../include/openssl/des.h
|
||||
fips_rand_selftest.o: ../../include/openssl/des_old.h
|
||||
fips_rand_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
|
||||
fips_rand_selftest.o: ../../include/openssl/fips.h
|
||||
fips_rand_selftest.o: ../../include/openssl/fips_rand.h
|
||||
fips_rand_selftest.o: ../../include/openssl/lhash.h
|
||||
fips_rand_selftest.o: ../../include/openssl/opensslconf.h
|
||||
fips_rand_selftest.o: ../../include/openssl/opensslv.h
|
||||
fips_rand_selftest.o: ../../include/openssl/ossl_typ.h
|
||||
fips_rand_selftest.o: ../../include/openssl/rand.h
|
||||
fips_rand_selftest.o: ../../include/openssl/safestack.h
|
||||
fips_rand_selftest.o: ../../include/openssl/stack.h
|
||||
fips_rand_selftest.o: ../../include/openssl/symhacks.h
|
||||
fips_rand_selftest.o: ../../include/openssl/ui.h
|
||||
fips_rand_selftest.o: ../../include/openssl/ui_compat.h fips_rand_selftest.c
|
||||
fips_randtest.o: ../../e_os.h ../../include/openssl/bio.h
|
||||
fips_randtest.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
|
||||
fips_randtest.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
|
||||
fips_randtest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
|
||||
fips_randtest.o: ../../include/openssl/fips_rand.h
|
||||
fips_randtest.o: ../../include/openssl/lhash.h
|
||||
fips_randtest.o: ../../include/openssl/opensslconf.h
|
||||
fips_randtest.o: ../../include/openssl/opensslv.h
|
||||
fips_randtest.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
|
||||
fips_randtest.o: ../../include/openssl/safestack.h
|
||||
fips_randtest.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
|
||||
fips_randtest.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
|
||||
fips_randtest.o: ../fips_utl.h fips_randtest.c
|
||||
fips_rngvs.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
|
||||
fips_rngvs.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
|
||||
fips_rngvs.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
|
||||
fips_rngvs.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
|
||||
fips_rngvs.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
|
||||
fips_rngvs.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
|
||||
fips_rngvs.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
|
||||
fips_rngvs.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
|
||||
fips_rngvs.o: ../../include/openssl/fips_rand.h ../../include/openssl/lhash.h
|
||||
fips_rngvs.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
|
||||
fips_rngvs.o: ../../include/openssl/opensslconf.h
|
||||
fips_rngvs.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
|
||||
fips_rngvs.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
|
||||
fips_rngvs.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
|
||||
fips_rngvs.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
|
||||
fips_rngvs.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
|
||||
fips_rngvs.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
|
||||
fips_rngvs.o: ../../include/openssl/x509v3.h ../fips_utl.h fips_rngvs.c
|
412
fips/rand/fips_rand.c
Normal file
412
fips/rand/fips_rand.c
Normal file
@ -0,0 +1,412 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2007 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is a FIPS approved AES PRNG based on ANSI X9.31 A.2.4.
|
||||
*/
|
||||
|
||||
#include "e_os.h"
|
||||
|
||||
/* If we don't define _XOPEN_SOURCE_EXTENDED, struct timeval won't
|
||||
be defined and gettimeofday() won't be declared with strict compilers
|
||||
like DEC C in ANSI C mode. */
|
||||
#ifndef _XOPEN_SOURCE_EXTENDED
|
||||
#define _XOPEN_SOURCE_EXTENDED 1
|
||||
#endif
|
||||
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/fips_rand.h>
|
||||
#ifndef OPENSSL_SYS_WIN32
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#include <assert.h>
|
||||
#ifndef OPENSSL_SYS_WIN32
|
||||
# ifdef OPENSSL_UNISTD
|
||||
# include OPENSSL_UNISTD
|
||||
# else
|
||||
# include <unistd.h>
|
||||
# endif
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <openssl/fips.h>
|
||||
#include "fips_locl.h"
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
|
||||
void *OPENSSL_stderr(void);
|
||||
|
||||
#define AES_BLOCK_LENGTH 16
|
||||
|
||||
|
||||
/* AES FIPS PRNG implementation */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int seeded;
|
||||
int keyed;
|
||||
int test_mode;
|
||||
int second;
|
||||
int error;
|
||||
unsigned long counter;
|
||||
AES_KEY ks;
|
||||
int vpos;
|
||||
/* Temporary storage for key if it equals seed length */
|
||||
unsigned char tmp_key[AES_BLOCK_LENGTH];
|
||||
unsigned char V[AES_BLOCK_LENGTH];
|
||||
unsigned char DT[AES_BLOCK_LENGTH];
|
||||
unsigned char last[AES_BLOCK_LENGTH];
|
||||
} FIPS_PRNG_CTX;
|
||||
|
||||
static FIPS_PRNG_CTX sctx;
|
||||
|
||||
static int fips_prng_fail = 0;
|
||||
|
||||
void FIPS_rng_stick(void)
|
||||
{
|
||||
fips_prng_fail = 1;
|
||||
}
|
||||
|
||||
static void fips_rand_prng_reset(FIPS_PRNG_CTX *ctx)
|
||||
{
|
||||
ctx->seeded = 0;
|
||||
ctx->keyed = 0;
|
||||
ctx->test_mode = 0;
|
||||
ctx->counter = 0;
|
||||
ctx->second = 0;
|
||||
ctx->error = 0;
|
||||
ctx->vpos = 0;
|
||||
OPENSSL_cleanse(ctx->V, AES_BLOCK_LENGTH);
|
||||
OPENSSL_cleanse(&ctx->ks, sizeof(AES_KEY));
|
||||
}
|
||||
|
||||
|
||||
static int fips_set_prng_key(FIPS_PRNG_CTX *ctx,
|
||||
const unsigned char *key, unsigned int keylen)
|
||||
{
|
||||
FIPS_selftest_check();
|
||||
if (keylen != 16 && keylen != 24 && keylen != 32)
|
||||
{
|
||||
/* error: invalid key size */
|
||||
return 0;
|
||||
}
|
||||
AES_set_encrypt_key(key, keylen << 3, &ctx->ks);
|
||||
if (keylen == 16)
|
||||
{
|
||||
memcpy(ctx->tmp_key, key, 16);
|
||||
ctx->keyed = 2;
|
||||
}
|
||||
else
|
||||
ctx->keyed = 1;
|
||||
ctx->seeded = 0;
|
||||
ctx->second = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int fips_set_prng_seed(FIPS_PRNG_CTX *ctx,
|
||||
const unsigned char *seed, unsigned int seedlen)
|
||||
{
|
||||
unsigned int i;
|
||||
if (!ctx->keyed)
|
||||
return 0;
|
||||
/* In test mode seed is just supplied data */
|
||||
if (ctx->test_mode)
|
||||
{
|
||||
if (seedlen != AES_BLOCK_LENGTH)
|
||||
return 0;
|
||||
memcpy(ctx->V, seed, AES_BLOCK_LENGTH);
|
||||
ctx->seeded = 1;
|
||||
return 1;
|
||||
}
|
||||
/* Outside test mode XOR supplied data with existing seed */
|
||||
for (i = 0; i < seedlen; i++)
|
||||
{
|
||||
ctx->V[ctx->vpos++] ^= seed[i];
|
||||
if (ctx->vpos == AES_BLOCK_LENGTH)
|
||||
{
|
||||
ctx->vpos = 0;
|
||||
/* Special case if first seed and key length equals
|
||||
* block size check key and seed do not match.
|
||||
*/
|
||||
if (ctx->keyed == 2)
|
||||
{
|
||||
if (!memcmp(ctx->tmp_key, ctx->V, 16))
|
||||
{
|
||||
RANDerr(RAND_F_FIPS_SET_PRNG_SEED,
|
||||
RAND_R_PRNG_SEED_MUST_NOT_MATCH_KEY);
|
||||
return 0;
|
||||
}
|
||||
OPENSSL_cleanse(ctx->tmp_key, 16);
|
||||
ctx->keyed = 1;
|
||||
}
|
||||
ctx->seeded = 1;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int fips_set_test_mode(FIPS_PRNG_CTX *ctx)
|
||||
{
|
||||
if (ctx->keyed)
|
||||
{
|
||||
RANDerr(RAND_F_FIPS_SET_TEST_MODE,RAND_R_PRNG_KEYED);
|
||||
return 0;
|
||||
}
|
||||
ctx->test_mode = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int FIPS_rand_test_mode(void)
|
||||
{
|
||||
return fips_set_test_mode(&sctx);
|
||||
}
|
||||
|
||||
int FIPS_rand_set_dt(unsigned char *dt)
|
||||
{
|
||||
if (!sctx.test_mode)
|
||||
{
|
||||
RANDerr(RAND_F_FIPS_RAND_SET_DT,RAND_R_NOT_IN_TEST_MODE);
|
||||
return 0;
|
||||
}
|
||||
memcpy(sctx.DT, dt, AES_BLOCK_LENGTH);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void fips_get_dt(FIPS_PRNG_CTX *ctx)
|
||||
{
|
||||
#ifdef OPENSSL_SYS_WIN32
|
||||
FILETIME ft;
|
||||
#else
|
||||
struct timeval tv;
|
||||
#endif
|
||||
unsigned char *buf = ctx->DT;
|
||||
|
||||
#ifndef GETPID_IS_MEANINGLESS
|
||||
unsigned long pid;
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_SYS_WIN32
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
buf[0] = (unsigned char) (ft.dwHighDateTime & 0xff);
|
||||
buf[1] = (unsigned char) ((ft.dwHighDateTime >> 8) & 0xff);
|
||||
buf[2] = (unsigned char) ((ft.dwHighDateTime >> 16) & 0xff);
|
||||
buf[3] = (unsigned char) ((ft.dwHighDateTime >> 24) & 0xff);
|
||||
buf[4] = (unsigned char) (ft.dwLowDateTime & 0xff);
|
||||
buf[5] = (unsigned char) ((ft.dwLowDateTime >> 8) & 0xff);
|
||||
buf[6] = (unsigned char) ((ft.dwLowDateTime >> 16) & 0xff);
|
||||
buf[7] = (unsigned char) ((ft.dwLowDateTime >> 24) & 0xff);
|
||||
#else
|
||||
gettimeofday(&tv,NULL);
|
||||
buf[0] = (unsigned char) (tv.tv_sec & 0xff);
|
||||
buf[1] = (unsigned char) ((tv.tv_sec >> 8) & 0xff);
|
||||
buf[2] = (unsigned char) ((tv.tv_sec >> 16) & 0xff);
|
||||
buf[3] = (unsigned char) ((tv.tv_sec >> 24) & 0xff);
|
||||
buf[4] = (unsigned char) (tv.tv_usec & 0xff);
|
||||
buf[5] = (unsigned char) ((tv.tv_usec >> 8) & 0xff);
|
||||
buf[6] = (unsigned char) ((tv.tv_usec >> 16) & 0xff);
|
||||
buf[7] = (unsigned char) ((tv.tv_usec >> 24) & 0xff);
|
||||
#endif
|
||||
buf[8] = (unsigned char) (ctx->counter & 0xff);
|
||||
buf[9] = (unsigned char) ((ctx->counter >> 8) & 0xff);
|
||||
buf[10] = (unsigned char) ((ctx->counter >> 16) & 0xff);
|
||||
buf[11] = (unsigned char) ((ctx->counter >> 24) & 0xff);
|
||||
|
||||
ctx->counter++;
|
||||
|
||||
|
||||
#ifndef GETPID_IS_MEANINGLESS
|
||||
pid=(unsigned long)getpid();
|
||||
buf[12] = (unsigned char) (pid & 0xff);
|
||||
buf[13] = (unsigned char) ((pid >> 8) & 0xff);
|
||||
buf[14] = (unsigned char) ((pid >> 16) & 0xff);
|
||||
buf[15] = (unsigned char) ((pid >> 24) & 0xff);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int fips_rand(FIPS_PRNG_CTX *ctx,
|
||||
unsigned char *out, unsigned int outlen)
|
||||
{
|
||||
unsigned char R[AES_BLOCK_LENGTH], I[AES_BLOCK_LENGTH];
|
||||
unsigned char tmp[AES_BLOCK_LENGTH];
|
||||
int i;
|
||||
if (ctx->error)
|
||||
{
|
||||
RANDerr(RAND_F_FIPS_RAND,RAND_R_PRNG_ERROR);
|
||||
return 0;
|
||||
}
|
||||
if (!ctx->keyed)
|
||||
{
|
||||
RANDerr(RAND_F_FIPS_RAND,RAND_R_NO_KEY_SET);
|
||||
return 0;
|
||||
}
|
||||
if (!ctx->seeded)
|
||||
{
|
||||
RANDerr(RAND_F_FIPS_RAND,RAND_R_PRNG_NOT_SEEDED);
|
||||
return 0;
|
||||
}
|
||||
for (;;)
|
||||
{
|
||||
if (!ctx->test_mode)
|
||||
fips_get_dt(ctx);
|
||||
AES_encrypt(ctx->DT, I, &ctx->ks);
|
||||
for (i = 0; i < AES_BLOCK_LENGTH; i++)
|
||||
tmp[i] = I[i] ^ ctx->V[i];
|
||||
AES_encrypt(tmp, R, &ctx->ks);
|
||||
for (i = 0; i < AES_BLOCK_LENGTH; i++)
|
||||
tmp[i] = R[i] ^ I[i];
|
||||
AES_encrypt(tmp, ctx->V, &ctx->ks);
|
||||
/* Continuous PRNG test */
|
||||
if (ctx->second)
|
||||
{
|
||||
if (fips_prng_fail)
|
||||
memcpy(ctx->last, R, AES_BLOCK_LENGTH);
|
||||
if (!memcmp(R, ctx->last, AES_BLOCK_LENGTH))
|
||||
{
|
||||
RANDerr(RAND_F_FIPS_RAND,RAND_R_PRNG_STUCK);
|
||||
ctx->error = 1;
|
||||
fips_set_selftest_fail();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
memcpy(ctx->last, R, AES_BLOCK_LENGTH);
|
||||
if (!ctx->second)
|
||||
{
|
||||
ctx->second = 1;
|
||||
if (!ctx->test_mode)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (outlen <= AES_BLOCK_LENGTH)
|
||||
{
|
||||
memcpy(out, R, outlen);
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(out, R, AES_BLOCK_LENGTH);
|
||||
out += AES_BLOCK_LENGTH;
|
||||
outlen -= AES_BLOCK_LENGTH;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int FIPS_rand_set_key(const unsigned char *key, int keylen)
|
||||
{
|
||||
int ret;
|
||||
CRYPTO_w_lock(CRYPTO_LOCK_RAND);
|
||||
ret = fips_set_prng_key(&sctx, key, keylen);
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int FIPS_rand_seed(const void *seed, int seedlen)
|
||||
{
|
||||
int ret;
|
||||
CRYPTO_w_lock(CRYPTO_LOCK_RAND);
|
||||
ret = fips_set_prng_seed(&sctx, seed, seedlen);
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int FIPS_rand_bytes(unsigned char *out, int count)
|
||||
{
|
||||
int ret;
|
||||
CRYPTO_w_lock(CRYPTO_LOCK_RAND);
|
||||
ret = fips_rand(&sctx, out, count);
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int FIPS_rand_status(void)
|
||||
{
|
||||
int ret;
|
||||
CRYPTO_r_lock(CRYPTO_LOCK_RAND);
|
||||
ret = sctx.seeded;
|
||||
CRYPTO_r_unlock(CRYPTO_LOCK_RAND);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void FIPS_rand_reset(void)
|
||||
{
|
||||
CRYPTO_w_lock(CRYPTO_LOCK_RAND);
|
||||
fips_rand_prng_reset(&sctx);
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
|
||||
}
|
||||
|
||||
static int fips_do_rand_seed(const void *seed, int seedlen)
|
||||
{
|
||||
FIPS_rand_seed(seed, seedlen);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int fips_do_rand_add(const void *seed, int seedlen,
|
||||
double add_entropy)
|
||||
{
|
||||
FIPS_rand_seed(seed, seedlen);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const RAND_METHOD rand_fips_meth=
|
||||
{
|
||||
fips_do_rand_seed,
|
||||
FIPS_rand_bytes,
|
||||
FIPS_rand_reset,
|
||||
fips_do_rand_add,
|
||||
FIPS_rand_bytes,
|
||||
FIPS_rand_status
|
||||
};
|
||||
|
||||
const RAND_METHOD *FIPS_rand_method(void)
|
||||
{
|
||||
return &rand_fips_meth;
|
||||
}
|
||||
|
||||
#endif
|
77
fips/rand/fips_rand.h
Normal file
77
fips/rand/fips_rand.h
Normal file
@ -0,0 +1,77 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2003 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HEADER_FIPS_RAND_H
|
||||
#define HEADER_FIPS_RAND_H
|
||||
|
||||
#include "des.h"
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int FIPS_rand_set_key(const unsigned char *key, int keylen);
|
||||
int FIPS_rand_seed(const void *buf, int num);
|
||||
int FIPS_rand_bytes(unsigned char *out, int outlen);
|
||||
|
||||
int FIPS_rand_test_mode(void);
|
||||
void FIPS_rand_reset(void);
|
||||
int FIPS_rand_set_dt(unsigned char *dt);
|
||||
|
||||
int FIPS_rand_status(void);
|
||||
|
||||
const RAND_METHOD *FIPS_rand_method(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
371
fips/rand/fips_rand_selftest.c
Normal file
371
fips/rand/fips_rand_selftest.c
Normal file
@ -0,0 +1,371 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2003 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/fips.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/fips_rand.h>
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char DT[16];
|
||||
unsigned char V[16];
|
||||
unsigned char R[16];
|
||||
} AES_PRNG_TV;
|
||||
|
||||
/* The following test vectors are taken directly from the RGNVS spec */
|
||||
|
||||
static unsigned char aes_128_key[16] =
|
||||
{0xf3,0xb1,0x66,0x6d,0x13,0x60,0x72,0x42,
|
||||
0xed,0x06,0x1c,0xab,0xb8,0xd4,0x62,0x02};
|
||||
|
||||
static AES_PRNG_TV aes_128_tv[] = {
|
||||
{
|
||||
/* DT */
|
||||
{0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62,
|
||||
0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x22,0xf9},
|
||||
/* V */
|
||||
{0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
|
||||
/* R */
|
||||
{0x59,0x53,0x1e,0xd1,0x3b,0xb0,0xc0,0x55,
|
||||
0x84,0x79,0x66,0x85,0xc1,0x2f,0x76,0x41}
|
||||
},
|
||||
{
|
||||
/* DT */
|
||||
{0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62,
|
||||
0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x22,0xfa},
|
||||
/* V */
|
||||
{0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
|
||||
/* R */
|
||||
{0x7c,0x22,0x2c,0xf4,0xca,0x8f,0xa2,0x4c,
|
||||
0x1c,0x9c,0xb6,0x41,0xa9,0xf3,0x22,0x0d}
|
||||
},
|
||||
{
|
||||
/* DT */
|
||||
{0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62,
|
||||
0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x22,0xfb},
|
||||
/* V */
|
||||
{0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
|
||||
/* R */
|
||||
{0x8a,0xaa,0x00,0x39,0x66,0x67,0x5b,0xe5,
|
||||
0x29,0x14,0x28,0x81,0xa9,0x4d,0x4e,0xc7}
|
||||
},
|
||||
{
|
||||
/* DT */
|
||||
{0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62,
|
||||
0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x22,0xfc},
|
||||
/* V */
|
||||
{0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
|
||||
/* R */
|
||||
{0x88,0xdd,0xa4,0x56,0x30,0x24,0x23,0xe5,
|
||||
0xf6,0x9d,0xa5,0x7e,0x7b,0x95,0xc7,0x3a}
|
||||
},
|
||||
{
|
||||
/* DT */
|
||||
{0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62,
|
||||
0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x22,0xfd},
|
||||
/* V */
|
||||
{0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
|
||||
/* R */
|
||||
{0x05,0x25,0x92,0x46,0x61,0x79,0xd2,0xcb,
|
||||
0x78,0xc4,0x0b,0x14,0x0a,0x5a,0x9a,0xc8}
|
||||
},
|
||||
{
|
||||
/* DT */
|
||||
{0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62,
|
||||
0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x23,0x77},
|
||||
/* V */
|
||||
{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe},
|
||||
/* R */
|
||||
{0x0d,0xd5,0xa0,0x36,0x7a,0x59,0x26,0xbc,
|
||||
0x48,0xd9,0x38,0xbf,0xf0,0x85,0x8f,0xea}
|
||||
},
|
||||
{
|
||||
/* DT */
|
||||
{0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62,
|
||||
0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x23,0x78},
|
||||
/* V */
|
||||
{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
|
||||
/* R */
|
||||
{0xae,0x53,0x87,0xee,0x8c,0xd9,0x12,0xf5,
|
||||
0x73,0x53,0xae,0x03,0xf9,0xd5,0x13,0x33}
|
||||
},
|
||||
};
|
||||
|
||||
static unsigned char aes_192_key[24] =
|
||||
{0x15,0xd8,0x78,0x0d,0x62,0xd3,0x25,0x6e,
|
||||
0x44,0x64,0x10,0x13,0x60,0x2b,0xa9,0xbc,
|
||||
0x4a,0xfb,0xca,0xeb,0x4c,0x8b,0x99,0x3b};
|
||||
|
||||
static AES_PRNG_TV aes_192_tv[] = {
|
||||
{
|
||||
/* DT */
|
||||
{0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1,
|
||||
0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0x4b},
|
||||
/* V */
|
||||
{0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
|
||||
/* R */
|
||||
{0x17,0x07,0xd5,0x28,0x19,0x79,0x1e,0xef,
|
||||
0xa5,0x0c,0xbf,0x25,0xe5,0x56,0xb4,0x93}
|
||||
},
|
||||
{
|
||||
/* DT */
|
||||
{0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1,
|
||||
0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0x4c},
|
||||
/* V */
|
||||
{0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
|
||||
/* R */
|
||||
{0x92,0x8d,0xbe,0x07,0xdd,0xc7,0x58,0xc0,
|
||||
0x6f,0x35,0x41,0x9b,0x17,0xc9,0xbd,0x9b}
|
||||
},
|
||||
{
|
||||
/* DT */
|
||||
{0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1,
|
||||
0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0x4d},
|
||||
/* V */
|
||||
{0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
|
||||
/* R */
|
||||
{0xd5,0xde,0xf4,0x50,0xf3,0xb7,0x10,0x4e,
|
||||
0xb8,0xc6,0xf8,0xcf,0xe2,0xb1,0xca,0xa2}
|
||||
},
|
||||
{
|
||||
/* DT */
|
||||
{0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1,
|
||||
0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0x4e},
|
||||
/* V */
|
||||
{0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
|
||||
/* R */
|
||||
{0xce,0x29,0x08,0x43,0xfc,0x34,0x41,0xe7,
|
||||
0x47,0x8f,0xb3,0x66,0x2b,0x46,0xb1,0xbb}
|
||||
},
|
||||
{
|
||||
/* DT */
|
||||
{0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1,
|
||||
0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0x4f},
|
||||
/* V */
|
||||
{0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
|
||||
/* R */
|
||||
{0xb3,0x26,0x0f,0xf5,0xd6,0xca,0xa8,0xbf,
|
||||
0x89,0xb8,0x5e,0x2f,0x22,0x56,0x92,0x2f}
|
||||
},
|
||||
{
|
||||
/* DT */
|
||||
{0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1,
|
||||
0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0xc9},
|
||||
/* V */
|
||||
{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe},
|
||||
/* R */
|
||||
{0x05,0xeb,0x18,0x52,0x34,0x43,0x00,0x43,
|
||||
0x6e,0x5a,0xa5,0xfe,0x7b,0x32,0xc4,0x2d}
|
||||
},
|
||||
{
|
||||
/* DT */
|
||||
{0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1,
|
||||
0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0xca},
|
||||
/* V */
|
||||
{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
|
||||
/* R */
|
||||
{0x15,0x3c,0xe8,0xd1,0x04,0xc7,0xad,0x50,
|
||||
0x0b,0xf0,0x07,0x16,0xe7,0x56,0x7a,0xea}
|
||||
},
|
||||
};
|
||||
|
||||
static unsigned char aes_256_key[32] =
|
||||
{0x6d,0x14,0x06,0x6c,0xb6,0xd8,0x21,0x2d,
|
||||
0x82,0x8d,0xfa,0xf2,0x7a,0x03,0xb7,0x9f,
|
||||
0x0c,0xc7,0x3e,0xcd,0x76,0xeb,0xee,0xb5,
|
||||
0x21,0x05,0x8c,0x4f,0x31,0x7a,0x80,0xbb};
|
||||
|
||||
static AES_PRNG_TV aes_256_tv[] = {
|
||||
{
|
||||
/* DT */
|
||||
{0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5,
|
||||
0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9e,0x88},
|
||||
/* V */
|
||||
{0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
|
||||
/* R */
|
||||
{0x35,0xc7,0xef,0xa7,0x78,0x4d,0x29,0xbc,
|
||||
0x82,0x79,0x99,0xfb,0xd0,0xb3,0x3b,0x72}
|
||||
},
|
||||
{
|
||||
/* DT */
|
||||
{0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5,
|
||||
0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9e,0x89},
|
||||
/* V */
|
||||
{0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
|
||||
/* R */
|
||||
{0x6c,0xf4,0x42,0x5d,0xc7,0x04,0x1a,0x41,
|
||||
0x28,0x2a,0x78,0xa9,0xb0,0x12,0xc4,0x95}
|
||||
},
|
||||
{
|
||||
/* DT */
|
||||
{0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5,
|
||||
0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9e,0x8a},
|
||||
/* V */
|
||||
{0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
|
||||
/* R */
|
||||
{0x16,0x90,0xa4,0xff,0x7b,0x7e,0xb9,0x30,
|
||||
0xdb,0x67,0x4b,0xac,0x2d,0xe1,0xd1,0x75}
|
||||
},
|
||||
{
|
||||
/* DT */
|
||||
{0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5,
|
||||
0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9e,0x8b},
|
||||
/* V */
|
||||
{0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
|
||||
/* R */
|
||||
{0x14,0x6f,0xf5,0x95,0xa1,0x46,0x65,0x30,
|
||||
0xbc,0x57,0xe2,0x4a,0xf7,0x45,0x62,0x05}
|
||||
},
|
||||
{
|
||||
/* DT */
|
||||
{0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5,
|
||||
0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9e,0x8c},
|
||||
/* V */
|
||||
{0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
|
||||
/* R */
|
||||
{0x96,0xe2,0xb4,0x1e,0x66,0x5e,0x0f,0xa4,
|
||||
0xc5,0xcd,0xa2,0x07,0xcc,0xb7,0x94,0x40}
|
||||
},
|
||||
{
|
||||
/* DT */
|
||||
{0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5,
|
||||
0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9f,0x06},
|
||||
/* V */
|
||||
{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe},
|
||||
/* R */
|
||||
{0x61,0xce,0x1d,0x6a,0x48,0x75,0x97,0x28,
|
||||
0x4b,0x41,0xde,0x18,0x44,0x4f,0x56,0xec}
|
||||
},
|
||||
{
|
||||
/* DT */
|
||||
{0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5,
|
||||
0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9f,0x07},
|
||||
/* V */
|
||||
{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
|
||||
/* R */
|
||||
{0x52,0x89,0x59,0x79,0x2d,0xaa,0x28,0xb3,
|
||||
0xb0,0x8a,0x3e,0x70,0xfa,0x71,0x59,0x84}
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
void FIPS_corrupt_rng()
|
||||
{
|
||||
aes_192_tv[0].V[0]++;
|
||||
}
|
||||
|
||||
#define fips_rand_test(key, tv) \
|
||||
do_rand_test(key, sizeof key, tv, sizeof(tv)/sizeof(AES_PRNG_TV))
|
||||
|
||||
static int do_rand_test(unsigned char *key, int keylen,
|
||||
AES_PRNG_TV *tv, int ntv)
|
||||
{
|
||||
unsigned char R[16];
|
||||
int i;
|
||||
if (!FIPS_rand_set_key(key, keylen))
|
||||
return 0;
|
||||
for (i = 0; i < ntv; i++)
|
||||
{
|
||||
FIPS_rand_seed(tv[i].V, 16);
|
||||
FIPS_rand_set_dt(tv[i].DT);
|
||||
FIPS_rand_bytes(R, 16);
|
||||
if (memcmp(R, tv[i].R, 16))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int FIPS_selftest_rng()
|
||||
{
|
||||
FIPS_rand_reset();
|
||||
if (!FIPS_rand_test_mode())
|
||||
{
|
||||
FIPSerr(FIPS_F_FIPS_SELFTEST_RNG,FIPS_R_SELFTEST_FAILED);
|
||||
return 0;
|
||||
}
|
||||
if (!fips_rand_test(aes_128_key,aes_128_tv)
|
||||
|| !fips_rand_test(aes_192_key, aes_192_tv)
|
||||
|| !fips_rand_test(aes_256_key, aes_256_tv))
|
||||
{
|
||||
FIPSerr(FIPS_F_FIPS_SELFTEST_RNG,FIPS_R_SELFTEST_FAILED);
|
||||
return 0;
|
||||
}
|
||||
FIPS_rand_reset();
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
250
fips/rand/fips_randtest.c
Normal file
250
fips/rand/fips_randtest.c
Normal file
@ -0,0 +1,250 @@
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* 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 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2003 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/fips_rand.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#include "e_os.h"
|
||||
|
||||
#ifndef OPENSSL_FIPS
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
printf("No FIPS RAND support\n");
|
||||
return(0);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <openssl/fips.h>
|
||||
#include "fips_utl.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char DT[16];
|
||||
unsigned char V[16];
|
||||
unsigned char R[16];
|
||||
} AES_PRNG_MCT;
|
||||
|
||||
static unsigned char aes_128_mct_key[16] =
|
||||
{0x9f,0x5b,0x51,0x20,0x0b,0xf3,0x34,0xb5,
|
||||
0xd8,0x2b,0xe8,0xc3,0x72,0x55,0xc8,0x48};
|
||||
|
||||
static AES_PRNG_MCT aes_128_mct_tv = {
|
||||
/* DT */
|
||||
{0x63,0x76,0xbb,0xe5,0x29,0x02,0xba,0x3b,
|
||||
0x67,0xc9,0x25,0xfa,0x70,0x1f,0x11,0xac},
|
||||
/* V */
|
||||
{0x57,0x2c,0x8e,0x76,0x87,0x26,0x47,0x97,
|
||||
0x7e,0x74,0xfb,0xdd,0xc4,0x95,0x01,0xd1},
|
||||
/* R */
|
||||
{0x48,0xe9,0xbd,0x0d,0x06,0xee,0x18,0xfb,
|
||||
0xe4,0x57,0x90,0xd5,0xc3,0xfc,0x9b,0x73}
|
||||
};
|
||||
|
||||
static unsigned char aes_192_mct_key[24] =
|
||||
{0xb7,0x6c,0x34,0xd1,0x09,0x67,0xab,0x73,
|
||||
0x4d,0x5a,0xd5,0x34,0x98,0x16,0x0b,0x91,
|
||||
0xbc,0x35,0x51,0x16,0x6b,0xae,0x93,0x8a};
|
||||
|
||||
static AES_PRNG_MCT aes_192_mct_tv = {
|
||||
/* DT */
|
||||
{0x84,0xce,0x22,0x7d,0x91,0x5a,0xa3,0xc9,
|
||||
0x84,0x3c,0x0a,0xb3,0xa9,0x63,0x15,0x52},
|
||||
/* V */
|
||||
{0xb6,0xaf,0xe6,0x8f,0x99,0x9e,0x90,0x64,
|
||||
0xdd,0xc7,0x7a,0xc1,0xbb,0x90,0x3a,0x6d},
|
||||
/* R */
|
||||
{0xfc,0x85,0x60,0x9a,0x29,0x6f,0xef,0x21,
|
||||
0xdd,0x86,0x20,0x32,0x8a,0x29,0x6f,0x47}
|
||||
};
|
||||
|
||||
static unsigned char aes_256_mct_key[32] =
|
||||
{0x9b,0x05,0xc8,0x68,0xff,0x47,0xf8,0x3a,
|
||||
0xa6,0x3a,0xa8,0xcb,0x4e,0x71,0xb2,0xe0,
|
||||
0xb8,0x7e,0xf1,0x37,0xb6,0xb4,0xf6,0x6d,
|
||||
0x86,0x32,0xfc,0x1f,0x5e,0x1d,0x1e,0x50};
|
||||
|
||||
static AES_PRNG_MCT aes_256_mct_tv = {
|
||||
/* DT */
|
||||
{0x31,0x6e,0x35,0x9a,0xb1,0x44,0xf0,0xee,
|
||||
0x62,0x6d,0x04,0x46,0xe0,0xa3,0x92,0x4c},
|
||||
/* V */
|
||||
{0x4f,0xcd,0xc1,0x87,0x82,0x1f,0x4d,0xa1,
|
||||
0x3e,0x0e,0x56,0x44,0x59,0xe8,0x83,0xca},
|
||||
/* R */
|
||||
{0xc8,0x87,0xc2,0x61,0x5b,0xd0,0xb9,0xe1,
|
||||
0xe7,0xf3,0x8b,0xd7,0x5b,0xd5,0xf1,0x8d}
|
||||
};
|
||||
|
||||
static void dump(const unsigned char *b,int n)
|
||||
{
|
||||
while(n-- > 0)
|
||||
{
|
||||
printf(" %02x",*b++);
|
||||
}
|
||||
}
|
||||
|
||||
static void compare(const unsigned char *result,const unsigned char *expected,
|
||||
int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0 ; i < n ; ++i)
|
||||
if(result[i] != expected[i])
|
||||
{
|
||||
puts("Random test failed, got:");
|
||||
dump(result,n);
|
||||
puts("\n expected:");
|
||||
dump(expected,n);
|
||||
putchar('\n');
|
||||
EXIT(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void run_test(unsigned char *key, int keylen, AES_PRNG_MCT *tv)
|
||||
{
|
||||
unsigned char buf[16], dt[16];
|
||||
int i, j;
|
||||
FIPS_rand_reset();
|
||||
FIPS_rand_test_mode();
|
||||
FIPS_rand_set_key(key, keylen);
|
||||
FIPS_rand_seed(tv->V, 16);
|
||||
memcpy(dt, tv->DT, 16);
|
||||
for (i = 0; i < 10000; i++)
|
||||
{
|
||||
FIPS_rand_set_dt(dt);
|
||||
FIPS_rand_bytes(buf, 16);
|
||||
/* Increment DT */
|
||||
for (j = 15; j >= 0; j--)
|
||||
{
|
||||
dt[j]++;
|
||||
if (dt[j])
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
compare(buf,tv->R, 16);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
fips_set_error_print();
|
||||
run_test(aes_128_mct_key, 16, &aes_128_mct_tv);
|
||||
printf("FIPS PRNG test 1 done\n");
|
||||
run_test(aes_192_mct_key, 24, &aes_192_mct_tv);
|
||||
printf("FIPS PRNG test 2 done\n");
|
||||
run_test(aes_256_mct_key, 32, &aes_256_mct_tv);
|
||||
printf("FIPS PRNG test 3 done\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
227
fips/rand/fips_rngvs.c
Normal file
227
fips/rand/fips_rngvs.c
Normal file
@ -0,0 +1,227 @@
|
||||
/*
|
||||
* Crude test driver for processing the VST and MCT testvector files
|
||||
* generated by the CMVP RNGVS product.
|
||||
*
|
||||
* Note the input files are assumed to have a _very_ specific format
|
||||
* as described in the NIST document "The Random Number Generator
|
||||
* Validation System (RNGVS)", May 25, 2004.
|
||||
*
|
||||
*/
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#ifndef OPENSSL_FIPS
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
printf("No FIPS RNG support\n");
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/dsa.h>
|
||||
#include <openssl/fips.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/fips_rand.h>
|
||||
#include <openssl/x509v3.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "fips_utl.h"
|
||||
|
||||
static void vst()
|
||||
{
|
||||
unsigned char *key = NULL;
|
||||
unsigned char *v = NULL;
|
||||
unsigned char *dt = NULL;
|
||||
unsigned char ret[16];
|
||||
char buf[1024];
|
||||
char lbuf[1024];
|
||||
char *keyword, *value;
|
||||
long i, keylen;
|
||||
|
||||
keylen = 0;
|
||||
|
||||
while(fgets(buf,sizeof buf,stdin) != NULL)
|
||||
{
|
||||
fputs(buf,stdout);
|
||||
if(!strncmp(buf,"[AES 128-Key]", 13))
|
||||
keylen = 16;
|
||||
else if(!strncmp(buf,"[AES 192-Key]", 13))
|
||||
keylen = 24;
|
||||
else if(!strncmp(buf,"[AES 256-Key]", 13))
|
||||
keylen = 32;
|
||||
if (!parse_line(&keyword, &value, lbuf, buf))
|
||||
continue;
|
||||
if(!strcmp(keyword,"Key"))
|
||||
{
|
||||
key=hex2bin_m(value,&i);
|
||||
if (i != keylen)
|
||||
{
|
||||
fprintf(stderr, "Invalid key length, expecting %ld\n", keylen);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if(!strcmp(keyword,"DT"))
|
||||
{
|
||||
dt=hex2bin_m(value,&i);
|
||||
if (i != 16)
|
||||
{
|
||||
fprintf(stderr, "Invalid DT length\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if(!strcmp(keyword,"V"))
|
||||
{
|
||||
v=hex2bin_m(value,&i);
|
||||
if (i != 16)
|
||||
{
|
||||
fprintf(stderr, "Invalid V length\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!key || !dt)
|
||||
{
|
||||
fprintf(stderr, "Missing key or DT\n");
|
||||
return;
|
||||
}
|
||||
|
||||
FIPS_rand_set_key(key, keylen);
|
||||
FIPS_rand_seed(v,16);
|
||||
FIPS_rand_set_dt(dt);
|
||||
if (FIPS_rand_bytes(ret,16) <= 0)
|
||||
{
|
||||
fprintf(stderr, "Error getting PRNG value\n");
|
||||
return;
|
||||
}
|
||||
|
||||
pv("R",ret,16);
|
||||
OPENSSL_free(key);
|
||||
key = NULL;
|
||||
OPENSSL_free(dt);
|
||||
dt = NULL;
|
||||
OPENSSL_free(v);
|
||||
v = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void mct()
|
||||
{
|
||||
unsigned char *key = NULL;
|
||||
unsigned char *v = NULL;
|
||||
unsigned char *dt = NULL;
|
||||
unsigned char ret[16];
|
||||
char buf[1024];
|
||||
char lbuf[1024];
|
||||
char *keyword, *value;
|
||||
long i, keylen;
|
||||
int j;
|
||||
|
||||
keylen = 0;
|
||||
|
||||
while(fgets(buf,sizeof buf,stdin) != NULL)
|
||||
{
|
||||
fputs(buf,stdout);
|
||||
if(!strncmp(buf,"[AES 128-Key]", 13))
|
||||
keylen = 16;
|
||||
else if(!strncmp(buf,"[AES 192-Key]", 13))
|
||||
keylen = 24;
|
||||
else if(!strncmp(buf,"[AES 256-Key]", 13))
|
||||
keylen = 32;
|
||||
if (!parse_line(&keyword, &value, lbuf, buf))
|
||||
continue;
|
||||
if(!strcmp(keyword,"Key"))
|
||||
{
|
||||
key=hex2bin_m(value,&i);
|
||||
if (i != keylen)
|
||||
{
|
||||
fprintf(stderr, "Invalid key length, expecting %ld\n", keylen);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if(!strcmp(keyword,"DT"))
|
||||
{
|
||||
dt=hex2bin_m(value,&i);
|
||||
if (i != 16)
|
||||
{
|
||||
fprintf(stderr, "Invalid DT length\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if(!strcmp(keyword,"V"))
|
||||
{
|
||||
v=hex2bin_m(value,&i);
|
||||
if (i != 16)
|
||||
{
|
||||
fprintf(stderr, "Invalid V length\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!key || !dt)
|
||||
{
|
||||
fprintf(stderr, "Missing key or DT\n");
|
||||
return;
|
||||
}
|
||||
|
||||
FIPS_rand_set_key(key, keylen);
|
||||
FIPS_rand_seed(v,16);
|
||||
for (i = 0; i < 10000; i++)
|
||||
{
|
||||
FIPS_rand_set_dt(dt);
|
||||
if (FIPS_rand_bytes(ret,16) <= 0)
|
||||
{
|
||||
fprintf(stderr, "Error getting PRNG value\n");
|
||||
return;
|
||||
}
|
||||
/* Increment DT */
|
||||
for (j = 15; j >= 0; j--)
|
||||
{
|
||||
dt[j]++;
|
||||
if (dt[j])
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pv("R",ret,16);
|
||||
OPENSSL_free(key);
|
||||
key = NULL;
|
||||
OPENSSL_free(dt);
|
||||
dt = NULL;
|
||||
OPENSSL_free(v);
|
||||
v = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc,char **argv)
|
||||
{
|
||||
if(argc != 2)
|
||||
{
|
||||
fprintf(stderr,"%s [mct|vst]\n",argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
fips_set_error_print();
|
||||
if(!FIPS_mode_set(1))
|
||||
exit(1);
|
||||
FIPS_rand_reset();
|
||||
if (!FIPS_rand_test_mode())
|
||||
{
|
||||
fprintf(stderr, "Error setting PRNG test mode\n");
|
||||
exit(1);
|
||||
}
|
||||
if(!strcmp(argv[1],"mct"))
|
||||
mct();
|
||||
else if(!strcmp(argv[1],"vst"))
|
||||
vst();
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"Don't know how to %s.\n",argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
101
fips/rsa/fips_rsa_lib.c
Normal file
101
fips/rsa/fips_rsa_lib.c
Normal file
@ -0,0 +1,101 @@
|
||||
/* fips_rsa_sign.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2007.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2007 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
/* Minimal FIPS versions of FIPS_rsa_new() and FIPS_rsa_free: to
|
||||
* reduce external dependencies.
|
||||
*/
|
||||
|
||||
RSA *FIPS_rsa_new(void)
|
||||
{
|
||||
RSA *ret;
|
||||
ret = OPENSSL_malloc(sizeof(RSA));
|
||||
if (!ret)
|
||||
return NULL;
|
||||
memset(ret, 0, sizeof(RSA));
|
||||
ret->meth = RSA_PKCS1_SSLeay();
|
||||
if (ret->meth->init)
|
||||
ret->meth->init(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void FIPS_rsa_free(RSA *r)
|
||||
{
|
||||
if (!r)
|
||||
return;
|
||||
if (r->meth->finish)
|
||||
r->meth->finish(r);
|
||||
if (r->n != NULL) BN_clear_free(r->n);
|
||||
if (r->e != NULL) BN_clear_free(r->e);
|
||||
if (r->d != NULL) BN_clear_free(r->d);
|
||||
if (r->p != NULL) BN_clear_free(r->p);
|
||||
if (r->q != NULL) BN_clear_free(r->q);
|
||||
if (r->dmp1 != NULL) BN_clear_free(r->dmp1);
|
||||
if (r->dmq1 != NULL) BN_clear_free(r->dmq1);
|
||||
if (r->iqmp != NULL) BN_clear_free(r->iqmp);
|
||||
if (r->blinding != NULL) BN_BLINDING_free(r->blinding);
|
||||
if (r->mt_blinding != NULL) BN_BLINDING_free(r->mt_blinding);
|
||||
if (r->bignum_data != NULL) OPENSSL_free_locked(r->bignum_data);
|
||||
OPENSSL_free(r);
|
||||
}
|
||||
|
434
fips/rsa/fips_rsa_selftest.c
Normal file
434
fips/rsa/fips_rsa_selftest.c
Normal file
@ -0,0 +1,434 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2003-2007 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#define OPENSSL_FIPS_EVP
|
||||
|
||||
#include <string.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/fips.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
|
||||
static unsigned char n[] =
|
||||
"\x00\xBB\xF8\x2F\x09\x06\x82\xCE\x9C\x23\x38\xAC\x2B\x9D\xA8\x71"
|
||||
"\xF7\x36\x8D\x07\xEE\xD4\x10\x43\xA4\x40\xD6\xB6\xF0\x74\x54\xF5"
|
||||
"\x1F\xB8\xDF\xBA\xAF\x03\x5C\x02\xAB\x61\xEA\x48\xCE\xEB\x6F\xCD"
|
||||
"\x48\x76\xED\x52\x0D\x60\xE1\xEC\x46\x19\x71\x9D\x8A\x5B\x8B\x80"
|
||||
"\x7F\xAF\xB8\xE0\xA3\xDF\xC7\x37\x72\x3E\xE6\xB4\xB7\xD9\x3A\x25"
|
||||
"\x84\xEE\x6A\x64\x9D\x06\x09\x53\x74\x88\x34\xB2\x45\x45\x98\x39"
|
||||
"\x4E\xE0\xAA\xB1\x2D\x7B\x61\xA5\x1F\x52\x7A\x9A\x41\xF6\xC1\x68"
|
||||
"\x7F\xE2\x53\x72\x98\xCA\x2A\x8F\x59\x46\xF8\xE5\xFD\x09\x1D\xBD"
|
||||
"\xCB";
|
||||
|
||||
|
||||
static int setrsakey(RSA *key)
|
||||
{
|
||||
static const unsigned char e[] = "\x11";
|
||||
|
||||
static const unsigned char d[] =
|
||||
"\x00\xA5\xDA\xFC\x53\x41\xFA\xF2\x89\xC4\xB9\x88\xDB\x30\xC1\xCD"
|
||||
"\xF8\x3F\x31\x25\x1E\x06\x68\xB4\x27\x84\x81\x38\x01\x57\x96\x41"
|
||||
"\xB2\x94\x10\xB3\xC7\x99\x8D\x6B\xC4\x65\x74\x5E\x5C\x39\x26\x69"
|
||||
"\xD6\x87\x0D\xA2\xC0\x82\xA9\x39\xE3\x7F\xDC\xB8\x2E\xC9\x3E\xDA"
|
||||
"\xC9\x7F\xF3\xAD\x59\x50\xAC\xCF\xBC\x11\x1C\x76\xF1\xA9\x52\x94"
|
||||
"\x44\xE5\x6A\xAF\x68\xC5\x6C\x09\x2C\xD3\x8D\xC3\xBE\xF5\xD2\x0A"
|
||||
"\x93\x99\x26\xED\x4F\x74\xA1\x3E\xDD\xFB\xE1\xA1\xCE\xCC\x48\x94"
|
||||
"\xAF\x94\x28\xC2\xB7\xB8\x88\x3F\xE4\x46\x3A\x4B\xC8\x5B\x1C\xB3"
|
||||
"\xC1";
|
||||
|
||||
static const unsigned char p[] =
|
||||
"\x00\xEE\xCF\xAE\x81\xB1\xB9\xB3\xC9\x08\x81\x0B\x10\xA1\xB5\x60"
|
||||
"\x01\x99\xEB\x9F\x44\xAE\xF4\xFD\xA4\x93\xB8\x1A\x9E\x3D\x84\xF6"
|
||||
"\x32\x12\x4E\xF0\x23\x6E\x5D\x1E\x3B\x7E\x28\xFA\xE7\xAA\x04\x0A"
|
||||
"\x2D\x5B\x25\x21\x76\x45\x9D\x1F\x39\x75\x41\xBA\x2A\x58\xFB\x65"
|
||||
"\x99";
|
||||
|
||||
static const unsigned char q[] =
|
||||
"\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9"
|
||||
"\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5A\x0F\x20\x35\x02\x8B\x9D"
|
||||
"\x86\x98\x40\xB4\x16\x66\xB4\x2E\x92\xEA\x0D\xA3\xB4\x32\x04\xB5"
|
||||
"\xCF\xCE\x33\x52\x52\x4D\x04\x16\xA5\xA4\x41\xE7\x00\xAF\x46\x15"
|
||||
"\x03";
|
||||
|
||||
static const unsigned char dmp1[] =
|
||||
"\x54\x49\x4C\xA6\x3E\xBA\x03\x37\xE4\xE2\x40\x23\xFC\xD6\x9A\x5A"
|
||||
"\xEB\x07\xDD\xDC\x01\x83\xA4\xD0\xAC\x9B\x54\xB0\x51\xF2\xB1\x3E"
|
||||
"\xD9\x49\x09\x75\xEA\xB7\x74\x14\xFF\x59\xC1\xF7\x69\x2E\x9A\x2E"
|
||||
"\x20\x2B\x38\xFC\x91\x0A\x47\x41\x74\xAD\xC9\x3C\x1F\x67\xC9\x81";
|
||||
|
||||
static const unsigned char dmq1[] =
|
||||
"\x47\x1E\x02\x90\xFF\x0A\xF0\x75\x03\x51\xB7\xF8\x78\x86\x4C\xA9"
|
||||
"\x61\xAD\xBD\x3A\x8A\x7E\x99\x1C\x5C\x05\x56\xA9\x4C\x31\x46\xA7"
|
||||
"\xF9\x80\x3F\x8F\x6F\x8A\xE3\x42\xE9\x31\xFD\x8A\xE4\x7A\x22\x0D"
|
||||
"\x1B\x99\xA4\x95\x84\x98\x07\xFE\x39\xF9\x24\x5A\x98\x36\xDA\x3D";
|
||||
|
||||
static const unsigned char iqmp[] =
|
||||
"\x00\xB0\x6C\x4F\xDA\xBB\x63\x01\x19\x8D\x26\x5B\xDB\xAE\x94\x23"
|
||||
"\xB3\x80\xF2\x71\xF7\x34\x53\x88\x50\x93\x07\x7F\xCD\x39\xE2\x11"
|
||||
"\x9F\xC9\x86\x32\x15\x4F\x58\x83\xB1\x67\xA9\x67\xBF\x40\x2B\x4E"
|
||||
"\x9E\x2E\x0F\x96\x56\xE6\x98\xEA\x36\x66\xED\xFB\x25\x79\x80\x39"
|
||||
"\xF7";
|
||||
|
||||
key->n = BN_bin2bn(n, sizeof(n)-1, key->n);
|
||||
key->e = BN_bin2bn(e, sizeof(e)-1, key->e);
|
||||
key->d = BN_bin2bn(d, sizeof(d)-1, key->d);
|
||||
key->p = BN_bin2bn(p, sizeof(p)-1, key->p);
|
||||
key->q = BN_bin2bn(q, sizeof(q)-1, key->q);
|
||||
key->dmp1 = BN_bin2bn(dmp1, sizeof(dmp1)-1, key->dmp1);
|
||||
key->dmq1 = BN_bin2bn(dmq1, sizeof(dmq1)-1, key->dmq1);
|
||||
key->iqmp = BN_bin2bn(iqmp, sizeof(iqmp)-1, key->iqmp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void FIPS_corrupt_rsa()
|
||||
{
|
||||
n[0]++;
|
||||
}
|
||||
|
||||
/* Known Answer Test (KAT) data for the above RSA private key signing
|
||||
* kat_tbs.
|
||||
*/
|
||||
|
||||
static const unsigned char kat_tbs[] = "OpenSSL FIPS 140-2 Public Key RSA KAT";
|
||||
|
||||
static const unsigned char kat_RSA_PSS_SHA1[] = {
|
||||
0x2D, 0xAF, 0x6E, 0xC2, 0x98, 0xFB, 0x8A, 0xA1, 0xB9, 0x46, 0xDA, 0x0F,
|
||||
0x01, 0x1E, 0x37, 0x93, 0xC2, 0x55, 0x27, 0xE4, 0x1D, 0xD2, 0x90, 0xBB,
|
||||
0xF4, 0xBF, 0x4A, 0x74, 0x39, 0x51, 0xBB, 0xE8, 0x0C, 0xB7, 0xF8, 0xD3,
|
||||
0xD1, 0xDF, 0xE7, 0xBE, 0x80, 0x05, 0xC3, 0xB5, 0xC7, 0x83, 0xD5, 0x4C,
|
||||
0x7F, 0x49, 0xFB, 0x3F, 0x29, 0x9B, 0xE1, 0x12, 0x51, 0x60, 0xD0, 0xA7,
|
||||
0x0D, 0xA9, 0x28, 0x56, 0x73, 0xD9, 0x07, 0xE3, 0x5E, 0x3F, 0x9B, 0xF5,
|
||||
0xB6, 0xF3, 0xF2, 0x5E, 0x74, 0xC9, 0x83, 0x81, 0x47, 0xF0, 0xC5, 0x45,
|
||||
0x0A, 0xE9, 0x8E, 0x38, 0xD7, 0x18, 0xC6, 0x2A, 0x0F, 0xF8, 0xB7, 0x31,
|
||||
0xD6, 0x55, 0xE4, 0x66, 0x78, 0x81, 0xD4, 0xE6, 0xDB, 0x9F, 0xBA, 0xE8,
|
||||
0x23, 0xB5, 0x7F, 0xDC, 0x08, 0xEA, 0xD5, 0x26, 0x1E, 0x20, 0x25, 0x84,
|
||||
0x26, 0xC6, 0x79, 0xC9, 0x9B, 0x3D, 0x7E, 0xA9
|
||||
};
|
||||
|
||||
static const unsigned char kat_RSA_PSS_SHA224[] = {
|
||||
0x39, 0x4A, 0x6A, 0x20, 0xBC, 0xE9, 0x33, 0xED, 0xEF, 0xC5, 0x58, 0xA7,
|
||||
0xFE, 0x81, 0xC4, 0x36, 0x50, 0x9A, 0x2C, 0x82, 0x98, 0x08, 0x95, 0xFA,
|
||||
0xB1, 0x9E, 0xD2, 0x55, 0x61, 0x87, 0x21, 0x59, 0x87, 0x7B, 0x1F, 0x57,
|
||||
0x30, 0x9D, 0x0D, 0x4A, 0x06, 0xEB, 0x52, 0x37, 0x55, 0x54, 0x1C, 0x89,
|
||||
0x83, 0x75, 0x59, 0x65, 0x64, 0x90, 0x2E, 0x16, 0xCC, 0x86, 0x05, 0xEE,
|
||||
0xB1, 0xE6, 0x7B, 0xBA, 0x16, 0x75, 0x0D, 0x0C, 0x64, 0x0B, 0xAB, 0x22,
|
||||
0x15, 0x78, 0x6B, 0x6F, 0xA4, 0xFB, 0x77, 0x40, 0x64, 0x62, 0xD1, 0xB5,
|
||||
0x37, 0x1E, 0xE0, 0x3D, 0xA8, 0xF9, 0xD2, 0xBD, 0xAA, 0x38, 0x24, 0x49,
|
||||
0x58, 0xD2, 0x74, 0x85, 0xF4, 0xB5, 0x93, 0x8E, 0xF5, 0x03, 0xEA, 0x2D,
|
||||
0xC8, 0x52, 0xFA, 0xCF, 0x7E, 0x35, 0xB0, 0x6A, 0xAF, 0x95, 0xC0, 0x00,
|
||||
0x54, 0x76, 0x3D, 0x0C, 0x9C, 0xB2, 0xEE, 0xC0
|
||||
};
|
||||
|
||||
static const unsigned char kat_RSA_PSS_SHA256[] = {
|
||||
0x6D, 0x3D, 0xBE, 0x8F, 0x60, 0x6D, 0x25, 0x14, 0xF0, 0x31, 0xE3, 0x89,
|
||||
0x00, 0x97, 0xFA, 0x99, 0x71, 0x28, 0xE5, 0x10, 0x25, 0x9A, 0xF3, 0x8F,
|
||||
0x7B, 0xC5, 0xA8, 0x4A, 0x74, 0x51, 0x36, 0xE2, 0x8D, 0x7D, 0x73, 0x28,
|
||||
0xC1, 0x77, 0xC6, 0x27, 0x97, 0x00, 0x8B, 0x00, 0xA3, 0x96, 0x73, 0x4E,
|
||||
0x7D, 0x2E, 0x2C, 0x34, 0x68, 0x8C, 0x8E, 0xDF, 0x9D, 0x49, 0x47, 0x05,
|
||||
0xAB, 0xF5, 0x01, 0xD6, 0x81, 0x47, 0x70, 0xF5, 0x1D, 0x6D, 0x26, 0xBA,
|
||||
0x2F, 0x7A, 0x54, 0x53, 0x4E, 0xED, 0x71, 0xD9, 0x5A, 0xF3, 0xDA, 0xB6,
|
||||
0x0B, 0x47, 0x34, 0xAF, 0x90, 0xDC, 0xC8, 0xD9, 0x6F, 0x56, 0xCD, 0x9F,
|
||||
0x21, 0xB7, 0x7E, 0xAD, 0x7C, 0x2F, 0x75, 0x50, 0x47, 0x12, 0xE4, 0x6D,
|
||||
0x5F, 0xB7, 0x01, 0xDF, 0xC3, 0x11, 0x6C, 0xA9, 0x9E, 0x49, 0xB9, 0xF6,
|
||||
0x72, 0xF4, 0xF6, 0xEF, 0x88, 0x1E, 0x2D, 0x1C
|
||||
};
|
||||
|
||||
static const unsigned char kat_RSA_PSS_SHA384[] = {
|
||||
0x40, 0xFB, 0xA1, 0x21, 0xF4, 0xB2, 0x40, 0x9A, 0xB4, 0x31, 0xA8, 0xF2,
|
||||
0xEC, 0x1C, 0xC4, 0xC8, 0x7C, 0x22, 0x65, 0x9C, 0x57, 0x45, 0xCD, 0x5E,
|
||||
0x86, 0x00, 0xF7, 0x25, 0x78, 0xDE, 0xDC, 0x7A, 0x71, 0x44, 0x9A, 0xCD,
|
||||
0xAA, 0x25, 0xF4, 0xB2, 0xFC, 0xF0, 0x75, 0xD9, 0x2F, 0x78, 0x23, 0x7F,
|
||||
0x6F, 0x02, 0xEF, 0xC1, 0xAF, 0xA6, 0x28, 0x16, 0x31, 0xDC, 0x42, 0x6C,
|
||||
0xB2, 0x44, 0xE5, 0x4D, 0x66, 0xA2, 0xE6, 0x71, 0xF3, 0xAC, 0x4F, 0xFB,
|
||||
0x91, 0xCA, 0xF5, 0x70, 0xEF, 0x6B, 0x9D, 0xA4, 0xEF, 0xD9, 0x3D, 0x2F,
|
||||
0x3A, 0xBE, 0x89, 0x38, 0x59, 0x01, 0xBA, 0xDA, 0x32, 0xAD, 0x42, 0x89,
|
||||
0x98, 0x8B, 0x39, 0x44, 0xF0, 0xFC, 0x38, 0xAC, 0x87, 0x1F, 0xCA, 0x6F,
|
||||
0x48, 0xF6, 0xAE, 0xD7, 0x45, 0xEE, 0xAE, 0x88, 0x0E, 0x60, 0xF4, 0x55,
|
||||
0x48, 0x44, 0xEE, 0x1F, 0x90, 0x18, 0x4B, 0xF1
|
||||
};
|
||||
|
||||
static const unsigned char kat_RSA_PSS_SHA512[] = {
|
||||
0x07, 0x1E, 0xD8, 0xD5, 0x05, 0xE8, 0xE6, 0xE6, 0x57, 0xAE, 0x63, 0x8C,
|
||||
0xC6, 0x83, 0xB7, 0xA0, 0x59, 0xBB, 0xF2, 0xC6, 0x8F, 0x12, 0x53, 0x9A,
|
||||
0x9B, 0x54, 0x9E, 0xB3, 0xC1, 0x1D, 0x23, 0x4D, 0x51, 0xED, 0x9E, 0xDD,
|
||||
0x4B, 0xF3, 0x46, 0x9B, 0x6B, 0xF6, 0x7C, 0x24, 0x60, 0x79, 0x23, 0x39,
|
||||
0x01, 0x1C, 0x51, 0xCB, 0xD8, 0xE9, 0x9A, 0x01, 0x67, 0x5F, 0xFE, 0xD7,
|
||||
0x7C, 0xE3, 0x7F, 0xED, 0xDB, 0x87, 0xBB, 0xF0, 0x3D, 0x78, 0x55, 0x61,
|
||||
0x57, 0xE3, 0x0F, 0xE3, 0xD2, 0x9D, 0x0C, 0x2A, 0x20, 0xB0, 0x85, 0x13,
|
||||
0xC5, 0x47, 0x34, 0x0D, 0x32, 0x15, 0xC8, 0xAE, 0x9A, 0x6A, 0x39, 0x63,
|
||||
0x2D, 0x60, 0xF5, 0x4C, 0xDF, 0x8A, 0x48, 0x4B, 0xBF, 0xF4, 0xA8, 0xFE,
|
||||
0x76, 0xF2, 0x32, 0x1B, 0x9C, 0x7C, 0xCA, 0xFE, 0x7F, 0x80, 0xC2, 0x88,
|
||||
0x5C, 0x97, 0x70, 0xB4, 0x26, 0xC9, 0x14, 0x8B
|
||||
};
|
||||
|
||||
static const unsigned char kat_RSA_SHA1[] = {
|
||||
0x71, 0xEE, 0x1A, 0xC0, 0xFE, 0x01, 0x93, 0x54, 0x79, 0x5C, 0xF2, 0x4C,
|
||||
0x4A, 0xFD, 0x1A, 0x05, 0x8F, 0x64, 0xB1, 0x6D, 0x61, 0x33, 0x8D, 0x9B,
|
||||
0xE7, 0xFD, 0x60, 0xA3, 0x83, 0xB5, 0xA3, 0x51, 0x55, 0x77, 0x90, 0xCF,
|
||||
0xDC, 0x22, 0x37, 0x8E, 0xD0, 0xE1, 0xAE, 0x09, 0xE3, 0x3D, 0x1E, 0xF8,
|
||||
0x80, 0xD1, 0x8B, 0xC2, 0xEC, 0x0A, 0xD7, 0x6B, 0x88, 0x8B, 0x8B, 0xA1,
|
||||
0x20, 0x22, 0xBE, 0x59, 0x5B, 0xE0, 0x23, 0x24, 0xA1, 0x49, 0x30, 0xBA,
|
||||
0xA9, 0x9E, 0xE8, 0xB1, 0x8A, 0x62, 0x16, 0xBF, 0x4E, 0xCA, 0x2E, 0x4E,
|
||||
0xBC, 0x29, 0xA8, 0x67, 0x13, 0xB7, 0x9F, 0x1D, 0x04, 0x44, 0xE5, 0x5F,
|
||||
0x35, 0x07, 0x11, 0xBC, 0xED, 0x19, 0x37, 0x21, 0xCF, 0x23, 0x48, 0x1F,
|
||||
0x72, 0x05, 0xDE, 0xE6, 0xE8, 0x7F, 0x33, 0x8A, 0x76, 0x4B, 0x2F, 0x95,
|
||||
0xDF, 0xF1, 0x5F, 0x84, 0x80, 0xD9, 0x46, 0xB4
|
||||
};
|
||||
|
||||
static const unsigned char kat_RSA_SHA224[] = {
|
||||
0x62, 0xAA, 0x79, 0xA9, 0x18, 0x0E, 0x5F, 0x8C, 0xBB, 0xB7, 0x15, 0xF9,
|
||||
0x25, 0xBB, 0xFA, 0xD4, 0x3A, 0x34, 0xED, 0x9E, 0xA0, 0xA9, 0x18, 0x8D,
|
||||
0x5B, 0x55, 0x9A, 0x7E, 0x1E, 0x08, 0x08, 0x60, 0xC5, 0x1A, 0xC5, 0x89,
|
||||
0x08, 0xE2, 0x1B, 0xBD, 0x62, 0x50, 0x17, 0x76, 0x30, 0x2C, 0x9E, 0xCD,
|
||||
0xA4, 0x02, 0xAD, 0xB1, 0x6D, 0x44, 0x6D, 0xD5, 0xC6, 0x45, 0x41, 0xE5,
|
||||
0xEE, 0x1F, 0x8D, 0x7E, 0x08, 0x16, 0xA6, 0xE1, 0x5E, 0x0B, 0xA9, 0xCC,
|
||||
0xDB, 0x59, 0x55, 0x87, 0x09, 0x25, 0x70, 0x86, 0x84, 0x02, 0xC6, 0x3B,
|
||||
0x0B, 0x44, 0x4C, 0x46, 0x95, 0xF4, 0xF8, 0x5A, 0x91, 0x28, 0x3E, 0xB2,
|
||||
0x58, 0x2E, 0x06, 0x45, 0x49, 0xE0, 0x92, 0xE2, 0xC0, 0x66, 0xE6, 0x35,
|
||||
0xD9, 0x79, 0x7F, 0x17, 0x5E, 0x02, 0x73, 0x04, 0x77, 0x82, 0xE6, 0xDC,
|
||||
0x40, 0x21, 0x89, 0x8B, 0x37, 0x3E, 0x1E, 0x8D
|
||||
};
|
||||
|
||||
static const unsigned char kat_RSA_SHA256[] = {
|
||||
0x0D, 0x55, 0xE2, 0xAA, 0x81, 0xDB, 0x8E, 0x82, 0x05, 0x17, 0xA5, 0x23,
|
||||
0xE7, 0x3B, 0x1D, 0xAF, 0xFB, 0x8C, 0xD0, 0x81, 0x20, 0x7B, 0xAA, 0x23,
|
||||
0x92, 0x87, 0x8C, 0xD1, 0x53, 0x85, 0x16, 0xDC, 0xBE, 0xAD, 0x6F, 0x35,
|
||||
0x98, 0x2D, 0x69, 0x84, 0xBF, 0xD9, 0x8A, 0x01, 0x17, 0x58, 0xB2, 0x6E,
|
||||
0x2C, 0x44, 0x9B, 0x90, 0xF1, 0xFB, 0x51, 0xE8, 0x6A, 0x90, 0x2D, 0x18,
|
||||
0x0E, 0xC0, 0x90, 0x10, 0x24, 0xA9, 0x1D, 0xB3, 0x58, 0x7A, 0x91, 0x30,
|
||||
0xBE, 0x22, 0xC7, 0xD3, 0xEC, 0xC3, 0x09, 0x5D, 0xBF, 0xE2, 0x80, 0x3A,
|
||||
0x7C, 0x85, 0xB4, 0xBC, 0xD1, 0xE9, 0xF0, 0x5C, 0xDE, 0x81, 0xA6, 0x38,
|
||||
0xB8, 0x42, 0xBB, 0x86, 0xC5, 0x9D, 0xCE, 0x7C, 0x2C, 0xEE, 0xD1, 0xDA,
|
||||
0x27, 0x48, 0x2B, 0xF5, 0xAB, 0xB9, 0xF7, 0x80, 0xD1, 0x90, 0x27, 0x90,
|
||||
0xBD, 0x44, 0x97, 0x60, 0xCD, 0x57, 0xC0, 0x7A
|
||||
};
|
||||
|
||||
static const unsigned char kat_RSA_SHA384[] = {
|
||||
0x1D, 0xE3, 0x6A, 0xDD, 0x27, 0x4C, 0xC0, 0xA5, 0x27, 0xEF, 0xE6, 0x1F,
|
||||
0xD2, 0x91, 0x68, 0x59, 0x04, 0xAE, 0xBD, 0x99, 0x63, 0x56, 0x47, 0xC7,
|
||||
0x6F, 0x22, 0x16, 0x48, 0xD0, 0xF9, 0x18, 0xA9, 0xCA, 0xFA, 0x5D, 0x5C,
|
||||
0xA7, 0x65, 0x52, 0x8A, 0xC8, 0x44, 0x7E, 0x86, 0x5D, 0xA9, 0xA6, 0x55,
|
||||
0x65, 0x3E, 0xD9, 0x2D, 0x02, 0x38, 0xA8, 0x79, 0x28, 0x7F, 0xB6, 0xCF,
|
||||
0x82, 0xDD, 0x7E, 0x55, 0xE1, 0xB1, 0xBC, 0xE2, 0x19, 0x2B, 0x30, 0xC2,
|
||||
0x1B, 0x2B, 0xB0, 0x82, 0x46, 0xAC, 0x4B, 0xD1, 0xE2, 0x7D, 0xEB, 0x8C,
|
||||
0xFF, 0x95, 0xE9, 0x6A, 0x1C, 0x3D, 0x4D, 0xBF, 0x8F, 0x8B, 0x9C, 0xCD,
|
||||
0xEA, 0x85, 0xEE, 0x00, 0xDC, 0x1C, 0xA7, 0xEB, 0xD0, 0x8F, 0x99, 0xF1,
|
||||
0x16, 0x28, 0x24, 0x64, 0x04, 0x39, 0x2D, 0x58, 0x1E, 0x37, 0xDC, 0x04,
|
||||
0xBD, 0x31, 0xA2, 0x2F, 0xB3, 0x35, 0x56, 0xBF
|
||||
};
|
||||
|
||||
static const unsigned char kat_RSA_SHA512[] = {
|
||||
0x69, 0x52, 0x1B, 0x51, 0x5E, 0x06, 0xCA, 0x9B, 0x16, 0x51, 0x5D, 0xCF,
|
||||
0x49, 0x25, 0x4A, 0xA1, 0x6A, 0x77, 0x4C, 0x36, 0x40, 0xF8, 0xB2, 0x9A,
|
||||
0x15, 0xEA, 0x5C, 0xE5, 0xE6, 0x82, 0xE0, 0x86, 0x82, 0x6B, 0x32, 0xF1,
|
||||
0x04, 0xC1, 0x5A, 0x1A, 0xED, 0x1E, 0x9A, 0xB6, 0x4C, 0x54, 0x9F, 0xD8,
|
||||
0x8D, 0xCC, 0xAC, 0x8A, 0xBB, 0x9C, 0x82, 0x3F, 0xA6, 0x53, 0x62, 0xB5,
|
||||
0x80, 0xE2, 0xBC, 0xDD, 0x67, 0x2B, 0xD9, 0x3F, 0xE4, 0x75, 0x92, 0x6B,
|
||||
0xAF, 0x62, 0x7C, 0x52, 0xF0, 0xEE, 0x33, 0xDF, 0x1B, 0x1D, 0x47, 0xE6,
|
||||
0x59, 0x56, 0xA5, 0xB9, 0x5C, 0xE6, 0x77, 0x78, 0x16, 0x63, 0x84, 0x05,
|
||||
0x6F, 0x0E, 0x2B, 0x31, 0x9D, 0xF7, 0x7F, 0xB2, 0x64, 0x71, 0xE0, 0x2D,
|
||||
0x3E, 0x62, 0xCE, 0xB5, 0x3F, 0x88, 0xDF, 0x2D, 0xAB, 0x98, 0x65, 0x91,
|
||||
0xDF, 0x70, 0x14, 0xA5, 0x3F, 0x36, 0xAB, 0x84
|
||||
};
|
||||
|
||||
static const unsigned char kat_RSA_X931_SHA1[] = {
|
||||
0x86, 0xB4, 0x18, 0xBA, 0xD1, 0x80, 0xB6, 0x7C, 0x42, 0x45, 0x4D, 0xDF,
|
||||
0xE9, 0x2D, 0xE1, 0x83, 0x5F, 0xB5, 0x2F, 0xC9, 0xCD, 0xC4, 0xB2, 0x75,
|
||||
0x80, 0xA4, 0xF1, 0x4A, 0xE7, 0x83, 0x12, 0x1E, 0x1E, 0x14, 0xB8, 0xAC,
|
||||
0x35, 0xE2, 0xAA, 0x0B, 0x5C, 0xF8, 0x38, 0x4D, 0x04, 0xEE, 0xA9, 0x97,
|
||||
0x70, 0xFB, 0x5E, 0xE7, 0xB7, 0xE3, 0x62, 0x23, 0x4B, 0x38, 0xBE, 0xD6,
|
||||
0x53, 0x15, 0xF7, 0xDF, 0x87, 0xB4, 0x0E, 0xCC, 0xB1, 0x1A, 0x11, 0x19,
|
||||
0xEE, 0x51, 0xCC, 0x92, 0xDD, 0xBC, 0x63, 0x29, 0x63, 0x0C, 0x59, 0xD7,
|
||||
0x6F, 0x4C, 0x3C, 0x37, 0x5B, 0x37, 0x03, 0x61, 0x7D, 0x24, 0x1C, 0x99,
|
||||
0x48, 0xAF, 0x82, 0xFE, 0x32, 0x41, 0x9B, 0xB2, 0xDB, 0xEA, 0xED, 0x76,
|
||||
0x8E, 0x6E, 0xCA, 0x7E, 0x4E, 0x14, 0xBA, 0x30, 0x84, 0x1C, 0xB3, 0x67,
|
||||
0xA3, 0x29, 0x80, 0x70, 0x54, 0x68, 0x7D, 0x49
|
||||
};
|
||||
|
||||
static const unsigned char kat_RSA_X931_SHA256[] = {
|
||||
0x7E, 0xA2, 0x77, 0xFE, 0xB8, 0x54, 0x8A, 0xC7, 0x7F, 0x64, 0x54, 0x89,
|
||||
0xE5, 0x52, 0x15, 0x8E, 0x52, 0x96, 0x4E, 0xA6, 0x58, 0x92, 0x1C, 0xDD,
|
||||
0xEA, 0xA2, 0x2D, 0x5C, 0xD1, 0x62, 0x00, 0x49, 0x05, 0x95, 0x73, 0xCF,
|
||||
0x16, 0x76, 0x68, 0xF6, 0xC6, 0x5E, 0x80, 0xB8, 0xB8, 0x7B, 0xC8, 0x9B,
|
||||
0xC6, 0x53, 0x88, 0x26, 0x20, 0x88, 0x73, 0xB6, 0x13, 0xB8, 0xF0, 0x4B,
|
||||
0x00, 0x85, 0xF3, 0xDD, 0x07, 0x50, 0xEB, 0x20, 0xC4, 0x38, 0x0E, 0x98,
|
||||
0xAD, 0x4E, 0x49, 0x2C, 0xD7, 0x65, 0xA5, 0x19, 0x0E, 0x59, 0x01, 0xEC,
|
||||
0x7E, 0x75, 0x89, 0x69, 0x2E, 0x63, 0x76, 0x85, 0x46, 0x8D, 0xA0, 0x8C,
|
||||
0x33, 0x1D, 0x82, 0x8C, 0x03, 0xEA, 0x69, 0x88, 0x35, 0xA1, 0x42, 0xBD,
|
||||
0x21, 0xED, 0x8D, 0xBC, 0xBC, 0xDB, 0x30, 0xFF, 0x86, 0xF0, 0x5B, 0xDC,
|
||||
0xE3, 0xE2, 0xE8, 0x0A, 0x0A, 0x29, 0x94, 0x80
|
||||
};
|
||||
|
||||
static const unsigned char kat_RSA_X931_SHA384[] = {
|
||||
0x5C, 0x7D, 0x96, 0x35, 0xEC, 0x7E, 0x11, 0x38, 0xBB, 0x7B, 0xEC, 0x7B,
|
||||
0xF2, 0x82, 0x8E, 0x99, 0xBD, 0xEF, 0xD8, 0xAE, 0xD7, 0x39, 0x37, 0xCB,
|
||||
0xE6, 0x4F, 0x5E, 0x0A, 0x13, 0xE4, 0x2E, 0x40, 0xB9, 0xBE, 0x2E, 0xE3,
|
||||
0xEF, 0x78, 0x83, 0x18, 0x44, 0x35, 0x9C, 0x8E, 0xD7, 0x4A, 0x63, 0xF6,
|
||||
0x57, 0xC2, 0xB0, 0x08, 0x51, 0x73, 0xCF, 0xCA, 0x99, 0x66, 0xEE, 0x31,
|
||||
0xD8, 0x69, 0xE9, 0xAB, 0x13, 0x27, 0x7B, 0x41, 0x1E, 0x6D, 0x8D, 0xF1,
|
||||
0x3E, 0x9C, 0x35, 0x95, 0x58, 0xDD, 0x2B, 0xD5, 0xA0, 0x60, 0x41, 0x79,
|
||||
0x24, 0x22, 0xE4, 0xB7, 0xBF, 0x47, 0x53, 0xF6, 0x34, 0xD5, 0x7C, 0xFF,
|
||||
0x0E, 0x09, 0xEE, 0x2E, 0xE2, 0x37, 0xB9, 0xDE, 0xC5, 0x12, 0x44, 0x35,
|
||||
0xEF, 0x01, 0xE6, 0x5E, 0x39, 0x31, 0x2D, 0x71, 0xA5, 0xDC, 0xC6, 0x6D,
|
||||
0xE2, 0xCD, 0x85, 0xDB, 0x73, 0x82, 0x65, 0x28
|
||||
};
|
||||
|
||||
static const unsigned char kat_RSA_X931_SHA512[] = {
|
||||
0xA6, 0x65, 0xA2, 0x77, 0x4F, 0xB3, 0x86, 0xCB, 0x64, 0x3A, 0xC1, 0x63,
|
||||
0xFC, 0xA1, 0xAA, 0xCB, 0x9B, 0x79, 0xDD, 0x4B, 0xE1, 0xD9, 0xDA, 0xAC,
|
||||
0xE7, 0x47, 0x09, 0xB2, 0x11, 0x4B, 0x8A, 0xAA, 0x05, 0x9E, 0x77, 0xD7,
|
||||
0x3A, 0xBD, 0x5E, 0x53, 0x09, 0x4A, 0xE6, 0x0F, 0x5E, 0xF9, 0x14, 0x28,
|
||||
0xA0, 0x99, 0x74, 0x64, 0x70, 0x4E, 0xF2, 0xE3, 0xFA, 0xC7, 0xF8, 0xC5,
|
||||
0x6E, 0x2B, 0x79, 0x96, 0x0D, 0x0C, 0xC8, 0x10, 0x34, 0x53, 0xD2, 0xAF,
|
||||
0x17, 0x0E, 0xE0, 0xBF, 0x79, 0xF6, 0x04, 0x72, 0x10, 0xE0, 0xF6, 0xD0,
|
||||
0xCE, 0x8A, 0x6F, 0xA1, 0x95, 0x89, 0xBF, 0x58, 0x8F, 0x46, 0x5F, 0x09,
|
||||
0x9F, 0x09, 0xCA, 0x84, 0x15, 0x85, 0xE0, 0xED, 0x04, 0x2D, 0xFB, 0x7C,
|
||||
0x36, 0x35, 0x21, 0x31, 0xC3, 0xFD, 0x92, 0x42, 0x11, 0x30, 0x71, 0x1B,
|
||||
0x60, 0x83, 0x18, 0x88, 0xA3, 0xF5, 0x59, 0xC3
|
||||
};
|
||||
|
||||
|
||||
int FIPS_selftest_rsa()
|
||||
{
|
||||
int ret = 0;
|
||||
RSA *key = NULL;
|
||||
EVP_PKEY pk;
|
||||
key=FIPS_rsa_new();
|
||||
setrsakey(key);
|
||||
pk.type = EVP_PKEY_RSA;
|
||||
pk.pkey.rsa = key;
|
||||
|
||||
if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
|
||||
kat_RSA_SHA1, sizeof(kat_RSA_SHA1),
|
||||
EVP_sha1(), RSA_PKCS1_PADDING,
|
||||
"RSA SHA1 PKCS#1"))
|
||||
goto err;
|
||||
if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
|
||||
kat_RSA_SHA224, sizeof(kat_RSA_SHA224),
|
||||
EVP_sha224(), RSA_PKCS1_PADDING,
|
||||
"RSA SHA224 PKCS#1"))
|
||||
goto err;
|
||||
if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
|
||||
kat_RSA_SHA256, sizeof(kat_RSA_SHA256),
|
||||
EVP_sha256(), RSA_PKCS1_PADDING,
|
||||
"RSA SHA256 PKCS#1"))
|
||||
goto err;
|
||||
if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
|
||||
kat_RSA_SHA384, sizeof(kat_RSA_SHA384),
|
||||
EVP_sha384(), RSA_PKCS1_PADDING,
|
||||
"RSA SHA384 PKCS#1"))
|
||||
goto err;
|
||||
if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
|
||||
kat_RSA_SHA512, sizeof(kat_RSA_SHA512),
|
||||
EVP_sha512(), RSA_PKCS1_PADDING,
|
||||
"RSA SHA512 PKCS#1"))
|
||||
goto err;
|
||||
|
||||
if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
|
||||
kat_RSA_PSS_SHA1, sizeof(kat_RSA_PSS_SHA1),
|
||||
EVP_sha1(), RSA_PKCS1_PSS_PADDING,
|
||||
"RSA SHA1 PSS"))
|
||||
goto err;
|
||||
if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
|
||||
kat_RSA_PSS_SHA224, sizeof(kat_RSA_PSS_SHA224),
|
||||
EVP_sha224(), RSA_PKCS1_PSS_PADDING,
|
||||
"RSA SHA224 PSS"))
|
||||
goto err;
|
||||
if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
|
||||
kat_RSA_PSS_SHA256, sizeof(kat_RSA_PSS_SHA256),
|
||||
EVP_sha256(), RSA_PKCS1_PSS_PADDING,
|
||||
"RSA SHA256 PSS"))
|
||||
goto err;
|
||||
if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
|
||||
kat_RSA_PSS_SHA384, sizeof(kat_RSA_PSS_SHA384),
|
||||
EVP_sha384(), RSA_PKCS1_PSS_PADDING,
|
||||
"RSA SHA384 PSS"))
|
||||
goto err;
|
||||
if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
|
||||
kat_RSA_PSS_SHA512, sizeof(kat_RSA_PSS_SHA512),
|
||||
EVP_sha512(), RSA_PKCS1_PSS_PADDING,
|
||||
"RSA SHA512 PSS"))
|
||||
goto err;
|
||||
|
||||
|
||||
if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
|
||||
kat_RSA_X931_SHA1, sizeof(kat_RSA_X931_SHA1),
|
||||
EVP_sha1(), RSA_X931_PADDING,
|
||||
"RSA SHA1 X931"))
|
||||
goto err;
|
||||
/* NB: SHA224 not supported in X9.31 */
|
||||
if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
|
||||
kat_RSA_X931_SHA256, sizeof(kat_RSA_X931_SHA256),
|
||||
EVP_sha256(), RSA_X931_PADDING,
|
||||
"RSA SHA256 X931"))
|
||||
goto err;
|
||||
if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
|
||||
kat_RSA_X931_SHA384, sizeof(kat_RSA_X931_SHA384),
|
||||
EVP_sha384(), RSA_X931_PADDING,
|
||||
"RSA SHA384 X931"))
|
||||
goto err;
|
||||
if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
|
||||
kat_RSA_X931_SHA512, sizeof(kat_RSA_X931_SHA512),
|
||||
EVP_sha512(), RSA_X931_PADDING,
|
||||
"RSA SHA512 X931"))
|
||||
goto err;
|
||||
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
FIPS_rsa_free(key);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* def OPENSSL_FIPS */
|
399
fips/rsa/fips_rsa_sign.c
Normal file
399
fips/rsa/fips_rsa_sign.c
Normal file
@ -0,0 +1,399 @@
|
||||
/* fips_rsa_sign.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2007.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2007 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#define OPENSSL_FIPSEVP
|
||||
|
||||
#include <string.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
|
||||
/* FIPS versions of RSA_sign() and RSA_verify().
|
||||
* These will only have to deal with SHA* signatures and by including
|
||||
* pregenerated encodings all ASN1 dependencies can be avoided
|
||||
*/
|
||||
|
||||
/* Standard encodings including NULL parameter */
|
||||
|
||||
static const unsigned char sha1_bin[] = {
|
||||
0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05,
|
||||
0x00, 0x04, 0x14
|
||||
};
|
||||
|
||||
static const unsigned char sha224_bin[] = {
|
||||
0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
|
||||
0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c
|
||||
};
|
||||
|
||||
static const unsigned char sha256_bin[] = {
|
||||
0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
|
||||
0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
|
||||
};
|
||||
|
||||
static const unsigned char sha384_bin[] = {
|
||||
0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
|
||||
0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30
|
||||
};
|
||||
|
||||
static const unsigned char sha512_bin[] = {
|
||||
0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
|
||||
0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40
|
||||
};
|
||||
|
||||
/* Alternate encodings with absent parameters. We don't generate signature
|
||||
* using this format but do tolerate received signatures of this form.
|
||||
*/
|
||||
|
||||
static unsigned char sha1_nn_bin[] = {
|
||||
0x30, 0x1f, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04,
|
||||
0x14
|
||||
};
|
||||
|
||||
static unsigned char sha224_nn_bin[] = {
|
||||
0x30, 0x2b, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
|
||||
0x04, 0x02, 0x04, 0x04, 0x1c
|
||||
};
|
||||
|
||||
static unsigned char sha256_nn_bin[] = {
|
||||
0x30, 0x2f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
|
||||
0x04, 0x02, 0x01, 0x04, 0x20
|
||||
};
|
||||
|
||||
static unsigned char sha384_nn_bin[] = {
|
||||
0x30, 0x3f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
|
||||
0x04, 0x02, 0x02, 0x04, 0x30
|
||||
};
|
||||
|
||||
static unsigned char sha512_nn_bin[] = {
|
||||
0x30, 0x4f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
|
||||
0x04, 0x02, 0x03, 0x04, 0x40
|
||||
};
|
||||
|
||||
|
||||
static const unsigned char *fips_digestinfo_encoding(int nid, unsigned int *len)
|
||||
{
|
||||
switch (nid)
|
||||
{
|
||||
|
||||
case NID_sha1:
|
||||
*len = sizeof(sha1_bin);
|
||||
return sha1_bin;
|
||||
|
||||
case NID_sha224:
|
||||
*len = sizeof(sha224_bin);
|
||||
return sha224_bin;
|
||||
|
||||
case NID_sha256:
|
||||
*len = sizeof(sha256_bin);
|
||||
return sha256_bin;
|
||||
|
||||
case NID_sha384:
|
||||
*len = sizeof(sha384_bin);
|
||||
return sha384_bin;
|
||||
|
||||
case NID_sha512:
|
||||
*len = sizeof(sha512_bin);
|
||||
return sha512_bin;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static const unsigned char *fips_digestinfo_nn_encoding(int nid, unsigned int *len)
|
||||
{
|
||||
switch (nid)
|
||||
{
|
||||
|
||||
case NID_sha1:
|
||||
*len = sizeof(sha1_nn_bin);
|
||||
return sha1_nn_bin;
|
||||
|
||||
case NID_sha224:
|
||||
*len = sizeof(sha224_nn_bin);
|
||||
return sha224_nn_bin;
|
||||
|
||||
case NID_sha256:
|
||||
*len = sizeof(sha256_nn_bin);
|
||||
return sha256_nn_bin;
|
||||
|
||||
case NID_sha384:
|
||||
*len = sizeof(sha384_nn_bin);
|
||||
return sha384_nn_bin;
|
||||
|
||||
case NID_sha512:
|
||||
*len = sizeof(sha512_nn_bin);
|
||||
return sha512_nn_bin;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int FIPS_rsa_sign_ctx(RSA *rsa, EVP_MD_CTX *ctx,
|
||||
int rsa_pad_mode, int saltlen, const EVP_MD *mgf1Hash,
|
||||
unsigned char *sigret, unsigned int *siglen)
|
||||
{
|
||||
int i=0,j,ret=0;
|
||||
unsigned int dlen;
|
||||
const unsigned char *der;
|
||||
unsigned int m_len;
|
||||
const EVP_MD *mhash;
|
||||
int md_type;
|
||||
/* Largest DigestInfo: 19 (max encoding) + max MD */
|
||||
unsigned char tmpdinfo[19 + EVP_MAX_MD_SIZE];
|
||||
unsigned char md[EVP_MAX_MD_SIZE + 1];
|
||||
|
||||
EVP_DigestFinal_ex(ctx, md, &m_len);
|
||||
|
||||
mhash = M_EVP_MD_CTX_md(ctx);
|
||||
md_type = M_EVP_MD_type(mhash);
|
||||
|
||||
if (rsa_pad_mode == RSA_X931_PADDING)
|
||||
{
|
||||
int hash_id;
|
||||
memcpy(tmpdinfo, md, m_len);
|
||||
hash_id = RSA_X931_hash_id(md_type);
|
||||
if (hash_id == -1)
|
||||
{
|
||||
RSAerr(RSA_F_FIPS_RSA_SIGN,RSA_R_UNKNOWN_ALGORITHM_TYPE);
|
||||
return 0;
|
||||
}
|
||||
tmpdinfo[m_len] = (unsigned char)hash_id;
|
||||
i = m_len + 1;
|
||||
}
|
||||
else if (rsa_pad_mode == RSA_PKCS1_PADDING)
|
||||
{
|
||||
|
||||
der = fips_digestinfo_encoding(md_type, &dlen);
|
||||
|
||||
if (!der)
|
||||
{
|
||||
RSAerr(RSA_F_FIPS_RSA_SIGN,RSA_R_UNKNOWN_ALGORITHM_TYPE);
|
||||
return 0;
|
||||
}
|
||||
memcpy(tmpdinfo, der, dlen);
|
||||
memcpy(tmpdinfo + dlen, md, m_len);
|
||||
|
||||
i = dlen + m_len;
|
||||
|
||||
}
|
||||
else if (rsa_pad_mode == RSA_PKCS1_PSS_PADDING)
|
||||
{
|
||||
unsigned char *sbuf;
|
||||
i = RSA_size(rsa);
|
||||
sbuf = OPENSSL_malloc(RSA_size(rsa));
|
||||
if (!sbuf)
|
||||
{
|
||||
RSAerr(RSA_F_FIPS_RSA_SIGN,ERR_R_MALLOC_FAILURE);
|
||||
goto psserr;
|
||||
}
|
||||
if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa, sbuf, md, mhash,
|
||||
mgf1Hash, saltlen))
|
||||
goto psserr;
|
||||
j=rsa->meth->rsa_priv_enc(i,sbuf,sigret,rsa,RSA_NO_PADDING);
|
||||
if (j > 0)
|
||||
{
|
||||
ret=1;
|
||||
*siglen=j;
|
||||
}
|
||||
psserr:
|
||||
OPENSSL_cleanse(md,m_len);
|
||||
OPENSSL_cleanse(sbuf, i);
|
||||
OPENSSL_free(sbuf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
j=RSA_size(rsa);
|
||||
if (i > (j-RSA_PKCS1_PADDING_SIZE))
|
||||
{
|
||||
RSAerr(RSA_F_FIPS_RSA_SIGN,RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
|
||||
goto done;
|
||||
}
|
||||
/* NB: call underlying method directly to avoid FIPS blocking */
|
||||
j=rsa->meth->rsa_priv_enc(i,tmpdinfo,sigret,rsa,rsa_pad_mode);
|
||||
if (j > 0)
|
||||
{
|
||||
ret=1;
|
||||
*siglen=j;
|
||||
}
|
||||
|
||||
done:
|
||||
OPENSSL_cleanse(tmpdinfo,i);
|
||||
OPENSSL_cleanse(md,m_len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int FIPS_rsa_verify_ctx(RSA *rsa, EVP_MD_CTX *ctx,
|
||||
int rsa_pad_mode, int saltlen, const EVP_MD *mgf1Hash,
|
||||
unsigned char *sigbuf, unsigned int siglen)
|
||||
{
|
||||
int i,ret=0;
|
||||
unsigned int dlen, diglen;
|
||||
unsigned char *s;
|
||||
const unsigned char *der;
|
||||
unsigned char dig[EVP_MAX_MD_SIZE];
|
||||
const EVP_MD *mhash;
|
||||
int md_type;
|
||||
int rsa_dec_pad_mode;
|
||||
|
||||
if (siglen != (unsigned int)RSA_size(rsa))
|
||||
{
|
||||
RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_WRONG_SIGNATURE_LENGTH);
|
||||
return(0);
|
||||
}
|
||||
|
||||
mhash = M_EVP_MD_CTX_md(ctx);
|
||||
md_type = M_EVP_MD_type(mhash);
|
||||
|
||||
EVP_DigestFinal_ex(ctx, dig, &diglen);
|
||||
|
||||
s= OPENSSL_malloc((unsigned int)siglen);
|
||||
if (s == NULL)
|
||||
{
|
||||
RSAerr(RSA_F_FIPS_RSA_VERIFY,ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (rsa_pad_mode == RSA_PKCS1_PSS_PADDING)
|
||||
rsa_dec_pad_mode = RSA_NO_PADDING;
|
||||
else
|
||||
rsa_dec_pad_mode = rsa_pad_mode;
|
||||
|
||||
/* NB: call underlying method directly to avoid FIPS blocking */
|
||||
i=rsa->meth->rsa_pub_dec((int)siglen,sigbuf,s, rsa, rsa_dec_pad_mode);
|
||||
|
||||
if (i <= 0) goto err;
|
||||
|
||||
if (rsa_pad_mode == RSA_X931_PADDING)
|
||||
{
|
||||
int hash_id;
|
||||
if (i != (int)(diglen + 1))
|
||||
{
|
||||
RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
|
||||
goto err;
|
||||
}
|
||||
hash_id = RSA_X931_hash_id(md_type);
|
||||
if (hash_id == -1)
|
||||
{
|
||||
RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_UNKNOWN_ALGORITHM_TYPE);
|
||||
goto err;
|
||||
}
|
||||
if (s[diglen] != (unsigned char)hash_id)
|
||||
{
|
||||
RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
|
||||
goto err;
|
||||
}
|
||||
if (memcmp(s, dig, diglen))
|
||||
{
|
||||
RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
|
||||
goto err;
|
||||
}
|
||||
ret = 1;
|
||||
}
|
||||
else if (rsa_pad_mode == RSA_PKCS1_PADDING)
|
||||
{
|
||||
|
||||
der = fips_digestinfo_encoding(md_type, &dlen);
|
||||
|
||||
if (!der)
|
||||
{
|
||||
RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_UNKNOWN_ALGORITHM_TYPE);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Compare, DigestInfo length, DigestInfo header and finally
|
||||
* digest value itself
|
||||
*/
|
||||
|
||||
/* If length mismatch try alternate encoding */
|
||||
if (i != (int)(dlen + diglen))
|
||||
der = fips_digestinfo_nn_encoding(md_type, &dlen);
|
||||
|
||||
if ((i != (int)(dlen + diglen)) || memcmp(der, s, dlen)
|
||||
|| memcmp(s + dlen, dig, diglen))
|
||||
{
|
||||
RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
|
||||
goto err;
|
||||
}
|
||||
ret = 1;
|
||||
|
||||
}
|
||||
else if (rsa_pad_mode == RSA_PKCS1_PSS_PADDING)
|
||||
{
|
||||
ret = RSA_verify_PKCS1_PSS_mgf1(rsa, dig, mhash, mgf1Hash,
|
||||
s, saltlen);
|
||||
if (ret < 0)
|
||||
ret = 0;
|
||||
}
|
||||
err:
|
||||
if (s != NULL)
|
||||
{
|
||||
OPENSSL_cleanse(s, siglen);
|
||||
OPENSSL_free(s);
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
|
||||
#endif
|
280
fips/rsa/fips_rsa_x931g.c
Normal file
280
fips/rsa/fips_rsa_x931g.c
Normal file
@ -0,0 +1,280 @@
|
||||
/* crypto/rsa/rsa_gen.c */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* 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 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/fips.h>
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
|
||||
extern int fips_check_rsa(RSA *rsa);
|
||||
|
||||
|
||||
/* X9.31 RSA key derivation and generation */
|
||||
|
||||
int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1, BIGNUM *q2,
|
||||
const BIGNUM *Xp1, const BIGNUM *Xp2, const BIGNUM *Xp,
|
||||
const BIGNUM *Xq1, const BIGNUM *Xq2, const BIGNUM *Xq,
|
||||
const BIGNUM *e, BN_GENCB *cb)
|
||||
{
|
||||
BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL;
|
||||
BN_CTX *ctx=NULL,*ctx2=NULL;
|
||||
|
||||
if (!rsa)
|
||||
goto err;
|
||||
|
||||
ctx = BN_CTX_new();
|
||||
BN_CTX_start(ctx);
|
||||
if (!ctx)
|
||||
goto err;
|
||||
|
||||
r0 = BN_CTX_get(ctx);
|
||||
r1 = BN_CTX_get(ctx);
|
||||
r2 = BN_CTX_get(ctx);
|
||||
r3 = BN_CTX_get(ctx);
|
||||
|
||||
if (r3 == NULL)
|
||||
goto err;
|
||||
if (!rsa->e)
|
||||
{
|
||||
rsa->e = BN_dup(e);
|
||||
if (!rsa->e)
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
e = rsa->e;
|
||||
|
||||
/* If not all parameters present only calculate what we can.
|
||||
* This allows test programs to output selective parameters.
|
||||
*/
|
||||
|
||||
if (Xp && !rsa->p)
|
||||
{
|
||||
rsa->p = BN_new();
|
||||
if (!rsa->p)
|
||||
goto err;
|
||||
|
||||
if (!BN_X931_derive_prime_ex(rsa->p, p1, p2,
|
||||
Xp, Xp1, Xp2, e, ctx, cb))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (Xq && !rsa->q)
|
||||
{
|
||||
rsa->q = BN_new();
|
||||
if (!rsa->q)
|
||||
goto err;
|
||||
if (!BN_X931_derive_prime_ex(rsa->q, q1, q2,
|
||||
Xq, Xq1, Xq2, e, ctx, cb))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!rsa->p || !rsa->q)
|
||||
{
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* Since both primes are set we can now calculate all remaining
|
||||
* components.
|
||||
*/
|
||||
|
||||
/* calculate n */
|
||||
rsa->n=BN_new();
|
||||
if (rsa->n == NULL)
|
||||
goto err;
|
||||
if (!BN_mul(rsa->n,rsa->p,rsa->q,ctx))
|
||||
goto err;
|
||||
|
||||
/* calculate d */
|
||||
if (!BN_sub(r1,rsa->p,BN_value_one()))
|
||||
goto err; /* p-1 */
|
||||
if (!BN_sub(r2,rsa->q,BN_value_one()))
|
||||
goto err; /* q-1 */
|
||||
if (!BN_mul(r0,r1,r2,ctx))
|
||||
goto err; /* (p-1)(q-1) */
|
||||
|
||||
if (!BN_gcd(r3, r1, r2, ctx))
|
||||
goto err;
|
||||
|
||||
if (!BN_div(r0, NULL, r0, r3, ctx))
|
||||
goto err; /* LCM((p-1)(q-1)) */
|
||||
|
||||
ctx2 = BN_CTX_new();
|
||||
if (!ctx2)
|
||||
goto err;
|
||||
|
||||
rsa->d=BN_mod_inverse(NULL,rsa->e,r0,ctx2); /* d */
|
||||
if (rsa->d == NULL)
|
||||
goto err;
|
||||
|
||||
/* calculate d mod (p-1) */
|
||||
rsa->dmp1=BN_new();
|
||||
if (rsa->dmp1 == NULL)
|
||||
goto err;
|
||||
if (!BN_mod(rsa->dmp1,rsa->d,r1,ctx))
|
||||
goto err;
|
||||
|
||||
/* calculate d mod (q-1) */
|
||||
rsa->dmq1=BN_new();
|
||||
if (rsa->dmq1 == NULL)
|
||||
goto err;
|
||||
if (!BN_mod(rsa->dmq1,rsa->d,r2,ctx))
|
||||
goto err;
|
||||
|
||||
/* calculate inverse of q mod p */
|
||||
rsa->iqmp=BN_mod_inverse(NULL,rsa->q,rsa->p,ctx2);
|
||||
|
||||
err:
|
||||
if (ctx)
|
||||
{
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
}
|
||||
if (ctx2)
|
||||
BN_CTX_free(ctx2);
|
||||
/* If this is set all calls successful */
|
||||
if (rsa->iqmp != NULL)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e, BN_GENCB *cb)
|
||||
{
|
||||
int ok = 0;
|
||||
BIGNUM *Xp = NULL, *Xq = NULL;
|
||||
BN_CTX *ctx = NULL;
|
||||
|
||||
if (bits < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)
|
||||
{
|
||||
FIPSerr(FIPS_F_RSA_X931_GENERATE_KEY_EX,FIPS_R_KEY_TOO_SHORT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (bits & 0xff)
|
||||
{
|
||||
FIPSerr(FIPS_F_RSA_X931_GENERATE_KEY_EX,FIPS_R_INVALID_KEY_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(FIPS_selftest_failed())
|
||||
{
|
||||
FIPSerr(FIPS_F_RSA_X931_GENERATE_KEY_EX,FIPS_R_FIPS_SELFTEST_FAILED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ctx = BN_CTX_new();
|
||||
if (!ctx)
|
||||
goto error;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
Xp = BN_CTX_get(ctx);
|
||||
Xq = BN_CTX_get(ctx);
|
||||
if (!BN_X931_generate_Xpq(Xp, Xq, bits, ctx))
|
||||
goto error;
|
||||
|
||||
rsa->p = BN_new();
|
||||
rsa->q = BN_new();
|
||||
if (!rsa->p || !rsa->q)
|
||||
goto error;
|
||||
|
||||
/* Generate two primes from Xp, Xq */
|
||||
|
||||
if (!BN_X931_generate_prime_ex(rsa->p, NULL, NULL, NULL, NULL, Xp,
|
||||
e, ctx, cb))
|
||||
goto error;
|
||||
|
||||
if (!BN_X931_generate_prime_ex(rsa->q, NULL, NULL, NULL, NULL, Xq,
|
||||
e, ctx, cb))
|
||||
goto error;
|
||||
|
||||
/* Since rsa->p and rsa->q are valid this call will just derive
|
||||
* remaining RSA components.
|
||||
*/
|
||||
|
||||
if (!RSA_X931_derive_ex(rsa, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, e, cb))
|
||||
goto error;
|
||||
|
||||
if(!fips_check_rsa(rsa))
|
||||
goto error;
|
||||
|
||||
ok = 1;
|
||||
|
||||
error:
|
||||
if (ctx)
|
||||
{
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
}
|
||||
|
||||
if (ok)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
388
fips/rsa/fips_rsagtest.c
Normal file
388
fips/rsa/fips_rsagtest.c
Normal file
@ -0,0 +1,388 @@
|
||||
/* fips_rsagtest.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2005.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2005,2007 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#define OPENSSL_FIPSEVP
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
#ifndef OPENSSL_FIPS
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
printf("No FIPS RSA support\n");
|
||||
return(0);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/fips.h>
|
||||
#include "fips_utl.h"
|
||||
|
||||
int rsa_test(FILE *out, FILE *in);
|
||||
static int rsa_printkey1(FILE *out, RSA *rsa,
|
||||
BIGNUM *Xp1, BIGNUM *Xp2, BIGNUM *Xp,
|
||||
BIGNUM *e);
|
||||
static int rsa_printkey2(FILE *out, RSA *rsa,
|
||||
BIGNUM *Xq1, BIGNUM *Xq2, BIGNUM *Xq);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
FILE *in = NULL, *out = NULL;
|
||||
|
||||
int ret = 1;
|
||||
|
||||
fips_set_error_print();
|
||||
if(!FIPS_mode_set(1))
|
||||
goto end;
|
||||
|
||||
if (argc == 1)
|
||||
in = stdin;
|
||||
else
|
||||
in = fopen(argv[1], "r");
|
||||
|
||||
if (argc < 2)
|
||||
out = stdout;
|
||||
else
|
||||
out = fopen(argv[2], "w");
|
||||
|
||||
if (!in)
|
||||
{
|
||||
fprintf(stderr, "FATAL input initialization error\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!out)
|
||||
{
|
||||
fprintf(stderr, "FATAL output initialization error\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!rsa_test(out, in))
|
||||
{
|
||||
fprintf(stderr, "FATAL RSAGTEST file processing error\n");
|
||||
goto end;
|
||||
}
|
||||
else
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
|
||||
if (in && (in != stdin))
|
||||
fclose(in);
|
||||
if (out && (out != stdout))
|
||||
fclose(out);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
#define RSA_TEST_MAXLINELEN 10240
|
||||
|
||||
int rsa_test(FILE *out, FILE *in)
|
||||
{
|
||||
char *linebuf, *olinebuf, *p, *q;
|
||||
char *keyword, *value;
|
||||
RSA *rsa = NULL;
|
||||
BIGNUM *Xp1 = NULL, *Xp2 = NULL, *Xp = NULL;
|
||||
BIGNUM *Xq1 = NULL, *Xq2 = NULL, *Xq = NULL;
|
||||
BIGNUM *e = NULL;
|
||||
int ret = 0;
|
||||
int lnum = 0;
|
||||
|
||||
olinebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN);
|
||||
linebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN);
|
||||
|
||||
if (!linebuf || !olinebuf)
|
||||
goto error;
|
||||
|
||||
while (fgets(olinebuf, RSA_TEST_MAXLINELEN, in))
|
||||
{
|
||||
lnum++;
|
||||
strcpy(linebuf, olinebuf);
|
||||
keyword = linebuf;
|
||||
/* Skip leading space */
|
||||
while (isspace((unsigned char)*keyword))
|
||||
keyword++;
|
||||
|
||||
/* Look for = sign */
|
||||
p = strchr(linebuf, '=');
|
||||
|
||||
/* If no = or starts with [ (for [foo = bar] line) just copy */
|
||||
if (!p || *keyword=='[')
|
||||
{
|
||||
if (fputs(olinebuf, out) < 0)
|
||||
goto error;
|
||||
continue;
|
||||
}
|
||||
|
||||
q = p - 1;
|
||||
|
||||
/* Remove trailing space */
|
||||
while (isspace((unsigned char)*q))
|
||||
*q-- = 0;
|
||||
|
||||
*p = 0;
|
||||
value = p + 1;
|
||||
|
||||
/* Remove leading space from value */
|
||||
while (isspace((unsigned char)*value))
|
||||
value++;
|
||||
|
||||
/* Remove trailing space from value */
|
||||
p = value + strlen(value) - 1;
|
||||
|
||||
while (*p == '\n' || isspace((unsigned char)*p))
|
||||
*p-- = 0;
|
||||
|
||||
if (!strcmp(keyword, "xp1"))
|
||||
{
|
||||
if (Xp1 || !do_hex2bn(&Xp1,value))
|
||||
goto parse_error;
|
||||
}
|
||||
else if (!strcmp(keyword, "xp2"))
|
||||
{
|
||||
if (Xp2 || !do_hex2bn(&Xp2,value))
|
||||
goto parse_error;
|
||||
}
|
||||
else if (!strcmp(keyword, "Xp"))
|
||||
{
|
||||
if (Xp || !do_hex2bn(&Xp,value))
|
||||
goto parse_error;
|
||||
}
|
||||
else if (!strcmp(keyword, "xq1"))
|
||||
{
|
||||
if (Xq1 || !do_hex2bn(&Xq1,value))
|
||||
goto parse_error;
|
||||
}
|
||||
else if (!strcmp(keyword, "xq2"))
|
||||
{
|
||||
if (Xq2 || !do_hex2bn(&Xq2,value))
|
||||
goto parse_error;
|
||||
}
|
||||
else if (!strcmp(keyword, "Xq"))
|
||||
{
|
||||
if (Xq || !do_hex2bn(&Xq,value))
|
||||
goto parse_error;
|
||||
}
|
||||
else if (!strcmp(keyword, "e"))
|
||||
{
|
||||
if (e || !do_hex2bn(&e,value))
|
||||
goto parse_error;
|
||||
}
|
||||
else if (!strcmp(keyword, "p1"))
|
||||
continue;
|
||||
else if (!strcmp(keyword, "p2"))
|
||||
continue;
|
||||
else if (!strcmp(keyword, "p"))
|
||||
continue;
|
||||
else if (!strcmp(keyword, "q1"))
|
||||
continue;
|
||||
else if (!strcmp(keyword, "q2"))
|
||||
continue;
|
||||
else if (!strcmp(keyword, "q"))
|
||||
continue;
|
||||
else if (!strcmp(keyword, "n"))
|
||||
continue;
|
||||
else if (!strcmp(keyword, "d"))
|
||||
continue;
|
||||
else
|
||||
goto parse_error;
|
||||
|
||||
fputs(olinebuf, out);
|
||||
|
||||
if (e && Xp1 && Xp2 && Xp)
|
||||
{
|
||||
rsa = FIPS_rsa_new();
|
||||
if (!rsa)
|
||||
goto error;
|
||||
if (!rsa_printkey1(out, rsa, Xp1, Xp2, Xp, e))
|
||||
goto error;
|
||||
BN_free(Xp1);
|
||||
Xp1 = NULL;
|
||||
BN_free(Xp2);
|
||||
Xp2 = NULL;
|
||||
BN_free(Xp);
|
||||
Xp = NULL;
|
||||
BN_free(e);
|
||||
e = NULL;
|
||||
}
|
||||
|
||||
if (rsa && Xq1 && Xq2 && Xq)
|
||||
{
|
||||
if (!rsa_printkey2(out, rsa, Xq1, Xq2, Xq))
|
||||
goto error;
|
||||
BN_free(Xq1);
|
||||
Xq1 = NULL;
|
||||
BN_free(Xq2);
|
||||
Xq2 = NULL;
|
||||
BN_free(Xq);
|
||||
Xq = NULL;
|
||||
FIPS_rsa_free(rsa);
|
||||
rsa = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
error:
|
||||
|
||||
if (olinebuf)
|
||||
OPENSSL_free(olinebuf);
|
||||
if (linebuf)
|
||||
OPENSSL_free(linebuf);
|
||||
|
||||
if (Xp1)
|
||||
BN_free(Xp1);
|
||||
if (Xp2)
|
||||
BN_free(Xp2);
|
||||
if (Xp)
|
||||
BN_free(Xp);
|
||||
if (Xq1)
|
||||
BN_free(Xq1);
|
||||
if (Xq1)
|
||||
BN_free(Xq1);
|
||||
if (Xq2)
|
||||
BN_free(Xq2);
|
||||
if (Xq)
|
||||
BN_free(Xq);
|
||||
if (e)
|
||||
BN_free(e);
|
||||
if (rsa)
|
||||
FIPS_rsa_free(rsa);
|
||||
|
||||
return ret;
|
||||
|
||||
parse_error:
|
||||
|
||||
fprintf(stderr, "FATAL parse error processing line %d\n", lnum);
|
||||
|
||||
goto error;
|
||||
|
||||
}
|
||||
|
||||
static int rsa_printkey1(FILE *out, RSA *rsa,
|
||||
BIGNUM *Xp1, BIGNUM *Xp2, BIGNUM *Xp,
|
||||
BIGNUM *e)
|
||||
{
|
||||
int ret = 0;
|
||||
BIGNUM *p1 = NULL, *p2 = NULL;
|
||||
p1 = BN_new();
|
||||
p2 = BN_new();
|
||||
if (!p1 || !p2)
|
||||
goto error;
|
||||
|
||||
if (!RSA_X931_derive_ex(rsa, p1, p2, NULL, NULL, Xp1, Xp2, Xp,
|
||||
NULL, NULL, NULL, e, NULL))
|
||||
goto error;
|
||||
|
||||
do_bn_print_name(out, "p1", p1);
|
||||
do_bn_print_name(out, "p2", p2);
|
||||
do_bn_print_name(out, "p", rsa->p);
|
||||
|
||||
ret = 1;
|
||||
|
||||
error:
|
||||
if (p1)
|
||||
BN_free(p1);
|
||||
if (p2)
|
||||
BN_free(p2);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rsa_printkey2(FILE *out, RSA *rsa,
|
||||
BIGNUM *Xq1, BIGNUM *Xq2, BIGNUM *Xq)
|
||||
{
|
||||
int ret = 0;
|
||||
BIGNUM *q1 = NULL, *q2 = NULL;
|
||||
q1 = BN_new();
|
||||
q2 = BN_new();
|
||||
if (!q1 || !q2)
|
||||
goto error;
|
||||
|
||||
if (!RSA_X931_derive_ex(rsa, NULL, NULL, q1, q2, NULL, NULL, NULL,
|
||||
Xq1, Xq2, Xq, NULL, NULL))
|
||||
goto error;
|
||||
|
||||
do_bn_print_name(out, "q1", q1);
|
||||
do_bn_print_name(out, "q2", q2);
|
||||
do_bn_print_name(out, "q", rsa->q);
|
||||
do_bn_print_name(out, "n", rsa->n);
|
||||
do_bn_print_name(out, "d", rsa->d);
|
||||
|
||||
ret = 1;
|
||||
|
||||
error:
|
||||
if (q1)
|
||||
BN_free(q1);
|
||||
if (q2)
|
||||
BN_free(q2);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
366
fips/rsa/fips_rsastest.c
Normal file
366
fips/rsa/fips_rsastest.c
Normal file
@ -0,0 +1,366 @@
|
||||
/* fips_rsastest.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2005.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2005 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#define OPENSSL_FIPSEVP
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
#ifndef OPENSSL_FIPS
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
printf("No FIPS RSA support\n");
|
||||
return(0);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/fips.h>
|
||||
#include "fips_utl.h"
|
||||
|
||||
static int rsa_stest(FILE *out, FILE *in, int Saltlen);
|
||||
static int rsa_printsig(FILE *out, RSA *rsa, const EVP_MD *dgst,
|
||||
unsigned char *Msg, long Msglen, int Saltlen);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
FILE *in = NULL, *out = NULL;
|
||||
|
||||
int ret = 1, Saltlen = -1;
|
||||
|
||||
fips_set_error_print();
|
||||
if(!FIPS_mode_set(1))
|
||||
goto end;
|
||||
|
||||
if ((argc > 2) && !strcmp("-saltlen", argv[1]))
|
||||
{
|
||||
Saltlen = atoi(argv[2]);
|
||||
if (Saltlen < 0)
|
||||
{
|
||||
fprintf(stderr, "FATAL: Invalid salt length\n");
|
||||
goto end;
|
||||
}
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
}
|
||||
else if ((argc > 1) && !strcmp("-x931", argv[1]))
|
||||
{
|
||||
Saltlen = -2;
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
if (argc == 1)
|
||||
in = stdin;
|
||||
else
|
||||
in = fopen(argv[1], "r");
|
||||
|
||||
if (argc < 2)
|
||||
out = stdout;
|
||||
else
|
||||
out = fopen(argv[2], "w");
|
||||
|
||||
if (!in)
|
||||
{
|
||||
fprintf(stderr, "FATAL input initialization error\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!out)
|
||||
{
|
||||
fprintf(stderr, "FATAL output initialization error\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!rsa_stest(out, in, Saltlen))
|
||||
{
|
||||
fprintf(stderr, "FATAL RSASTEST file processing error\n");
|
||||
goto end;
|
||||
}
|
||||
else
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
|
||||
if (in && (in != stdin))
|
||||
fclose(in);
|
||||
if (out && (out != stdout))
|
||||
fclose(out);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
#define RSA_TEST_MAXLINELEN 10240
|
||||
|
||||
int rsa_stest(FILE *out, FILE *in, int Saltlen)
|
||||
{
|
||||
char *linebuf, *olinebuf, *p, *q;
|
||||
char *keyword, *value;
|
||||
RSA *rsa = NULL;
|
||||
const EVP_MD *dgst = NULL;
|
||||
unsigned char *Msg = NULL;
|
||||
long Msglen = -1;
|
||||
int keylen = -1, current_keylen = -1;
|
||||
int ret = 0;
|
||||
int lnum = 0;
|
||||
|
||||
olinebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN);
|
||||
linebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN);
|
||||
|
||||
if (!linebuf || !olinebuf)
|
||||
goto error;
|
||||
|
||||
while (fgets(olinebuf, RSA_TEST_MAXLINELEN, in))
|
||||
{
|
||||
lnum++;
|
||||
strcpy(linebuf, olinebuf);
|
||||
keyword = linebuf;
|
||||
/* Skip leading space */
|
||||
while (isspace((unsigned char)*keyword))
|
||||
keyword++;
|
||||
|
||||
/* Look for = sign */
|
||||
p = strchr(linebuf, '=');
|
||||
|
||||
/* If no = just copy */
|
||||
if (!p)
|
||||
{
|
||||
if (fputs(olinebuf, out) < 0)
|
||||
goto error;
|
||||
continue;
|
||||
}
|
||||
|
||||
q = p - 1;
|
||||
|
||||
/* Remove trailing space */
|
||||
while (isspace((unsigned char)*q))
|
||||
*q-- = 0;
|
||||
|
||||
*p = 0;
|
||||
value = p + 1;
|
||||
|
||||
/* Remove leading space from value */
|
||||
while (isspace((unsigned char)*value))
|
||||
value++;
|
||||
|
||||
/* Remove trailing space from value */
|
||||
p = value + strlen(value) - 1;
|
||||
|
||||
while (*p == '\n' || isspace((unsigned char)*p))
|
||||
*p-- = 0;
|
||||
|
||||
/* Look for [mod = XXX] for key length */
|
||||
|
||||
if (!strcmp(keyword, "[mod"))
|
||||
{
|
||||
p = value + strlen(value) - 1;
|
||||
if (*p != ']')
|
||||
goto parse_error;
|
||||
*p = 0;
|
||||
keylen = atoi(value);
|
||||
if (keylen < 0)
|
||||
goto parse_error;
|
||||
}
|
||||
else if (!strcmp(keyword, "SHAAlg"))
|
||||
{
|
||||
if (!strcmp(value, "SHA1"))
|
||||
dgst = EVP_sha1();
|
||||
else if (!strcmp(value, "SHA224"))
|
||||
dgst = EVP_sha224();
|
||||
else if (!strcmp(value, "SHA256"))
|
||||
dgst = EVP_sha256();
|
||||
else if (!strcmp(value, "SHA384"))
|
||||
dgst = EVP_sha384();
|
||||
else if (!strcmp(value, "SHA512"))
|
||||
dgst = EVP_sha512();
|
||||
else
|
||||
{
|
||||
fprintf(stderr,
|
||||
"FATAL: unsupported algorithm \"%s\"\n",
|
||||
value);
|
||||
goto parse_error;
|
||||
}
|
||||
}
|
||||
else if (!strcmp(keyword, "Msg"))
|
||||
{
|
||||
if (Msg)
|
||||
goto parse_error;
|
||||
if (strlen(value) & 1)
|
||||
*(--value) = '0';
|
||||
Msg = hex2bin_m(value, &Msglen);
|
||||
if (!Msg)
|
||||
goto parse_error;
|
||||
}
|
||||
|
||||
fputs(olinebuf, out);
|
||||
|
||||
/* If key length has changed, generate and output public
|
||||
* key components of new RSA private key.
|
||||
*/
|
||||
|
||||
if (keylen != current_keylen)
|
||||
{
|
||||
BIGNUM *bn_e;
|
||||
if (rsa)
|
||||
FIPS_rsa_free(rsa);
|
||||
rsa = FIPS_rsa_new();
|
||||
if (!rsa)
|
||||
goto error;
|
||||
bn_e = BN_new();
|
||||
if (!bn_e || !BN_set_word(bn_e, 0x1001))
|
||||
goto error;
|
||||
if (!RSA_X931_generate_key_ex(rsa, keylen, bn_e, NULL))
|
||||
goto error;
|
||||
BN_free(bn_e);
|
||||
fputs("n = ", out);
|
||||
do_bn_print(out, rsa->n);
|
||||
fputs("\ne = ", out);
|
||||
do_bn_print(out, rsa->e);
|
||||
fputs("\n", out);
|
||||
current_keylen = keylen;
|
||||
}
|
||||
|
||||
if (Msg && dgst)
|
||||
{
|
||||
if (!rsa_printsig(out, rsa, dgst, Msg, Msglen,
|
||||
Saltlen))
|
||||
goto error;
|
||||
OPENSSL_free(Msg);
|
||||
Msg = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
error:
|
||||
|
||||
if (olinebuf)
|
||||
OPENSSL_free(olinebuf);
|
||||
if (linebuf)
|
||||
OPENSSL_free(linebuf);
|
||||
if (rsa)
|
||||
FIPS_rsa_free(rsa);
|
||||
|
||||
return ret;
|
||||
|
||||
parse_error:
|
||||
|
||||
fprintf(stderr, "FATAL parse error processing line %d\n", lnum);
|
||||
|
||||
goto error;
|
||||
|
||||
}
|
||||
|
||||
static int rsa_printsig(FILE *out, RSA *rsa, const EVP_MD *dgst,
|
||||
unsigned char *Msg, long Msglen, int Saltlen)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char *sigbuf = NULL;
|
||||
int i, siglen, pad_mode;
|
||||
/* EVP_PKEY structure */
|
||||
EVP_MD_CTX ctx;
|
||||
|
||||
siglen = RSA_size(rsa);
|
||||
sigbuf = OPENSSL_malloc(siglen);
|
||||
if (!sigbuf)
|
||||
goto error;
|
||||
|
||||
EVP_MD_CTX_init(&ctx);
|
||||
|
||||
if (Saltlen >= 0)
|
||||
pad_mode = RSA_PKCS1_PSS_PADDING;
|
||||
else if (Saltlen == -2)
|
||||
pad_mode = RSA_X931_PADDING;
|
||||
else
|
||||
pad_mode = RSA_PKCS1_PADDING;
|
||||
|
||||
if (!EVP_DigestInit_ex(&ctx, dgst, NULL))
|
||||
goto error;
|
||||
if (!EVP_DigestUpdate(&ctx, Msg, Msglen))
|
||||
goto error;
|
||||
if (!FIPS_rsa_sign_ctx(rsa, &ctx, pad_mode, Saltlen, NULL,
|
||||
sigbuf, (unsigned int *)&siglen))
|
||||
goto error;
|
||||
|
||||
EVP_MD_CTX_cleanup(&ctx);
|
||||
|
||||
fputs("S = ", out);
|
||||
|
||||
for (i = 0; i < siglen; i++)
|
||||
fprintf(out, "%02X", sigbuf[i]);
|
||||
|
||||
fputs("\n", out);
|
||||
|
||||
ret = 1;
|
||||
|
||||
error:
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
375
fips/rsa/fips_rsavtest.c
Normal file
375
fips/rsa/fips_rsavtest.c
Normal file
@ -0,0 +1,375 @@
|
||||
/* fips_rsavtest.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2005.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2005 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#define OPENSSL_FIPSEVP
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/x509v3.h>
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#ifndef OPENSSL_FIPS
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
printf("No FIPS RSA support\n");
|
||||
return(0);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/fips.h>
|
||||
|
||||
#include "fips_utl.h"
|
||||
|
||||
int rsa_test(FILE *out, FILE *in, int saltlen);
|
||||
static int rsa_printver(FILE *out,
|
||||
BIGNUM *n, BIGNUM *e,
|
||||
const EVP_MD *dgst,
|
||||
unsigned char *Msg, long Msglen,
|
||||
unsigned char *S, long Slen, int Saltlen);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
FILE *in = NULL, *out = NULL;
|
||||
|
||||
int ret = 1;
|
||||
int Saltlen = -1;
|
||||
|
||||
fips_set_error_print();
|
||||
if(!FIPS_mode_set(1))
|
||||
goto end;
|
||||
|
||||
if ((argc > 2) && !strcmp("-saltlen", argv[1]))
|
||||
{
|
||||
Saltlen = atoi(argv[2]);
|
||||
if (Saltlen < 0)
|
||||
{
|
||||
fprintf(stderr, "FATAL: Invalid salt length\n");
|
||||
goto end;
|
||||
}
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
}
|
||||
else if ((argc > 1) && !strcmp("-x931", argv[1]))
|
||||
{
|
||||
Saltlen = -2;
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
if (argc == 1)
|
||||
in = stdin;
|
||||
else
|
||||
in = fopen(argv[1], "r");
|
||||
|
||||
if (argc < 2)
|
||||
out = stdout;
|
||||
else
|
||||
out = fopen(argv[2], "w");
|
||||
|
||||
if (!in)
|
||||
{
|
||||
fprintf(stderr, "FATAL input initialization error\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!out)
|
||||
{
|
||||
fprintf(stderr, "FATAL output initialization error\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!rsa_test(out, in, Saltlen))
|
||||
{
|
||||
fprintf(stderr, "FATAL RSAVTEST file processing error\n");
|
||||
goto end;
|
||||
}
|
||||
else
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
|
||||
if (in && (in != stdin))
|
||||
fclose(in);
|
||||
if (out && (out != stdout))
|
||||
fclose(out);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
#define RSA_TEST_MAXLINELEN 10240
|
||||
|
||||
int rsa_test(FILE *out, FILE *in, int Saltlen)
|
||||
{
|
||||
char *linebuf, *olinebuf, *p, *q;
|
||||
char *keyword, *value;
|
||||
const EVP_MD *dgst = NULL;
|
||||
BIGNUM *n = NULL, *e = NULL;
|
||||
unsigned char *Msg = NULL, *S = NULL;
|
||||
long Msglen, Slen;
|
||||
int ret = 0;
|
||||
int lnum = 0;
|
||||
|
||||
olinebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN);
|
||||
linebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN);
|
||||
|
||||
if (!linebuf || !olinebuf)
|
||||
goto error;
|
||||
|
||||
while (fgets(olinebuf, RSA_TEST_MAXLINELEN, in))
|
||||
{
|
||||
lnum++;
|
||||
strcpy(linebuf, olinebuf);
|
||||
keyword = linebuf;
|
||||
/* Skip leading space */
|
||||
while (isspace((unsigned char)*keyword))
|
||||
keyword++;
|
||||
|
||||
/* Look for = sign */
|
||||
p = strchr(linebuf, '=');
|
||||
|
||||
/* If no = or starts with [ (for [foo = bar] line) just copy */
|
||||
if (!p || *keyword=='[')
|
||||
{
|
||||
if (fputs(olinebuf, out) < 0)
|
||||
goto error;
|
||||
continue;
|
||||
}
|
||||
|
||||
q = p - 1;
|
||||
|
||||
/* Remove trailing space */
|
||||
while (isspace((unsigned char)*q))
|
||||
*q-- = 0;
|
||||
|
||||
*p = 0;
|
||||
value = p + 1;
|
||||
|
||||
/* Remove leading space from value */
|
||||
while (isspace((unsigned char)*value))
|
||||
value++;
|
||||
|
||||
/* Remove trailing space from value */
|
||||
p = value + strlen(value) - 1;
|
||||
|
||||
while (*p == '\n' || isspace((unsigned char)*p))
|
||||
*p-- = 0;
|
||||
|
||||
if (!strcmp(keyword, "n"))
|
||||
{
|
||||
if (!do_hex2bn(&n,value))
|
||||
goto parse_error;
|
||||
}
|
||||
else if (!strcmp(keyword, "e"))
|
||||
{
|
||||
if (!do_hex2bn(&e,value))
|
||||
goto parse_error;
|
||||
}
|
||||
else if (!strcmp(keyword, "SHAAlg"))
|
||||
{
|
||||
if (!strcmp(value, "SHA1"))
|
||||
dgst = EVP_sha1();
|
||||
else if (!strcmp(value, "SHA224"))
|
||||
dgst = EVP_sha224();
|
||||
else if (!strcmp(value, "SHA256"))
|
||||
dgst = EVP_sha256();
|
||||
else if (!strcmp(value, "SHA384"))
|
||||
dgst = EVP_sha384();
|
||||
else if (!strcmp(value, "SHA512"))
|
||||
dgst = EVP_sha512();
|
||||
else
|
||||
{
|
||||
fprintf(stderr,
|
||||
"FATAL: unsupported algorithm \"%s\"\n",
|
||||
value);
|
||||
goto parse_error;
|
||||
}
|
||||
}
|
||||
else if (!strcmp(keyword, "Msg"))
|
||||
{
|
||||
if (Msg)
|
||||
goto parse_error;
|
||||
if (strlen(value) & 1)
|
||||
*(--value) = '0';
|
||||
Msg = hex2bin_m(value, &Msglen);
|
||||
if (!Msg)
|
||||
goto parse_error;
|
||||
}
|
||||
else if (!strcmp(keyword, "S"))
|
||||
{
|
||||
if (S)
|
||||
goto parse_error;
|
||||
if (strlen(value) & 1)
|
||||
*(--value) = '0';
|
||||
S = hex2bin_m(value, &Slen);
|
||||
if (!S)
|
||||
goto parse_error;
|
||||
}
|
||||
else if (!strcmp(keyword, "Result"))
|
||||
continue;
|
||||
else
|
||||
goto parse_error;
|
||||
|
||||
fputs(olinebuf, out);
|
||||
|
||||
if (n && e && Msg && S && dgst)
|
||||
{
|
||||
if (!rsa_printver(out, n, e, dgst,
|
||||
Msg, Msglen, S, Slen, Saltlen))
|
||||
goto error;
|
||||
OPENSSL_free(Msg);
|
||||
Msg = NULL;
|
||||
OPENSSL_free(S);
|
||||
S = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
ret = 1;
|
||||
|
||||
|
||||
error:
|
||||
|
||||
if (olinebuf)
|
||||
OPENSSL_free(olinebuf);
|
||||
if (linebuf)
|
||||
OPENSSL_free(linebuf);
|
||||
if (n)
|
||||
BN_free(n);
|
||||
if (e)
|
||||
BN_free(e);
|
||||
|
||||
return ret;
|
||||
|
||||
parse_error:
|
||||
|
||||
fprintf(stderr, "FATAL parse error processing line %d\n", lnum);
|
||||
|
||||
goto error;
|
||||
|
||||
}
|
||||
|
||||
static int rsa_printver(FILE *out,
|
||||
BIGNUM *n, BIGNUM *e,
|
||||
const EVP_MD *dgst,
|
||||
unsigned char *Msg, long Msglen,
|
||||
unsigned char *S, long Slen, int Saltlen)
|
||||
{
|
||||
int ret = 0, r, pad_mode;
|
||||
/* Setup RSA and EVP_PKEY structures */
|
||||
RSA *rsa_pubkey = NULL;
|
||||
EVP_MD_CTX ctx;
|
||||
unsigned char *buf = NULL;
|
||||
rsa_pubkey = FIPS_rsa_new();
|
||||
if (!rsa_pubkey)
|
||||
goto error;
|
||||
rsa_pubkey->n = BN_dup(n);
|
||||
rsa_pubkey->e = BN_dup(e);
|
||||
if (!rsa_pubkey->n || !rsa_pubkey->e)
|
||||
goto error;
|
||||
|
||||
EVP_MD_CTX_init(&ctx);
|
||||
|
||||
if (Saltlen >= 0)
|
||||
pad_mode = RSA_PKCS1_PSS_PADDING;
|
||||
else if (Saltlen == -2)
|
||||
pad_mode = RSA_X931_PADDING;
|
||||
else
|
||||
pad_mode = RSA_PKCS1_PADDING;
|
||||
|
||||
if (!EVP_DigestInit_ex(&ctx, dgst, NULL))
|
||||
goto error;
|
||||
if (!EVP_DigestUpdate(&ctx, Msg, Msglen))
|
||||
goto error;
|
||||
|
||||
no_err = 1;
|
||||
r = FIPS_rsa_verify_ctx(rsa_pubkey, &ctx,
|
||||
pad_mode, Saltlen, NULL, S, Slen);
|
||||
no_err = 0;
|
||||
|
||||
|
||||
EVP_MD_CTX_cleanup(&ctx);
|
||||
|
||||
if (r < 0)
|
||||
goto error;
|
||||
|
||||
if (r == 0)
|
||||
fputs("Result = F\n", out);
|
||||
else
|
||||
fputs("Result = P\n", out);
|
||||
|
||||
ret = 1;
|
||||
|
||||
error:
|
||||
if (rsa_pubkey)
|
||||
FIPS_rsa_free(rsa_pubkey);
|
||||
if (buf)
|
||||
OPENSSL_free(buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
73
fips/utl/Makefile
Normal file
73
fips/utl/Makefile
Normal file
@ -0,0 +1,73 @@
|
||||
#
|
||||
# OpenSSL/fips/utl/Makefile
|
||||
#
|
||||
|
||||
DIR= callback
|
||||
TOP= ../..
|
||||
CC= cc
|
||||
INCLUDES=
|
||||
CFLAG=-g
|
||||
INSTALL_PREFIX=
|
||||
OPENSSLDIR= /usr/local/ssl
|
||||
INSTALLTOP=/usr/local/ssl
|
||||
MAKEDEPPROG= makedepend
|
||||
MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
|
||||
MAKEFILE= Makefile
|
||||
AR= ar r
|
||||
|
||||
CFLAGS= $(INCLUDES) $(CFLAG)
|
||||
|
||||
GENERAL=Makefile
|
||||
TEST=
|
||||
APPS=
|
||||
|
||||
LIB=$(TOP)/libcrypto.a
|
||||
LIBSRC= fips_err.c fips_md.c fips_enc.c
|
||||
LIBOBJ= fips_err.o fips_md.o fips_enc.o
|
||||
|
||||
SRC= $(LIBSRC)
|
||||
|
||||
EXHEADER=
|
||||
HEADER= $(EXHEADER)
|
||||
|
||||
ALL= $(GENERAL) $(SRC) $(HEADER)
|
||||
|
||||
top:
|
||||
(cd $(TOP); $(MAKE) DIRS=fips FDIRS=$(DIR) sub_all)
|
||||
|
||||
all: lib
|
||||
|
||||
lib: $(LIBOBJ)
|
||||
@echo $(LIBOBJ) > lib
|
||||
|
||||
files:
|
||||
$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
|
||||
|
||||
links:
|
||||
@$(PERL) $(TOP)/util/mklink.pl $(TOP)/include/openssl $(EXHEADER)
|
||||
@$(PERL) $(TOP)/util/mklink.pl $(TOP)/test $(TEST)
|
||||
@$(PERL) $(TOP)/util/mklink.pl $(TOP)/apps $(APPS)
|
||||
|
||||
install:
|
||||
@headerlist="$(EXHEADER)"; for i in $$headerlist; \
|
||||
do \
|
||||
(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
|
||||
chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
|
||||
done
|
||||
|
||||
tags:
|
||||
ctags $(SRC)
|
||||
|
||||
tests:
|
||||
|
||||
depend:
|
||||
$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(SRC) $(TEST)
|
||||
|
||||
dclean:
|
||||
$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
|
||||
mv -f Makefile.new $(MAKEFILE)
|
||||
|
||||
clean:
|
||||
rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
|
||||
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
||||
|
228
fips/utl/fips_enc.c
Normal file
228
fips/utl/fips_enc.c
Normal file
@ -0,0 +1,228 @@
|
||||
/* fipe/evp/fips_enc.c */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* 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 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
void FIPS_cipher_ctx_init(EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
memset(ctx,0,sizeof(EVP_CIPHER_CTX));
|
||||
/* ctx->cipher=NULL; */
|
||||
}
|
||||
|
||||
EVP_CIPHER_CTX *FIPS_cipher_ctx_new(void)
|
||||
{
|
||||
EVP_CIPHER_CTX *ctx=OPENSSL_malloc(sizeof *ctx);
|
||||
if (ctx)
|
||||
FIPS_cipher_ctx_init(ctx);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
int FIPS_cipherinit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
|
||||
const unsigned char *key, const unsigned char *iv, int enc)
|
||||
{
|
||||
if (enc == -1)
|
||||
enc = ctx->encrypt;
|
||||
else
|
||||
{
|
||||
if (enc)
|
||||
enc = 1;
|
||||
ctx->encrypt = enc;
|
||||
}
|
||||
if (cipher)
|
||||
{
|
||||
/* Ensure a context left lying around from last time is cleared
|
||||
* (the previous check attempted to avoid this if the same
|
||||
* ENGINE and EVP_CIPHER could be used). */
|
||||
FIPS_cipher_ctx_cleanup(ctx);
|
||||
|
||||
/* Restore encrypt field: it is zeroed by cleanup */
|
||||
ctx->encrypt = enc;
|
||||
|
||||
ctx->cipher=cipher;
|
||||
if (ctx->cipher->ctx_size)
|
||||
{
|
||||
ctx->cipher_data=OPENSSL_malloc(ctx->cipher->ctx_size);
|
||||
if (!ctx->cipher_data)
|
||||
{
|
||||
EVPerr(EVP_F_EVP_CIPHERINIT_EX, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx->cipher_data = NULL;
|
||||
}
|
||||
ctx->key_len = cipher->key_len;
|
||||
ctx->flags = 0;
|
||||
if(ctx->cipher->flags & EVP_CIPH_CTRL_INIT)
|
||||
{
|
||||
if(!FIPS_cipher_ctx_ctrl(ctx, EVP_CTRL_INIT, 0, NULL))
|
||||
{
|
||||
EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(!ctx->cipher)
|
||||
{
|
||||
EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_NO_CIPHER_SET);
|
||||
return 0;
|
||||
}
|
||||
/* we assume block size is a power of 2 in *cryptUpdate */
|
||||
OPENSSL_assert(ctx->cipher->block_size == 1
|
||||
|| ctx->cipher->block_size == 8
|
||||
|| ctx->cipher->block_size == 16);
|
||||
|
||||
if(!(M_EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) {
|
||||
switch(M_EVP_CIPHER_CTX_mode(ctx)) {
|
||||
|
||||
case EVP_CIPH_STREAM_CIPHER:
|
||||
case EVP_CIPH_ECB_MODE:
|
||||
break;
|
||||
|
||||
case EVP_CIPH_CFB_MODE:
|
||||
case EVP_CIPH_OFB_MODE:
|
||||
|
||||
ctx->num = 0;
|
||||
/* fall-through */
|
||||
|
||||
case EVP_CIPH_CBC_MODE:
|
||||
|
||||
OPENSSL_assert(M_EVP_CIPHER_CTX_iv_length(ctx) <=
|
||||
(int)sizeof(ctx->iv));
|
||||
if(iv) memcpy(ctx->oiv, iv, M_EVP_CIPHER_CTX_iv_length(ctx));
|
||||
memcpy(ctx->iv, ctx->oiv, M_EVP_CIPHER_CTX_iv_length(ctx));
|
||||
break;
|
||||
|
||||
case EVP_CIPH_CTR_MODE:
|
||||
/* Don't reuse IV for CTR mode */
|
||||
if(iv)
|
||||
memcpy(ctx->iv, iv, M_EVP_CIPHER_CTX_iv_length(ctx));
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) {
|
||||
if(!ctx->cipher->init(ctx,key,iv,enc)) return 0;
|
||||
}
|
||||
ctx->buf_len=0;
|
||||
ctx->final_used=0;
|
||||
ctx->block_mask=ctx->cipher->block_size-1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void FIPS_cipher_ctx_free(EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
if (ctx)
|
||||
{
|
||||
FIPS_cipher_ctx_cleanup(ctx);
|
||||
OPENSSL_free(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
int FIPS_cipher_ctx_cleanup(EVP_CIPHER_CTX *c)
|
||||
{
|
||||
if (c->cipher != NULL)
|
||||
{
|
||||
if(c->cipher->cleanup && !c->cipher->cleanup(c))
|
||||
return 0;
|
||||
/* Cleanse cipher context data */
|
||||
if (c->cipher_data)
|
||||
OPENSSL_cleanse(c->cipher_data, c->cipher->ctx_size);
|
||||
}
|
||||
if (c->cipher_data)
|
||||
OPENSSL_free(c->cipher_data);
|
||||
memset(c,0,sizeof(EVP_CIPHER_CTX));
|
||||
return 1;
|
||||
}
|
||||
|
||||
int FIPS_cipher_ctx_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
|
||||
{
|
||||
int ret;
|
||||
if(!ctx->cipher) {
|
||||
EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!ctx->cipher->ctrl) {
|
||||
EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_NOT_IMPLEMENTED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = ctx->cipher->ctrl(ctx, type, arg, ptr);
|
||||
if(ret == -1) {
|
||||
EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED);
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int FIPS_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
const unsigned char *in, unsigned int inl)
|
||||
{
|
||||
return ctx->cipher->do_cipher(ctx,out,in,inl);
|
||||
}
|
87
fips/utl/fips_err.c
Normal file
87
fips/utl/fips_err.c
Normal file
@ -0,0 +1,87 @@
|
||||
/* fips/utl/fips_err.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2010 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/fips.h>
|
||||
|
||||
/* FIPS error callbacks */
|
||||
|
||||
static void (*fips_put_error_cb)(int lib, int func,int reason,const char *file,int line) = 0;
|
||||
static void (*fips_add_error_vdata)(int num, va_list args) = 0;
|
||||
|
||||
void FIPS_put_error(int lib, int func,int reason,const char *file,int line)
|
||||
{
|
||||
if (fips_put_error_cb)
|
||||
fips_put_error_cb(lib, func, reason, file, line);
|
||||
}
|
||||
|
||||
void FIPS_add_error_data(int num, ...)
|
||||
{
|
||||
if (fips_add_error_vdata)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, num);
|
||||
fips_add_error_vdata(num, args);
|
||||
va_end(args);
|
||||
}
|
||||
}
|
||||
|
||||
void FIPS_set_error_callbacks(
|
||||
void (*put_cb)(int lib, int func,int reason,const char *file,int line),
|
||||
void (*add_cb)(int num, va_list args) )
|
||||
{
|
||||
fips_put_error_cb = put_cb;
|
||||
fips_add_error_vdata = add_cb;
|
||||
}
|
||||
|
||||
|
265
fips/utl/fips_md.c
Normal file
265
fips/utl/fips_md.c
Normal file
@ -0,0 +1,265 @@
|
||||
/* fips/evp/fips_md.c */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* 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 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
/* Minimal standalone FIPS versions of Digest operations */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
void FIPS_md_ctx_init(EVP_MD_CTX *ctx)
|
||||
{
|
||||
memset(ctx,'\0',sizeof *ctx);
|
||||
}
|
||||
|
||||
EVP_MD_CTX *FIPS_md_ctx_create(void)
|
||||
{
|
||||
EVP_MD_CTX *ctx=OPENSSL_malloc(sizeof *ctx);
|
||||
|
||||
if (ctx)
|
||||
FIPS_md_ctx_init(ctx);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
int FIPS_digestinit(EVP_MD_CTX *ctx, const EVP_MD *type)
|
||||
{
|
||||
M_EVP_MD_CTX_clear_flags(ctx,EVP_MD_CTX_FLAG_CLEANED);
|
||||
if (ctx->digest != type)
|
||||
{
|
||||
if (ctx->digest && ctx->digest->ctx_size)
|
||||
OPENSSL_free(ctx->md_data);
|
||||
ctx->digest=type;
|
||||
if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size)
|
||||
{
|
||||
ctx->update = type->update;
|
||||
ctx->md_data=OPENSSL_malloc(type->ctx_size);
|
||||
if (ctx->md_data == NULL)
|
||||
{
|
||||
EVPerr(EVP_F_EVP_DIGESTINIT_EX,
|
||||
ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT)
|
||||
return 1;
|
||||
return ctx->digest->init(ctx);
|
||||
}
|
||||
|
||||
int FIPS_digestupdate(EVP_MD_CTX *ctx, const void *data, size_t count)
|
||||
{
|
||||
return ctx->update(ctx,data,count);
|
||||
}
|
||||
|
||||
/* The caller can assume that this removes any secret data from the context */
|
||||
int FIPS_digestfinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE);
|
||||
ret=ctx->digest->final(ctx,md);
|
||||
if (size != NULL)
|
||||
*size=ctx->digest->md_size;
|
||||
if (ctx->digest->cleanup)
|
||||
{
|
||||
ctx->digest->cleanup(ctx);
|
||||
M_EVP_MD_CTX_set_flags(ctx,EVP_MD_CTX_FLAG_CLEANED);
|
||||
}
|
||||
memset(ctx->md_data,0,ctx->digest->ctx_size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int FIPS_digest(const void *data, size_t count,
|
||||
unsigned char *md, unsigned int *size, const EVP_MD *type)
|
||||
{
|
||||
EVP_MD_CTX ctx;
|
||||
int ret;
|
||||
|
||||
FIPS_md_ctx_init(&ctx);
|
||||
M_EVP_MD_CTX_set_flags(&ctx,EVP_MD_CTX_FLAG_ONESHOT);
|
||||
ret=FIPS_digestinit(&ctx, type)
|
||||
&& FIPS_digestupdate(&ctx, data, count)
|
||||
&& FIPS_digestfinal(&ctx, md, size);
|
||||
FIPS_md_ctx_cleanup(&ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void FIPS_md_ctx_destroy(EVP_MD_CTX *ctx)
|
||||
{
|
||||
FIPS_md_ctx_cleanup(ctx);
|
||||
OPENSSL_free(ctx);
|
||||
}
|
||||
|
||||
/* This call frees resources associated with the context */
|
||||
int FIPS_md_ctx_cleanup(EVP_MD_CTX *ctx)
|
||||
{
|
||||
/* Don't assume ctx->md_data was cleaned in EVP_Digest_Final,
|
||||
* because sometimes only copies of the context are ever finalised.
|
||||
*/
|
||||
if (ctx->digest && ctx->digest->cleanup
|
||||
&& !M_EVP_MD_CTX_test_flags(ctx,EVP_MD_CTX_FLAG_CLEANED))
|
||||
ctx->digest->cleanup(ctx);
|
||||
if (ctx->digest && ctx->digest->ctx_size && ctx->md_data
|
||||
&& !M_EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE))
|
||||
{
|
||||
OPENSSL_cleanse(ctx->md_data,ctx->digest->ctx_size);
|
||||
OPENSSL_free(ctx->md_data);
|
||||
}
|
||||
memset(ctx,'\0',sizeof *ctx);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int FIPS_md_ctx_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in)
|
||||
{
|
||||
unsigned char *tmp_buf;
|
||||
if ((in == NULL) || (in->digest == NULL))
|
||||
{
|
||||
EVPerr(EVP_F_EVP_MD_CTX_COPY_EX,EVP_R_INPUT_NOT_INITIALIZED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (out->digest == in->digest)
|
||||
{
|
||||
tmp_buf = out->md_data;
|
||||
M_EVP_MD_CTX_set_flags(out,EVP_MD_CTX_FLAG_REUSE);
|
||||
}
|
||||
else tmp_buf = NULL;
|
||||
FIPS_md_ctx_cleanup(out);
|
||||
memcpy(out,in,sizeof *out);
|
||||
|
||||
if (in->md_data && out->digest->ctx_size)
|
||||
{
|
||||
if (tmp_buf)
|
||||
out->md_data = tmp_buf;
|
||||
else
|
||||
{
|
||||
out->md_data=OPENSSL_malloc(out->digest->ctx_size);
|
||||
if (!out->md_data)
|
||||
{
|
||||
EVPerr(EVP_F_EVP_MD_CTX_COPY_EX,ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
memcpy(out->md_data,in->md_data,out->digest->ctx_size);
|
||||
}
|
||||
|
||||
out->update = in->update;
|
||||
|
||||
if (out->digest->copy)
|
||||
return out->digest->copy(out,in);
|
||||
|
||||
return 1;
|
||||
}
|
Loading…
Reference in New Issue
Block a user