]> granicus.if.org Git - openssl/commitdiff
Add tiny ASN1 code for DSA signatures.
authorDr. Stephen Henson <steve@openssl.org>
Mon, 2 Apr 2007 23:59:47 +0000 (23:59 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Mon, 2 Apr 2007 23:59:47 +0000 (23:59 +0000)
Make DSA tests, selftests and algorithm tests use EVP.

12 files changed:
CHANGES
Makefile.org
crypto/dsa/dsa.h
crypto/dsa/dsa_asn1.c
crypto/evp/m_dss1.c
crypto/evp/m_sha1.c
crypto/rsa/rsa.h
fips-1.0/dsa/Makefile
fips-1.0/dsa/fips_dsa_selftest.c
fips-1.0/dsa/fips_dsatest.c
fips-1.0/dsa/fips_dssvs.c
fips-1.0/rsa/fips_rsa_sign.c

diff --git a/CHANGES b/CHANGES
index 68895177b9397d1b0d480064d419659e183ad03f..cbeaf193dc0e1a3bb8eca88d24721ac59a415862 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,11 @@
 
  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
index a897bde0880f341110a45a2f5b3a8e69a419bae2..76086f0def65e732956c53898708b2b164a4cdd2 100644 (file)
@@ -298,7 +298,6 @@ FIPS_EX_OBJ= ../crypto/aes/aes_cbc.o \
        ../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 \
index 74eb05acfea27004e999f790b67f3ed0047f7713..3b4c636d06f969874448d94b71c4e535c3ac7112 100644 (file)
@@ -265,6 +265,11 @@ int        DSA_print_fp(FILE *bp, const DSA *x, int off);
 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.
index c4e9b07eead90516a64447b67380e65d5fad2664..be8913d1e7a4339c992ef7c3ef9ac294097957f5 100644 (file)
@@ -196,3 +196,4 @@ err:
        DSA_SIG_free(s);
        return(ret);
        }
+
index c711bb2015229e1b6fa9904237817e634fba5f9a..da8babc147dd6010b9c6daaf6bc29c86713e6804 100644 (file)
@@ -68,6 +68,8 @@
 #include <openssl/dsa.h>
 #endif
 
+#ifndef OPENSSL_FIPS
+
 static int init(EVP_MD_CTX *ctx)
        { return SHA1_Init(ctx->md_data); }
 
@@ -82,7 +84,7 @@ static const EVP_MD dss1_md=
        NID_dsa,
        NID_dsaWithSHA1,
        SHA_DIGEST_LENGTH,
-       EVP_MD_FLAG_FIPS,
+       0,
        init,
        update,
        final,
@@ -98,3 +100,4 @@ const EVP_MD *EVP_dss1(void)
        return(&dss1_md);
        }
 #endif
+#endif
index 1e12c84c9685c861ed9cb8ba86115ca17d6ebc1b..471ec30be0139dd846c9ab2888002b4eb1efc371 100644 (file)
 #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); }
@@ -91,13 +84,13 @@ static const EVP_MD sha1_md=
        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),
        };
@@ -106,7 +99,6 @@ const EVP_MD *EVP_sha1(void)
        {
        return(&sha1_md);
        }
-#endif
 
 #ifndef OPENSSL_NO_SHA256
 static int init224(EVP_MD_CTX *ctx)
@@ -128,13 +120,13 @@ static const EVP_MD sha224_md=
        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),
        };
@@ -147,13 +139,13 @@ static const EVP_MD sha256_md=
        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),
        };
@@ -178,13 +170,13 @@ static const EVP_MD sha384_md=
        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),
        };
@@ -197,13 +189,13 @@ static const EVP_MD sha512_md=
        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),
        };
@@ -211,3 +203,7 @@ static const EVP_MD sha512_md=
 const EVP_MD *EVP_sha512(void)
        { return(&sha512_md); }
 #endif /* ifndef OPENSSL_NO_SHA512 */
+
+#endif
+
+#endif
index 1c247ed3229c7602863fada6c4f9620a8e74ead0..e36397bd5f7b9a8a68b10e18eada71b388ffc92e 100644 (file)
@@ -323,13 +323,6 @@ int RSA_sign(int type, const unsigned char *m, unsigned int m_length,
 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,
index 82375cd1b34df26822e3a3fbccfc4ac08ee97561..41a77754349e11c415c6dfa2271b91a3190c7848 100644 (file)
@@ -23,9 +23,9 @@ APPS=
 
 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)
 
index 7c10be65d4c247e81e026ce41bfd2de94221a618..bb4726226113a3e461db20b2fc19a61dd480fb6d 100644 (file)
@@ -61,6 +61,7 @@
 #include <openssl/dsa.h>
 #include <openssl/fips.h>
 #include <openssl/err.h>
+#include <openssl/evp.h>
 
 #ifdef OPENSSL_FIPS
 
@@ -109,74 +110,65 @@ void FIPS_corrupt_dsa()
 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
index a3b0cae4382b4e1f8fb1ce5532e5d51a295198c2..e9105d6297fe71116151fe59f64f878b71b592da 100644 (file)
@@ -139,20 +139,21 @@ static const unsigned char rnd_key2[]="abcdefgh";
 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);
@@ -214,22 +215,30 @@ int main(int argc, char **argv)
                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
index 5eda6daf0e66b6bfe37e8f10d24783e146433ebf..042edc001cd0059a0811f92c8d39c8a1c0113625 100644 (file)
@@ -14,6 +14,7 @@ int main()
 #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>
@@ -179,21 +180,34 @@ void siggen()
        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);
            }
        }
     }
@@ -203,6 +217,8 @@ void sigver()
     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];
@@ -241,8 +257,6 @@ void sigver()
            }
        else if(!strcmp(keyword,"Msg"))
            {
-           unsigned char msg[1024];
-           int n;
 
            n=hex2bin(value,msg);
            pv("Msg",msg,n);
@@ -254,13 +268,27 @@ void sigver()
            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);
            }
        }
index 7088357dbf45c2c5d1dfe690409373036605c555..b9880741a509ad503361cf9e60a0c8720ec2531c 100644 (file)
@@ -60,6 +60,9 @@
 #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
@@ -123,7 +126,7 @@ static const unsigned char *fips_digestinfo_encoding(int nid, unsigned int *len)
                }
        }
 
-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;
@@ -161,7 +164,8 @@ int FIPS_rsa_sign(int type, const unsigned char *m, unsigned int m_len,
                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
@@ -171,8 +175,9 @@ int FIPS_rsa_sign(int type, const unsigned char *m, unsigned int m_len,
        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;
@@ -198,7 +203,8 @@ int FIPS_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len,
                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;
 
@@ -229,3 +235,140 @@ 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