Make MD functions take EVP_MD_CTX * instead of void *, add copy() function.
authorBen Laurie <ben@openssl.org>
Sun, 2 Sep 2001 20:05:27 +0000 (20:05 +0000)
committerBen Laurie <ben@openssl.org>
Sun, 2 Sep 2001 20:05:27 +0000 (20:05 +0000)
17 files changed:
CHANGES
crypto/evp/Makefile.ssl
crypto/evp/digest.c
crypto/evp/evp.h
crypto/evp/m_dss.c
crypto/evp/m_dss1.c
crypto/evp/m_md2.c
crypto/evp/m_md4.c
crypto/evp/m_md5.c
crypto/evp/m_mdc2.c
crypto/evp/m_null.c
crypto/evp/m_ripemd.c
crypto/evp/m_sha.c
crypto/evp/m_sha1.c
crypto/evp/openbsd_hw.c
crypto/ex_data.c
crypto/types.h

diff --git a/CHANGES b/CHANGES
index 6fad0cfb91f50f773ebfffe1a347b84b098a6b74..d5aa76976ea1aab9c23f0db5debbf8b6b4dd59a3 100644 (file)
--- a/CHANGES
+++ b/CHANGES
          *) applies to 0.9.6a/0.9.6b/0.9.6c and 0.9.7
          +) applies to 0.9.7 only
 
+  +) Add a copy() function to EVP_MD.
+     [Ben Laurie]
+
+  +) Make EVP_MD routines take a context pointer instead of just the
+     md_data voud pointer.
+     [Ben Laurie]
+
+  +) Add flags to EVP_MD and EVP_MD_CTX. EVP_MD_FLAG_ONESHOT indicates
+     that the digest can only process a single chunk of data
+     (typically because it is provided by a piece of
+     hardware). EVP_MD_CTX_FLAG_ONESHOT indicates that the application
+     is only going to provide a single chunk of data, and hence the
+     framework needn't accumulate the data for oneshot drivers.
+     [Ben Laurie]
+
   +) As with "ERR", make it possible to replace the underlying "ex_data"
      functions. This change also alters the storage and management of global
      ex_data state - it's now all inside ex_data.c and all "class" code (eg.
index 7206baf7649ccc720602bf039e2dc23863ce1f78..0d3acd69ca1705d42026b3609053b86ce0132fc4 100644 (file)
@@ -513,7 +513,15 @@ names.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
 names.o: ../../include/openssl/symhacks.h ../../include/openssl/types.h
 names.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
 names.o: ../cryptlib.h names.c
-openbsd_hw.o: openbsd_hw.c
+openbsd_hw.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+openbsd_hw.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+openbsd_hw.o: ../../include/openssl/e_os2.h ../../include/openssl/evp.h
+openbsd_hw.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+openbsd_hw.o: ../../include/openssl/opensslconf.h
+openbsd_hw.o: ../../include/openssl/opensslv.h ../../include/openssl/rsa.h
+openbsd_hw.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+openbsd_hw.o: ../../include/openssl/symhacks.h ../../include/openssl/types.h
+openbsd_hw.o: evp_locl.h openbsd_hw.c
 p5_crpt.o: ../../e_os.h ../../include/openssl/asn1.h
 p5_crpt.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
 p5_crpt.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
index 1457a001185d8f6910d9f82ea2fed36cef39730f..c81f6e6cf8e8410b2b7567453f9073e7d3a5fbaf 100644 (file)
@@ -84,29 +84,30 @@ int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type)
        {
        if(ctx->digest != type)
                {
-               if(ctx->md_data != NULL)
+               if(ctx->digest && ctx->digest->ctx_size)
                        OPENSSL_free(ctx->md_data);
                ctx->digest=type;
+               if(type->ctx_size)
 #ifdef CRYPTO_MDEBUG
-               ctx->md_data=CRYPTO_malloc(type->ctx_size,file,line);
+                       ctx->md_data=CRYPTO_malloc(type->ctx_size,file,line);
 #else
-               ctx->md_data=OPENSSL_malloc(type->ctx_size);
+                       ctx->md_data=OPENSSL_malloc(type->ctx_size);
 #endif
                }
-       return type->init(ctx->md_data);
+       return type->init(ctx);
        }
 
 int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data,
             unsigned int count)
        {
-       return ctx->digest->update(ctx->md_data,data,(unsigned long)count);
+       return ctx->digest->update(ctx,data,(unsigned long)count);
        }
 
 /* The caller can assume that this removes any secret data from the context */
 int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
        {
        int ret;
-       ret=ctx->digest->final(md,ctx->md_data);
+       ret=ctx->digest->final(ctx,md);
        if (size != NULL)
                *size=ctx->digest->md_size;
        /* FIXME: add a cleanup function to the ctx? */
@@ -120,11 +121,19 @@ int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in)
         EVPerr(EVP_F_EVP_MD_CTX_COPY,EVP_R_INPUT_NOT_INITIALIZED);
        return 0;
     }
+
     EVP_MD_CTX_cleanup(out);
     memcpy(out,in,sizeof *out);
-    out->md_data=OPENSSL_malloc(out->digest->ctx_size);
-    /* FIXME: we really need a per-MD copy function */
-    memcpy(out->md_data,in->md_data,out->digest->ctx_size);
+
+    if(out->digest->ctx_size)
+       {
+       out->md_data=OPENSSL_malloc(out->digest->ctx_size);
+       memcpy(out->md_data,in->md_data,out->digest->ctx_size);
+       }
+
+    if(out->digest->copy)
+       return out->digest->copy(out,in);
+
     return 1;
 }
 
@@ -135,6 +144,7 @@ int EVP_Digest(void *data, unsigned int count,
        int ret;
 
        EVP_MD_CTX_init(&ctx);
+       EVP_MD_CTX_set_flags(&ctx,EVP_MD_CTX_FLAG_ONESHOT);
        ret=EVP_DigestInit(&ctx, type)
          && EVP_DigestUpdate(&ctx, data, count)
          && EVP_DigestFinal(&ctx, md, size);
@@ -155,7 +165,7 @@ int EVP_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->md_data)
+       if(ctx->digest && ctx->digest->ctx_size && ctx->md_data)
                {
                memset(ctx->md_data,0,ctx->digest->ctx_size);
                OPENSSL_free(ctx->md_data);
index ef77db499e4fdc1e844419ab82627f95ced7966b..7f798388f0d9e16f5ac08fd76a1df170b2c5d5f8 100644 (file)
@@ -217,10 +217,13 @@ struct env_md_st
        int type;
        int pkey_type;
        int md_size;
-       int (*init)();
-       int (*update)();
-       int (*final)();
+       unsigned long flags;
+       int (*init)(EVP_MD_CTX *ctx);
+       int (*update)(EVP_MD_CTX *ctx,const void *data,unsigned long count);
+       int (*final)(EVP_MD_CTX *ctx,unsigned char *md);
+       int (*copy)(EVP_MD_CTX *to,const EVP_MD_CTX *from);
 
+       /* FIXME: prototype these some day */
        int (*sign)();
        int (*verify)();
        int required_pkey_type[5]; /*EVP_PKEY_xxx */
@@ -228,7 +231,8 @@ struct env_md_st
        int ctx_size; /* how big does the ctx->md_data need to be */
        } /* EVP_MD */;
 
-
+#define EVP_MD_FLAG_ONESHOT    0x0001 /* digest can only handle a single
+                                       * block */
 
 #define EVP_PKEY_NULL_method   NULL,NULL,{0,0,0,0}
 
@@ -254,11 +258,17 @@ struct env_md_st
 
 #endif /* !EVP_MD */
 
-typedef struct env_md_ctx_st
+struct env_md_ctx_st
        {
        const EVP_MD *digest;
+       unsigned long flags;
        void *md_data;
-       } EVP_MD_CTX;
+       } /* EVP_MD_CTX */;
+
+/* values for EVP_MD_CTX flags */
+
+#define EVP_MD_CTX_FLAG_ONESHOT                0x0001 /* digest update will be called
+                                               * once only */
 
 struct evp_cipher_st
        {
@@ -443,6 +453,7 @@ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx);
 EVP_MD_CTX *EVP_MD_CTX_create(void);
 void   EVP_MD_CTX_destroy(EVP_MD_CTX *ctx);
 int     EVP_MD_CTX_copy(EVP_MD_CTX *out,const EVP_MD_CTX *in);  
+#define EVP_MD_CTX_set_flags(ctx,flgs) ((ctx)->flags|=(flgs))
 #ifdef CRYPTO_MDEBUG
 int    EVP_DigestInit_dbg(EVP_MD_CTX *ctx, const EVP_MD *type,
                           const char *file,int line);
index 1a10f676587bc6877139f595c836fb1fa016c9c1..f50b35b07239c0e0427302c127d4f843e601e7e8 100644 (file)
 #include <openssl/x509.h>
 
 #ifndef OPENSSL_NO_SHA
+static int init(EVP_MD_CTX *ctx)
+       { return SHA1_Init(ctx->md_data); }
+
+static int update(EVP_MD_CTX *ctx,const void *data,unsigned long 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 dsa_md=
        {
        NID_dsaWithSHA,
        NID_dsaWithSHA,
        SHA_DIGEST_LENGTH,
-       SHA1_Init,
-       SHA1_Update,
-       SHA1_Final,
+       0,
+       init,
+       update,
+       final,
+       NULL,
        EVP_PKEY_DSA_method,
        SHA_CBLOCK,
        sizeof(EVP_MD *)+sizeof(SHA_CTX),
index 115c432f94618fba8e62d775217af5e1f2ad734d..be27d63da05946568690317fa571b210284a2fe9 100644 (file)
 #include <openssl/objects.h>
 #include <openssl/x509.h>
 
+static int init(EVP_MD_CTX *ctx)
+       { return SHA1_Init(ctx->md_data); }
+
+static int update(EVP_MD_CTX *ctx,const void *data,unsigned long 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 dss1_md=
        {
        NID_dsa,
        NID_dsaWithSHA1,
        SHA_DIGEST_LENGTH,
-       SHA1_Init,
-       SHA1_Update,
-       SHA1_Final,
+       0,
+       init,
+       update,
+       final,
+       NULL,
        EVP_PKEY_DSA_method,
        SHA_CBLOCK,
        sizeof(EVP_MD *)+sizeof(SHA_CTX),
index 442d234e320ed61e8983f2ba21987d082da4fc1d..8f95541c6a30af69cdf24574d88994ff3dc8ef37 100644 (file)
 #include <openssl/x509.h>
 #include <openssl/md2.h>
 
+static int init(EVP_MD_CTX *ctx)
+       { return MD2_Init(ctx->md_data); }
+
+static int update(EVP_MD_CTX *ctx,const void *data,unsigned long count)
+       { return MD2_Update(ctx->md_data,data,count); }
+
+static int final(EVP_MD_CTX *ctx,unsigned char *md)
+       { return MD2_Final(md,ctx->md_data); }
+
 static const EVP_MD md2_md=
        {
        NID_md2,
        NID_md2WithRSAEncryption,
        MD2_DIGEST_LENGTH,
-       MD2_Init,
-       MD2_Update,
-       MD2_Final,
+       0,
+       init,
+       update,
+       final,
+       NULL,
        EVP_PKEY_RSA_method,
        MD2_BLOCK,
        sizeof(EVP_MD *)+sizeof(MD2_CTX),
index 7b99ab8b9e6f04cd5568a65bff85a242b7a2bc92..11458ee1cd4d77b366d01ea0ed91aebaad1bd0ba 100644 (file)
 #include <openssl/x509.h>
 #include <openssl/md4.h>
 
+static int init(EVP_MD_CTX *ctx)
+       { return MD4_Init(ctx->md_data); }
+
+static int update(EVP_MD_CTX *ctx,const void *data,unsigned long count)
+       { return MD4_Update(ctx->md_data,data,count); }
+
+static int final(EVP_MD_CTX *ctx,unsigned char *md)
+       { return MD4_Final(md,ctx->md_data); }
+
 static const EVP_MD md4_md=
        {
        NID_md4,
        0,
        MD4_DIGEST_LENGTH,
-       MD4_Init,
-       MD4_Update,
-       MD4_Final,
+       0,
+       init,
+       update,
+       final,
+       NULL,
        EVP_PKEY_RSA_method,
        MD4_CBLOCK,
        sizeof(EVP_MD *)+sizeof(MD4_CTX),
index 3d3ec0f79ba1ffe0b796382643a115f74eb8b2ab..69ec8aa027fa13d07577b0c9cc8dba7ef7eea550 100644 (file)
 #include <openssl/x509.h>
 #include <openssl/md5.h>
 
+static int init(EVP_MD_CTX *ctx)
+       { return MD5_Init(ctx->md_data); }
+
+static int update(EVP_MD_CTX *ctx,const void *data,unsigned long count)
+       { return MD5_Update(ctx->md_data,data,count); }
+
+static int final(EVP_MD_CTX *ctx,unsigned char *md)
+       { return MD5_Final(md,ctx->md_data); }
+
 static const EVP_MD md5_md=
        {
        NID_md5,
        NID_md5WithRSAEncryption,
        MD5_DIGEST_LENGTH,
-       MD5_Init,
-       MD5_Update,
-       MD5_Final,
+       0,
+       init,
+       update,
+       final,
+       NULL,
        EVP_PKEY_RSA_method,
        MD5_CBLOCK,
        sizeof(EVP_MD *)+sizeof(MD5_CTX),
index f22b2cd5e988c036373fad716af3a5fd59baf851..d36a6e30b9724535b079dd9c77ab2d32480451f4 100644 (file)
 #include <openssl/x509.h>
 #include <openssl/mdc2.h>
 
+static int init(EVP_MD_CTX *ctx)
+       { return MDC2_Init(ctx->md_data); }
+
+static int update(EVP_MD_CTX *ctx,const void *data,unsigned long count)
+       { return MDC2_Update(ctx->md_data,data,count); }
+
+static int final(EVP_MD_CTX *ctx,unsigned char *md)
+       { return MDC2_Final(md,ctx->md_data); }
+
 static const EVP_MD mdc2_md=
        {
        NID_mdc2,
        NID_mdc2WithRSA,
        MDC2_DIGEST_LENGTH,
-       MDC2_Init,
-       MDC2_Update,
-       MDC2_Final,
+       0,
+       init,
+       update,
+       final,
+       NULL,
        EVP_PKEY_RSA_ASN1_OCTET_STRING_method,
        MDC2_BLOCK,
        sizeof(EVP_MD *)+sizeof(MDC2_CTX),
index 8952709330c052323deb891543db4f37e7a89818..fa3a0301d974e98c86cf6ca2206349e1cd11fd49 100644 (file)
 #include <openssl/objects.h>
 #include <openssl/x509.h>
 
-static int function(void)
-       {
-       return 1;
-       }
+static int init(EVP_MD_CTX *ctx)
+       { return 1; }
+
+static int update(EVP_MD_CTX *ctx,const void *data,unsigned long count)
+       { return 1; }
+
+static int final(EVP_MD_CTX *ctx,unsigned char *md)
+       { return 1; }
 
 static const EVP_MD null_md=
        {
        NID_undef,
        NID_undef,
        0,
-       function,
-       function,
-       function,
-       
+       0,
+       init,
+       update,
+       final,
+       NULL,
        EVP_PKEY_NULL_method,
        0,
        sizeof(EVP_MD *),
index 976d5e59c4653fee32e3021e5ac57895c8388fd6..0bfc04c12fa9042e9dfc0f886db9564b4a5831cc 100644 (file)
 #include <openssl/objects.h>
 #include <openssl/x509.h>
 
+static int init(EVP_MD_CTX *ctx)
+       { return RIPEMD160_Init(ctx->md_data); }
+
+static int update(EVP_MD_CTX *ctx,const void *data,unsigned long count)
+       { return RIPEMD160_Update(ctx->md_data,data,count); }
+
+static int final(EVP_MD_CTX *ctx,unsigned char *md)
+       { return RIPEMD160_Final(md,ctx->md_data); }
+
 static const EVP_MD ripemd160_md=
        {
        NID_ripemd160,
        NID_ripemd160WithRSA,
        RIPEMD160_DIGEST_LENGTH,
-       RIPEMD160_Init,
-       RIPEMD160_Update,
-       RIPEMD160_Final,
+       0,
+       init,
+       update,
+       final,
+       NULL,
        EVP_PKEY_RSA_method,
        RIPEMD160_CBLOCK,
        sizeof(EVP_MD *)+sizeof(RIPEMD160_CTX),
index 42309ebc4648cc1ac4d5f6a21e9eb07e06801e61..acb7a44c5ebe49cc2b93d4fd94fe9b5fced76fc7 100644 (file)
 #include <openssl/objects.h>
 #include <openssl/x509.h>
 
+static int init(EVP_MD_CTX *ctx)
+       { return SHA_Init(ctx->md_data); }
+
+static int update(EVP_MD_CTX *ctx,const void *data,unsigned long count)
+       { return SHA_Update(ctx->md_data,data,count); }
+
+static int final(EVP_MD_CTX *ctx,unsigned char *md)
+       { return SHA_Final(md,ctx->md_data); }
+
 static const EVP_MD sha_md=
        {
        NID_sha,
        NID_shaWithRSAEncryption,
        SHA_DIGEST_LENGTH,
-       SHA_Init,
-       SHA_Update,
-       SHA_Final,
+       0,
+       init,
+       update,
+       final,
+       NULL,
        EVP_PKEY_RSA_method,
        SHA_CBLOCK,
        sizeof(EVP_MD *)+sizeof(SHA_CTX),
index ddc905179441f2ef95e1803877af18fb61be2832..ea54adad5b927ab63af81b6ef6bbfc73fbf68d79 100644 (file)
 #include <openssl/objects.h>
 #include <openssl/x509.h>
 
+static int init(EVP_MD_CTX *ctx)
+       { return SHA1_Init(ctx->md_data); }
+
+static int update(EVP_MD_CTX *ctx,const void *data,unsigned long 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,
-       SHA1_Init,
-       SHA1_Update,
-       SHA1_Final,
+       0,
+       init,
+       update,
+       final,
+       NULL,
        EVP_PKEY_RSA_method,
        SHA_CBLOCK,
        sizeof(EVP_MD *)+sizeof(SHA_CTX),
index 46bc885eb34bd7ccac530360fcd2173ab79b3fd3..b4ac72dbcbfe9e87ae1c5a1647b46cf79fb396a5 100644 (file)
@@ -47,8 +47,6 @@
  * OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifdef OPENSSL_OPENBSD_DEV_CRYPTO
-
 #include <fcntl.h>
 #include <stdio.h>
 #include <errno.h>
@@ -61,6 +59,9 @@
 #include "evp_locl.h"
 #include <assert.h>
 
+/* check flag after headers to ensure make depend works */
+#ifdef OPENSSL_OPENBSD_DEV_CRYPTO
+
 /* longest key supported in hardware */
 #define MAX_HW_KEY     24
 #define MAX_HW_IV      8
@@ -73,7 +74,7 @@ static int dev_failed;
 
 typedef struct session_op session_op;
 
-#define data(ctx) EVP_C_DATA(session_op,ctx)
+#define CDATA(ctx) EVP_C_DATA(session_op,ctx)
 
 static void err(const char *str)
     {
@@ -111,11 +112,10 @@ static int dev_crypto_init(session_op *ses)
 
 static int dev_crypto_cleanup(EVP_CIPHER_CTX *ctx)
     {
-    printf("Cleanup %d\n",data(ctx)->ses);
-    if(ioctl(fd,CIOCFSESSION,&data(ctx)->ses) == -1)
+    if(ioctl(fd,CIOCFSESSION,&CDATA(ctx)->ses) == -1)
        err("CIOCFSESSION failed");
 
-    OPENSSL_free(data(ctx)->key);
+    OPENSSL_free(CDATA(ctx)->key);
 
     return 1;
     }
@@ -123,40 +123,23 @@ static int dev_crypto_cleanup(EVP_CIPHER_CTX *ctx)
 static int dev_crypto_init_key(EVP_CIPHER_CTX *ctx,int cipher,
                               const unsigned char *key,int klen)
     {
-    if(!dev_crypto_init(data(ctx)))
+    if(!dev_crypto_init(CDATA(ctx)))
        return 0;
 
-    data(ctx)->key=OPENSSL_malloc(MAX_HW_KEY);
+    CDATA(ctx)->key=OPENSSL_malloc(MAX_HW_KEY);
 
     assert(ctx->cipher->iv_len <= MAX_HW_IV);
 
-    memcpy(data(ctx)->key,key,klen);
+    memcpy(CDATA(ctx)->key,key,klen);
     
-    data(ctx)->cipher=cipher;
-    data(ctx)->keylen=klen;
-
-    if (ioctl(fd,CIOCGSESSION,data(ctx)) == -1)
-       {
-       err("CIOCGSESSION failed");
-       return 0;
-       }
-    printf("Init %d\n",data(ctx)->ses);
-    return 1;
-    }
-
-static int dev_crypto_init_digest(session_op *ses,int mac)
-    {
-    if(!dev_crypto_init(ses))
-       return 0;
+    CDATA(ctx)->cipher=cipher;
+    CDATA(ctx)->keylen=klen;
 
-    ses->mac=mac;
-
-    if (ioctl(fd,CIOCGSESSION,ses) == -1)
+    if (ioctl(fd,CIOCGSESSION,CDATA(ctx)) == -1)
        {
        err("CIOCGSESSION failed");
        return 0;
        }
-    printf("Init MAC %d\n",ses->ses);
     return 1;
     }
 
@@ -169,11 +152,11 @@ static int dev_crypto_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
     if(!inl)
        return 1;
 
-    assert(data(ctx));
+    assert(CDATA(ctx));
     assert(!dev_failed);
 
     memset(&cryp,'\0',sizeof cryp);
-    cryp.ses=data(ctx)->ses;
+    cryp.ses=CDATA(ctx)->ses;
     cryp.op=ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT;
     cryp.flags=0;
     cryp.len=inl;
@@ -281,54 +264,137 @@ static const EVP_CIPHER r4_cipher=
 const EVP_CIPHER *EVP_dev_crypto_rc4(void)
     { return &r4_cipher; }
 
-static int dev_crypto_md5_init(void *md_data)
-    { return dev_crypto_init_digest(md_data,CRYPTO_MD5); }
+typedef struct
+    {
+    session_op sess;
+    char *data;
+    int len;
+    unsigned char md[EVP_MAX_MD_SIZE];
+    } MD_DATA;
 
-static int dev_crypto_md5_update(void *md_data,const void *data,
-                                unsigned long len)
+static int dev_crypto_init_digest(MD_DATA *md_data,int mac)
     {
-    struct crypt_op cryp;
-    session_op *ses=md_data;
-    char buf[MD5_DIGEST_LENGTH];
+    if(!dev_crypto_init(&md_data->sess))
+       return 0;
 
-    printf("update\n");
-    memset(&cryp,'\0',sizeof cryp);
-    cryp.ses=ses->ses;
-    cryp.len=len;
-    cryp.src=(caddr_t)data;
-    cryp.dst=buf;
+    md_data->len=0;
+    md_data->data=NULL;
 
-    if(ioctl(fd, CIOCCRYPT, &cryp) == -1)
+    md_data->sess.mac=mac;
+
+    if (ioctl(fd,CIOCGSESSION,&md_data->sess) == -1)
        {
-       err("CIOCCRYPT(MAC) failed");
-       abort();
+       err("CIOCGSESSION failed");
        return 0;
        }
-    printf("update done\n");
     return 1;
     }
 
-static int dev_crypto_md5_final(unsigned char *md,void *md_data)
+/* FIXME: if device can do chained MACs, then don't accumulate */
+/* FIXME: move accumulation to the framework */
+static int dev_crypto_md5_init(EVP_MD_CTX *ctx)
+    { return dev_crypto_init_digest(ctx->md_data,CRYPTO_MD5); }
+
+static int do_digest(int ses,unsigned char *md,const void *data,int len)
     {
     struct crypt_op cryp;
-    session_op *ses=md_data;
+    static unsigned char md5zero[16]=
+       {
+       0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,
+       0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,0x7e
+       };
+
+    /* some cards can't do zero length */
+    if(!len)
+       {
+       memcpy(md,md5zero,16);
+       return 1;
+       }
 
-    printf("final\n");
     memset(&cryp,'\0',sizeof cryp);
-    cryp.ses=ses->ses;
-    cryp.len=0;
+    cryp.ses=ses;
     cryp.op=COP_ENCRYPT;/* required to do the MAC rather than check it */
-    cryp.src=(caddr_t)md;
-    cryp.dst=(caddr_t)md;
+    cryp.len=len;
+    cryp.src=(caddr_t)data;
+    cryp.dst=(caddr_t)data; // FIXME!!!
+    cryp.mac=(caddr_t)md;
 
     if(ioctl(fd, CIOCCRYPT, &cryp) == -1)
        {
-       err("CIOCCRYPT(MAC,final) failed");
-       abort();
-       return 0;
+       if(errno == EINVAL) /* buffer is misaligned */
+           {
+           char *dcopy;
+
+           dcopy=OPENSSL_malloc(len);
+           memcpy(dcopy,data,len);
+           cryp.src=dcopy;
+           cryp.dst=cryp.src; // FIXME!!!
+
+           if(ioctl(fd, CIOCCRYPT, &cryp) == -1)
+               {
+               err("CIOCCRYPT(MAC2) failed");
+               abort();
+               return 0;
+               }
+           OPENSSL_free(dcopy);
+           }
+       else
+           {
+           err("CIOCCRYPT(MAC) failed");
+           abort();
+           return 0;
+           }
        }
+    printf("done\n");
+
+    return 1;
+    }
+
+static int dev_crypto_md5_update(EVP_MD_CTX *ctx,const void *data,
+                                unsigned long len)
+    {
+    MD_DATA *md_data=ctx->md_data;
+
+    if(ctx->flags&EVP_MD_CTX_FLAG_ONESHOT)
+       return do_digest(md_data->sess.ses,md_data->md,data,len);
+
+    md_data->data=OPENSSL_realloc(md_data->data,md_data->len+len);
+    memcpy(md_data->data+md_data->len,data,len);
+    md_data->len+=len;
+
+    return 1;
+    }  
+
+static int dev_crypto_md5_final(EVP_MD_CTX *ctx,unsigned char *md)
+    {
+    int ret;
+    MD_DATA *md_data=ctx->md_data;
+
+    if(ctx->flags&EVP_MD_CTX_FLAG_ONESHOT)
+       {
+       memcpy(md,md_data->md,MD5_DIGEST_LENGTH);
+       return 1;
+       }
+
+    ret=do_digest(md_data->sess.ses,md,md_data->data,md_data->len);
+    OPENSSL_free(md_data->data);
+    md_data->data=NULL;
+    md_data->len=0;
+
+    return ret;
+    }
+
+static int dev_crypto_md5_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from)
+    {
+    const MD_DATA *from_md=from->md_data;
+    MD_DATA *to_md=to->md_data;
+
+    // How do we copy sessions?
+    assert(from->digest->flags&EVP_MD_FLAG_ONESHOT);
+
+    to_md->data=OPENSSL_malloc(from_md->len);
+    memcpy(to_md->data,from_md->data,from_md->len);
 
-    printf("final done\n");
     return 1;
     }
 
@@ -337,17 +403,17 @@ static const EVP_MD md5_md=
     NID_md5,
     NID_md5WithRSAEncryption,
     MD5_DIGEST_LENGTH,
+    EVP_MD_FLAG_ONESHOT,       // XXX: set according to device info...
     dev_crypto_md5_init,
     dev_crypto_md5_update,
     dev_crypto_md5_final,
+    dev_crypto_md5_copy,
     EVP_PKEY_RSA_method,
     MD5_CBLOCK,
-    sizeof(session_op),
+    sizeof(MD_DATA),
     };
 
 const EVP_MD *EVP_dev_crypto_md5(void)
     { return &md5_md; }
 
-#else
-static void *dummy=&dummy;
 #endif
index af8ee704d740e16c4cee16f47fce7eecb623b847..56bd8cf0c288c90617427edb9929a87afea413ad 100644 (file)
@@ -226,9 +226,8 @@ static int ex_data_check(void)
 #define EX_DATA_CHECK(iffail) if(!ex_data && !ex_data_check()) {iffail}
 
 /* This "inner" callback is used by the callback function that follows it */
-static void def_cleanup_util_cb(void *a_void)
+static void def_cleanup_util_cb(CRYPTO_EX_DATA_FUNCS *v)
        {
-       CRYPTO_EX_DATA_FUNCS *v = (CRYPTO_EX_DATA_FUNCS *)a_void;
        OPENSSL_free(v);
        }
 
@@ -499,7 +498,7 @@ int CRYPTO_ex_data_new_class(void)
 void CRYPTO_cleanup_all_ex_data(void)
        {
        IMPL_CHECK
-       return EX_IMPL(cleanup)();
+       EX_IMPL(cleanup)();
        }
 
 /* Inside an existing class, get/register a new index. */
@@ -537,7 +536,7 @@ int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
 void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
        {
        IMPL_CHECK
-       return EX_IMPL(free_ex_data)(class_index, obj, ad);
+       EX_IMPL(free_ex_data)(class_index, obj, ad);
        }
 
 /* For a given CRYPTO_EX_DATA variable, set the value corresponding to a
index 23bf47a74198693a615b9744527d737812838160..310cf42f54ad09136eed6708cfee296309a72247 100644 (file)
@@ -96,6 +96,7 @@ typedef int ASN1_NULL;
 typedef struct evp_cipher_st EVP_CIPHER;
 typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX;
 typedef struct env_md_st EVP_MD;
+typedef struct env_md_ctx_st EVP_MD_CTX;
 typedef struct evp_pkey_st EVP_PKEY;
 
 typedef struct x509_st X509;