aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Laurie <ben@openssl.org>2001-09-02 20:05:27 +0000
committerBen Laurie <ben@openssl.org>2001-09-02 20:05:27 +0000
commit26188931147826e280c73ac2692081ce230885c6 (patch)
treecad4789b556b6ba313d41bd5c4a63f03b9a8a396
parent36026dfc0103b289b53b1ae9307cfd634b97afae (diff)
downloadopenssl-26188931147826e280c73ac2692081ce230885c6.tar.gz
Make MD functions take EVP_MD_CTX * instead of void *, add copy() function.
-rw-r--r--CHANGES15
-rw-r--r--crypto/evp/Makefile.ssl10
-rw-r--r--crypto/evp/digest.c30
-rw-r--r--crypto/evp/evp.h23
-rw-r--r--crypto/evp/m_dss.c17
-rw-r--r--crypto/evp/m_dss1.c17
-rw-r--r--crypto/evp/m_md2.c17
-rw-r--r--crypto/evp/m_md4.c17
-rw-r--r--crypto/evp/m_md5.c17
-rw-r--r--crypto/evp/m_mdc2.c17
-rw-r--r--crypto/evp/m_null.c21
-rw-r--r--crypto/evp/m_ripemd.c17
-rw-r--r--crypto/evp/m_sha.c17
-rw-r--r--crypto/evp/m_sha1.c17
-rw-r--r--crypto/evp/openbsd_hw.c190
-rw-r--r--crypto/ex_data.c7
-rw-r--r--crypto/types.h1
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 <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),
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 <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),
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 <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),
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 <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),
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 <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),
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 <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),
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 <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 *),
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 <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),
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 <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),
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 <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),
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 <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
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;