From 26188931147826e280c73ac2692081ce230885c6 Mon Sep 17 00:00:00 2001 From: Ben Laurie Date: Sun, 2 Sep 2001 20:05:27 +0000 Subject: [PATCH 1/1] Make MD functions take EVP_MD_CTX * instead of void *, add copy() function. --- CHANGES | 15 ++++ crypto/evp/Makefile.ssl | 10 ++- crypto/evp/digest.c | 30 ++++--- crypto/evp/evp.h | 23 +++-- crypto/evp/m_dss.c | 17 +++- crypto/evp/m_dss1.c | 17 +++- crypto/evp/m_md2.c | 17 +++- crypto/evp/m_md4.c | 17 +++- crypto/evp/m_md5.c | 17 +++- crypto/evp/m_mdc2.c | 17 +++- crypto/evp/m_null.c | 21 +++-- crypto/evp/m_ripemd.c | 17 +++- crypto/evp/m_sha.c | 17 +++- crypto/evp/m_sha1.c | 17 +++- crypto/evp/openbsd_hw.c | 190 +++++++++++++++++++++++++++------------- crypto/ex_data.c | 7 +- crypto/types.h | 1 + 17 files changed, 332 insertions(+), 118 deletions(-) diff --git a/CHANGES b/CHANGES index 6fad0cfb91..d5aa76976e 100644 --- a/CHANGES +++ b/CHANGES @@ -12,6 +12,21 @@ *) 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. diff --git a/crypto/evp/Makefile.ssl b/crypto/evp/Makefile.ssl index 7206baf764..0d3acd69ca 100644 --- a/crypto/evp/Makefile.ssl +++ b/crypto/evp/Makefile.ssl @@ -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 diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c index 1457a00118..c81f6e6cf8 100644 --- a/crypto/evp/digest.c +++ b/crypto/evp/digest.c @@ -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); diff --git a/crypto/evp/evp.h b/crypto/evp/evp.h index ef77db499e..7f798388f0 100644 --- a/crypto/evp/evp.h +++ b/crypto/evp/evp.h @@ -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); diff --git a/crypto/evp/m_dss.c b/crypto/evp/m_dss.c index 1a10f67658..f50b35b072 100644 --- a/crypto/evp/m_dss.c +++ b/crypto/evp/m_dss.c @@ -63,14 +63,25 @@ #include #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), diff --git a/crypto/evp/m_dss1.c b/crypto/evp/m_dss1.c index 115c432f94..be27d63da0 100644 --- a/crypto/evp/m_dss1.c +++ b/crypto/evp/m_dss1.c @@ -63,14 +63,25 @@ #include #include +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), diff --git a/crypto/evp/m_md2.c b/crypto/evp/m_md2.c index 442d234e32..8f95541c6a 100644 --- a/crypto/evp/m_md2.c +++ b/crypto/evp/m_md2.c @@ -64,14 +64,25 @@ #include #include +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), diff --git a/crypto/evp/m_md4.c b/crypto/evp/m_md4.c index 7b99ab8b9e..11458ee1cd 100644 --- a/crypto/evp/m_md4.c +++ b/crypto/evp/m_md4.c @@ -64,14 +64,25 @@ #include #include +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), diff --git a/crypto/evp/m_md5.c b/crypto/evp/m_md5.c index 3d3ec0f79b..69ec8aa027 100644 --- a/crypto/evp/m_md5.c +++ b/crypto/evp/m_md5.c @@ -64,14 +64,25 @@ #include #include +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), diff --git a/crypto/evp/m_mdc2.c b/crypto/evp/m_mdc2.c index f22b2cd5e9..d36a6e30b9 100644 --- a/crypto/evp/m_mdc2.c +++ b/crypto/evp/m_mdc2.c @@ -64,14 +64,25 @@ #include #include +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), diff --git a/crypto/evp/m_null.c b/crypto/evp/m_null.c index 8952709330..fa3a0301d9 100644 --- a/crypto/evp/m_null.c +++ b/crypto/evp/m_null.c @@ -62,20 +62,25 @@ #include #include -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 *), diff --git a/crypto/evp/m_ripemd.c b/crypto/evp/m_ripemd.c index 976d5e59c4..0bfc04c12f 100644 --- a/crypto/evp/m_ripemd.c +++ b/crypto/evp/m_ripemd.c @@ -64,14 +64,25 @@ #include #include +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), diff --git a/crypto/evp/m_sha.c b/crypto/evp/m_sha.c index 42309ebc46..acb7a44c5e 100644 --- a/crypto/evp/m_sha.c +++ b/crypto/evp/m_sha.c @@ -63,14 +63,25 @@ #include #include +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), diff --git a/crypto/evp/m_sha1.c b/crypto/evp/m_sha1.c index ddc9051794..ea54adad5b 100644 --- a/crypto/evp/m_sha1.c +++ b/crypto/evp/m_sha1.c @@ -63,14 +63,25 @@ #include #include +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), diff --git a/crypto/evp/openbsd_hw.c b/crypto/evp/openbsd_hw.c index 46bc885eb3..b4ac72dbcb 100644 --- a/crypto/evp/openbsd_hw.c +++ b/crypto/evp/openbsd_hw.c @@ -47,8 +47,6 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifdef OPENSSL_OPENBSD_DEV_CRYPTO - #include #include #include @@ -61,6 +59,9 @@ #include "evp_locl.h" #include +/* 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 diff --git a/crypto/ex_data.c b/crypto/ex_data.c index af8ee704d7..56bd8cf0c2 100644 --- a/crypto/ex_data.c +++ b/crypto/ex_data.c @@ -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 diff --git a/crypto/types.h b/crypto/types.h index 23bf47a741..310cf42f54 100644 --- a/crypto/types.h +++ b/crypto/types.h @@ -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; -- 2.34.1