Make DSA tests, selftests and algorithm tests use EVP.
Changes between 0.9.8e and 0.9.8f-fips [xx XXX xxxx]
+ *) Add small standalone ASN1 encoder/decoder to handle DSA signature format.
+ Modify test, algorithm test and selftest routines to use EVP for DSA.
+ Move FIPS implementation of EVP_sha*() and EVP_dss1() under fips-1.0.
+ [Steve Henson]
+
*) Modify VC++ build system to rename .text and .rdata segments in
FIPS sources to .fipst${a,b,c}, and $fipsr${a,b,c} and place them
in a static library fipscanister.lib using a perl script. These are
../crypto/dsa/dsa_vrf.o \
../crypto/err/err.o \
../crypto/evp/digest.o \
- ../crypto/evp/m_sha1.o \
../crypto/evp/p_sign.o \
../crypto/evp/p_verify.o \
../crypto/mem_clr.o \
DH *DSA_dup_DH(const DSA *r);
#endif
+#ifdef OPENSSL_FIPS
+int FIPS_dsa_sig_encode(unsigned char *out, DSA_SIG *sig);
+int FIPS_dsa_sig_decode(DSA_SIG *sig, const unsigned char *in, int inlen);
+#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.
DSA_SIG_free(s);
return(ret);
}
+
#include <openssl/dsa.h>
#endif
+#ifndef OPENSSL_FIPS
+
static int init(EVP_MD_CTX *ctx)
{ return SHA1_Init(ctx->md_data); }
NID_dsa,
NID_dsaWithSHA1,
SHA_DIGEST_LENGTH,
- EVP_MD_FLAG_FIPS,
+ 0,
init,
update,
final,
return(&dss1_md);
}
#endif
+#endif
#include <openssl/rsa.h>
#endif
-#ifdef OPENSSL_FIPS
-#define EVP_PKEY_RSA_fips_method \
- (evp_sign_method *)FIPS_rsa_sign, \
- (evp_verify_method *) FIPS_rsa_verify, \
- {EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0}
-#else
-#define EVP_PKEY_RSA_fips_method EVP_PKEY_RSA_method
-#endif
+#ifndef OPENSSL_FIPS
static int init(EVP_MD_CTX *ctx)
{ return SHA1_Init(ctx->md_data); }
NID_sha1,
NID_sha1WithRSAEncryption,
SHA_DIGEST_LENGTH,
- EVP_MD_FLAG_FIPS,
+ 0,
init,
update,
final,
NULL,
NULL,
- EVP_PKEY_RSA_fips_method,
+ EVP_PKEY_RSA_method,
SHA_CBLOCK,
sizeof(EVP_MD *)+sizeof(SHA_CTX),
};
{
return(&sha1_md);
}
-#endif
#ifndef OPENSSL_NO_SHA256
static int init224(EVP_MD_CTX *ctx)
NID_sha224,
NID_sha224WithRSAEncryption,
SHA224_DIGEST_LENGTH,
- EVP_MD_FLAG_FIPS,
+ 0,
init224,
update256,
final256,
NULL,
NULL,
- EVP_PKEY_RSA_fips_method,
+ EVP_PKEY_RSA_method,
SHA256_CBLOCK,
sizeof(EVP_MD *)+sizeof(SHA256_CTX),
};
NID_sha256,
NID_sha256WithRSAEncryption,
SHA256_DIGEST_LENGTH,
- EVP_MD_FLAG_FIPS,
+ 0,
init256,
update256,
final256,
NULL,
NULL,
- EVP_PKEY_RSA_fips_method,
+ EVP_PKEY_RSA_method,
SHA256_CBLOCK,
sizeof(EVP_MD *)+sizeof(SHA256_CTX),
};
NID_sha384,
NID_sha384WithRSAEncryption,
SHA384_DIGEST_LENGTH,
- EVP_MD_FLAG_FIPS,
+ 0,
init384,
update512,
final512,
NULL,
NULL,
- EVP_PKEY_RSA_fips_method,
+ EVP_PKEY_RSA_method,
SHA512_CBLOCK,
sizeof(EVP_MD *)+sizeof(SHA512_CTX),
};
NID_sha512,
NID_sha512WithRSAEncryption,
SHA512_DIGEST_LENGTH,
- EVP_MD_FLAG_FIPS,
+ 0,
init512,
update512,
final512,
NULL,
NULL,
- EVP_PKEY_RSA_fips_method,
+ EVP_PKEY_RSA_method,
SHA512_CBLOCK,
sizeof(EVP_MD *)+sizeof(SHA512_CTX),
};
const EVP_MD *EVP_sha512(void)
{ return(&sha512_md); }
#endif /* ifndef OPENSSL_NO_SHA512 */
+
+#endif
+
+#endif
int RSA_verify(int type, const unsigned char *m, unsigned int m_length,
unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
-#ifdef OPENSSL_FIPS
-int FIPS_rsa_sign(int type, const unsigned char *m, unsigned int m_length,
- unsigned char *sigret, unsigned int *siglen, RSA *rsa);
-int FIPS_rsa_verify(int type, const unsigned char *m, unsigned int m_length,
- unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
-#endif
-
/* The following 2 function sign and verify a ASN1_OCTET_STRING
* object inside PKCS#1 padded RSA encryption */
int RSA_sign_ASN1_OCTET_STRING(int type,
LIB=$(TOP)/libcrypto.a
LIBSRC=fips_dsa_ossl.c fips_dsa_gen.c fips_dsa_selftest.c fips_dsa_key.c \
- fips_dsa_lib.c
+ fips_dsa_lib.c fips_dsa_sign.c
LIBOBJ=fips_dsa_ossl.o fips_dsa_gen.o fips_dsa_selftest.o fips_dsa_key.o \
- fips_dsa_lib.o
+ fips_dsa_lib.o fips_dsa_sign.o
SRC= $(LIBSRC)
#include <openssl/dsa.h>
#include <openssl/fips.h>
#include <openssl/err.h>
+#include <openssl/evp.h>
#ifdef OPENSSL_FIPS
int FIPS_selftest_dsa()
{
DSA *dsa=NULL;
- int counter,i,j;
+ int counter,i,j, ret = 0;
+ unsigned int slen;
unsigned char buf[256];
unsigned long h;
+ EVP_MD_CTX mctx;
+ EVP_PKEY pk;
- DSA_SIG *sig = NULL;
+ EVP_MD_CTX_init(&mctx);
dsa = FIPS_dsa_new();
if(dsa == NULL)
- {
- FIPSerr(FIPS_F_FIPS_SELFTEST_DSA,FIPS_R_SELFTEST_FAILED);
- return 0;
- }
+ goto err;
if(!DSA_generate_parameters_ex(dsa, 512,seed,20,&counter,&h,NULL))
- {
- FIPSerr(FIPS_F_FIPS_SELFTEST_DSA,FIPS_R_SELFTEST_FAILED);
- return 0;
- }
+ goto err;
if (counter != 105)
- {
- FIPSerr(FIPS_F_FIPS_SELFTEST_DSA,FIPS_R_SELFTEST_FAILED);
- return 0;
- }
+ goto err;
if (h != 2)
- {
- FIPSerr(FIPS_F_FIPS_SELFTEST_DSA,FIPS_R_SELFTEST_FAILED);
- return 0;
- }
+ goto err;
i=BN_bn2bin(dsa->q,buf);
j=sizeof(out_q);
if (i != j || memcmp(buf,out_q,i) != 0)
- {
- FIPSerr(FIPS_F_FIPS_SELFTEST_DSA,FIPS_R_SELFTEST_FAILED);
- return 0;
- }
+ goto err;
i=BN_bn2bin(dsa->p,buf);
j=sizeof(out_p);
if (i != j || memcmp(buf,out_p,i) != 0)
- {
- FIPSerr(FIPS_F_FIPS_SELFTEST_DSA,FIPS_R_SELFTEST_FAILED);
- return 0;
- }
+ goto err;
i=BN_bn2bin(dsa->g,buf);
j=sizeof(out_g);
if (i != j || memcmp(buf,out_g,i) != 0)
- {
- FIPSerr(FIPS_F_FIPS_SELFTEST_DSA,FIPS_R_SELFTEST_FAILED);
- return 0;
- }
+ goto err;
DSA_generate_key(dsa);
- sig = DSA_do_sign(str1, 20, dsa);
-
- if (sig)
- {
- i = DSA_do_verify(str1, 20, sig, dsa);
- DSA_SIG_free(sig);
- }
- else
- i = 0;
-
- if (i != 1)
- {
- FIPSerr(FIPS_F_FIPS_SELFTEST_DSA,FIPS_R_SELFTEST_FAILED);
- return 0;
- }
- FIPS_dsa_free(dsa);
- return 1;
+ pk.type = EVP_PKEY_DSA;
+ pk.pkey.dsa = dsa;
+
+ if (!EVP_SignInit_ex(&mctx, EVP_dss1(), NULL))
+ goto err;
+ if (!EVP_SignUpdate(&mctx, str1, 20))
+ goto err;
+ if (!EVP_SignFinal(&mctx, buf, &slen, &pk))
+ goto err;
+
+ if (!EVP_VerifyInit_ex(&mctx, EVP_dss1(), NULL))
+ goto err;
+ if (!EVP_VerifyUpdate(&mctx, str1, 20))
+ goto err;
+ if (EVP_VerifyFinal(&mctx, buf, slen, &pk) != 1)
+ goto err;
+
+ ret = 1;
+
+ err:
+ EVP_MD_CTX_cleanup(&mctx);
+ if (dsa)
+ FIPS_dsa_free(dsa);
+ if (ret == 0)
+ FIPSerr(FIPS_F_FIPS_SELFTEST_DSA,FIPS_R_SELFTEST_FAILED);
+ return ret;
}
#endif
int main(int argc, char **argv)
{
DSA *dsa=NULL;
+ EVP_PKEY pk;
int counter,ret=0,i,j;
+ unsigned int slen;
unsigned char buf[256];
unsigned long h;
- DSA_SIG *sig = NULL;
BN_GENCB cb;
+ EVP_MD_CTX mctx;
BN_GENCB_set(&cb, dsa_cb, stderr);
+ EVP_MD_CTX_init(&mctx);
-#ifdef OPENSSL_FIPS
if(!FIPS_mode_set(1))
{
do_print_errors();
EXIT(1);
}
-#endif
#if 0
CRYPTO_malloc_debug_init();
CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
goto end;
}
DSA_generate_key(dsa);
+ pk.type = EVP_PKEY_DSA;
+ pk.pkey.dsa = dsa;
- sig = DSA_do_sign(str1, 20, dsa);
+ if (!EVP_SignInit_ex(&mctx, EVP_dss1(), NULL))
+ goto end;
+ if (!EVP_SignUpdate(&mctx, str1, 20))
+ goto end;
+ if (!EVP_SignFinal(&mctx, buf, &slen, &pk))
+ goto end;
+
+ if (!EVP_VerifyInit_ex(&mctx, EVP_dss1(), NULL))
+ goto end;
+ if (!EVP_VerifyUpdate(&mctx, str1, 20))
+ goto end;
+ if (EVP_VerifyFinal(&mctx, buf, slen, &pk) != 1)
+ goto end;
+
+ ret = 1;
- if (sig)
- {
- i = DSA_do_verify(str1, 20, sig, dsa);
- DSA_SIG_free(sig);
- }
- else
- i = 0;
- if (i == 1)
- ret=1;
end:
if (!ret)
do_print_errors();
if (dsa != NULL) FIPS_dsa_free(dsa);
+ EVP_MD_CTX_cleanup(&mctx);
#if 0
CRYPTO_mem_leaks(bio_err);
#endif
#include <openssl/dsa.h>
#include <openssl/fips.h>
#include <openssl/err.h>
+#include <openssl/evp.h>
#include <openssl/fips_sha.h>
#include <string.h>
#include <ctype.h>
else if(!strcmp(keyword,"Msg"))
{
unsigned char msg[1024];
- unsigned char hash[20];
+ unsigned char sbuf[60];
+ unsigned int slen;
int n;
+ EVP_PKEY pk;
+ EVP_MD_CTX mctx;
DSA_SIG *sig;
+ EVP_MD_CTX_init(&mctx);
n=hex2bin(value,msg);
pv("Msg",msg,n);
DSA_generate_key(dsa);
+ pk.type = EVP_PKEY_DSA;
+ pk.pkey.dsa = dsa;
pbn("Y",dsa->pub_key);
- SHA1(msg,n,hash);
- sig=DSA_do_sign(hash,sizeof hash,dsa);
+ EVP_SignInit_ex(&mctx, EVP_dss1(), NULL);
+ EVP_SignUpdate(&mctx, msg, n);
+ EVP_SignFinal(&mctx, sbuf, &slen, &pk);
+
+ sig = DSA_SIG_new();
+ FIPS_dsa_sig_decode(sig, sbuf, slen);
+
pbn("R",sig->r);
pbn("S",sig->s);
putc('\n',stdout);
+ EVP_MD_CTX_cleanup(&mctx);
+ FIPS_dsa_free(dsa);
}
}
}
DSA *dsa=NULL;
char buf[1024];
char lbuf[1024];
+ unsigned char msg[1024];
+ int n;
char *keyword, *value;
int nmod=0;
unsigned char hash[20];
}
else if(!strcmp(keyword,"Msg"))
{
- unsigned char msg[1024];
- int n;
n=hex2bin(value,msg);
pv("Msg",msg,n);
sig->r=hex2bn(value);
else if(!strcmp(keyword,"S"))
{
+ EVP_MD_CTX mctx;
+ EVP_PKEY pk;
+ unsigned char sigbuf[60];
+ unsigned int slen;
+ int r;
+ EVP_MD_CTX_init(&mctx);
+ pk.type = EVP_PKEY_DSA;
+ pk.pkey.dsa = dsa;
sig->s=hex2bn(value);
pbn("Y",dsa->pub_key);
pbn("R",sig->r);
pbn("S",sig->s);
- printf("Result = %c\n",DSA_do_verify(hash,sizeof hash,sig,dsa)
- ? 'P' : 'F');
+
+ slen = FIPS_dsa_sig_encode(sigbuf, sig);
+ EVP_VerifyInit_ex(&mctx, EVP_dss1(), NULL);
+ EVP_VerifyUpdate(&mctx, msg, n);
+ r = EVP_VerifyFinal(&mctx, sigbuf, slen, &pk);
+ EVP_MD_CTX_cleanup(&mctx);
+
+ printf("Result = %c\n", r == 1 ? 'P' : 'F');
putc('\n',stdout);
}
}
#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
}
}
-int FIPS_rsa_sign(int type, const unsigned char *m, unsigned int m_len,
+static int fips_rsa_sign(int type, const unsigned char *m, unsigned int m_len,
unsigned char *sigret, unsigned int *siglen, RSA *rsa)
{
int i,j,ret=1;
RSAerr(RSA_F_RSA_SIGN,RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
return(0);
}
- j=RSA_private_encrypt(i,tmpdinfo,sigret,rsa,RSA_PKCS1_PADDING);
+ /* NB: call underlying method directly to avoid FIPS blocking */
+ j=rsa->meth->rsa_priv_enc(i,tmpdinfo,sigret,rsa,RSA_PKCS1_PADDING);
if (j <= 0)
ret=0;
else
return(ret);
}
-int FIPS_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len,
- unsigned char *sigbuf, unsigned int siglen, RSA *rsa)
+static int fips_rsa_verify(int dtype,
+ const unsigned char *m, unsigned int m_len,
+ unsigned char *sigbuf, unsigned int siglen, RSA *rsa)
{
int i,ret=0;
unsigned int dlen;
goto err;
}
- i=RSA_public_decrypt((int)siglen,sigbuf,s,rsa,RSA_PKCS1_PADDING);
+ /* NB: call underlying method directly to avoid FIPS blocking */
+ i=rsa->meth->rsa_pub_dec((int)siglen,sigbuf,s,rsa,RSA_PKCS1_PADDING);
if (i <= 0) goto err;
}
return(ret);
}
+
+#define EVP_PKEY_RSA_fips_method \
+ (evp_sign_method *)fips_rsa_sign, \
+ (evp_verify_method *)fips_rsa_verify, \
+ {EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0}
+
+static int init(EVP_MD_CTX *ctx)
+ { return SHA1_Init(ctx->md_data); }
+
+static int update(EVP_MD_CTX *ctx,const void *data,size_t count)
+ { return SHA1_Update(ctx->md_data,data,count); }
+
+static int final(EVP_MD_CTX *ctx,unsigned char *md)
+ { return SHA1_Final(md,ctx->md_data); }
+
+static const EVP_MD sha1_md=
+ {
+ NID_sha1,
+ NID_sha1WithRSAEncryption,
+ SHA_DIGEST_LENGTH,
+ EVP_MD_FLAG_FIPS,
+ init,
+ update,
+ final,
+ NULL,
+ NULL,
+ EVP_PKEY_RSA_fips_method,
+ SHA_CBLOCK,
+ sizeof(EVP_MD *)+sizeof(SHA_CTX),
+ };
+
+const EVP_MD *EVP_sha1(void)
+ {
+ return(&sha1_md);
+ }
+
+static int init224(EVP_MD_CTX *ctx)
+ { return SHA224_Init(ctx->md_data); }
+static int init256(EVP_MD_CTX *ctx)
+ { return SHA256_Init(ctx->md_data); }
+/*
+ * Even though there're separate SHA224_[Update|Final], we call
+ * SHA256 functions even in SHA224 context. This is what happens
+ * there anyway, so we can spare few CPU cycles:-)
+ */
+static int update256(EVP_MD_CTX *ctx,const void *data,size_t count)
+ { return SHA256_Update(ctx->md_data,data,count); }
+static int final256(EVP_MD_CTX *ctx,unsigned char *md)
+ { return SHA256_Final(md,ctx->md_data); }
+
+static const EVP_MD sha224_md=
+ {
+ NID_sha224,
+ NID_sha224WithRSAEncryption,
+ SHA224_DIGEST_LENGTH,
+ EVP_MD_FLAG_FIPS,
+ init224,
+ update256,
+ final256,
+ NULL,
+ NULL,
+ EVP_PKEY_RSA_fips_method,
+ SHA256_CBLOCK,
+ sizeof(EVP_MD *)+sizeof(SHA256_CTX),
+ };
+
+const EVP_MD *EVP_sha224(void)
+ { return(&sha224_md); }
+
+static const EVP_MD sha256_md=
+ {
+ NID_sha256,
+ NID_sha256WithRSAEncryption,
+ SHA256_DIGEST_LENGTH,
+ EVP_MD_FLAG_FIPS,
+ init256,
+ update256,
+ final256,
+ NULL,
+ NULL,
+ EVP_PKEY_RSA_fips_method,
+ SHA256_CBLOCK,
+ sizeof(EVP_MD *)+sizeof(SHA256_CTX),
+ };
+
+const EVP_MD *EVP_sha256(void)
+ { return(&sha256_md); }
+
+static int init384(EVP_MD_CTX *ctx)
+ { return SHA384_Init(ctx->md_data); }
+static int init512(EVP_MD_CTX *ctx)
+ { return SHA512_Init(ctx->md_data); }
+/* See comment in SHA224/256 section */
+static int update512(EVP_MD_CTX *ctx,const void *data,size_t count)
+ { return SHA512_Update(ctx->md_data,data,count); }
+static int final512(EVP_MD_CTX *ctx,unsigned char *md)
+ { return SHA512_Final(md,ctx->md_data); }
+
+static const EVP_MD sha384_md=
+ {
+ NID_sha384,
+ NID_sha384WithRSAEncryption,
+ SHA384_DIGEST_LENGTH,
+ EVP_MD_FLAG_FIPS,
+ init384,
+ update512,
+ final512,
+ NULL,
+ NULL,
+ EVP_PKEY_RSA_fips_method,
+ SHA512_CBLOCK,
+ sizeof(EVP_MD *)+sizeof(SHA512_CTX),
+ };
+
+const EVP_MD *EVP_sha384(void)
+ { return(&sha384_md); }
+
+static const EVP_MD sha512_md=
+ {
+ NID_sha512,
+ NID_sha512WithRSAEncryption,
+ SHA512_DIGEST_LENGTH,
+ EVP_MD_FLAG_FIPS,
+ init512,
+ update512,
+ final512,
+ NULL,
+ NULL,
+ EVP_PKEY_RSA_fips_method,
+ SHA512_CBLOCK,
+ sizeof(EVP_MD *)+sizeof(SHA512_CTX),
+ };
+
+const EVP_MD *EVP_sha512(void)
+ { return(&sha512_md); }
+
+#endif