From 0e36019977e78c34d6ea67b943fe17d4a01e769d Mon Sep 17 00:00:00 2001 From: Ben Laurie Date: Sat, 18 Aug 2001 13:53:01 +0000 Subject: [PATCH] Add EVP test program. --- CHANGES | 3 + crypto/engine/engine.h | 4 + crypto/engine/engine_evp.c | 14 ++ crypto/evp/Makefile.ssl | 2 +- crypto/evp/evp.h | 15 ++- crypto/evp/evp_enc.c | 12 +- crypto/evp/evp_test.c | 255 +++++++++++++++++++++++++++++++++++++ crypto/evp/evptests.txt | 16 +++ crypto/evp/openbsd_hw.c | 3 +- test/Makefile.ssl | 28 +++- 10 files changed, 333 insertions(+), 19 deletions(-) create mode 100644 crypto/evp/evp_test.c create mode 100644 crypto/evp/evptests.txt diff --git a/CHANGES b/CHANGES index 52593b2e04..d7e86490bc 100644 --- a/CHANGES +++ b/CHANGES @@ -12,6 +12,9 @@ *) applies to 0.9.6a/0.9.6b/0.9.6c and 0.9.7 +) applies to 0.9.7 only + +) Add EVP test program. + [Ben Laurie] + +) Add symmetric cipher support to ENGINE. Expect the API to change! [Ben Laurie] diff --git a/crypto/engine/engine.h b/crypto/engine/engine.h index 9955582a62..0558f2018c 100644 --- a/crypto/engine/engine.h +++ b/crypto/engine/engine.h @@ -483,6 +483,10 @@ int ENGINE_clear_defaults(void); /* Instruct an engine to load any EVP ciphers it knows of */ /* XXX make this work via defaults? */ void ENGINE_load_engine_ciphers(ENGINE *e); +/* Get a particular cipher from a particular engine - NULL if the engine + * doesn't have it */ +const EVP_CIPHER *ENGINE_get_cipher_by_name(ENGINE *e,const char *name); + /* Obligatory error function. */ void ERR_load_ENGINE_strings(void); diff --git a/crypto/engine/engine_evp.c b/crypto/engine/engine_evp.c index ffd1bff8f6..b2fbdc68c2 100644 --- a/crypto/engine/engine_evp.c +++ b/crypto/engine/engine_evp.c @@ -96,3 +96,17 @@ void ENGINE_load_engine_ciphers(ENGINE *e) for(n=0 ; n < sk_ENGINE_EVP_CIPHER_num(e->ciphers) ; ++n) EVP_add_cipher(sk_ENGINE_EVP_CIPHER_value(e->ciphers,n)->cipher); } + +const EVP_CIPHER *ENGINE_get_cipher_by_name(ENGINE *e,const char *name) + { + int n; + + for(n=0 ; n < ENGINE_cipher_num(e) ; ++n) + { + const EVP_CIPHER *c=ENGINE_get_cipher(e,n); + + if(!strcmp(EVP_CIPHER_name(c),name)) + return c; + } + return NULL; + } diff --git a/crypto/evp/Makefile.ssl b/crypto/evp/Makefile.ssl index 1d92d8e84a..7206baf764 100644 --- a/crypto/evp/Makefile.ssl +++ b/crypto/evp/Makefile.ssl @@ -19,7 +19,7 @@ AR= ar r CFLAGS= $(INCLUDES) $(CFLAG) GENERAL=Makefile -TEST= +TEST=evp_test.c evptests.txt APPS= LIB=$(TOP)/libcrypto.a diff --git a/crypto/evp/evp.h b/crypto/evp/evp.h index 8feb6c7a1d..629782c8b8 100644 --- a/crypto/evp/evp.h +++ b/crypto/evp/evp.h @@ -387,6 +387,7 @@ typedef int (EVP_PBE_KEYGEN)(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, #define EVP_MD_CTX_type(e) EVP_MD_type((e)->digest) #define EVP_CIPHER_nid(e) ((e)->nid) +#define EVP_CIPHER_name(e) OBJ_nid2sn(EVP_CIPHER_nid(e)) #define EVP_CIPHER_block_size(e) ((e)->block_size) #define EVP_CIPHER_key_length(e) ((e)->key_len) #define EVP_CIPHER_iv_length(e) ((e)->iv_len) @@ -435,7 +436,6 @@ void BIO_set_md(BIO *,const EVP_MD *md); #define EVP_delete_digest_alias(alias) \ OBJ_NAME_remove(alias,OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS); - void EVP_MD_CTX_init(EVP_MD_CTX *ctx); int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx); EVP_MD_CTX *EVP_MD_CTX_create(void); @@ -457,21 +457,22 @@ int EVP_BytesToKey(const EVP_CIPHER *type,const EVP_MD *md, int datal, int count, unsigned char *key,unsigned char *iv); int EVP_EncryptInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *type, - unsigned char *key, unsigned char *iv); + const unsigned char *key, const unsigned char *iv); int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, - int *outl, unsigned char *in, int inl); + int *outl, const unsigned char *in, int inl); int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); int EVP_DecryptInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *type, - unsigned char *key, unsigned char *iv); + const unsigned char *key, const unsigned char *iv); int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, - int *outl, unsigned char *in, int inl); + int *outl, const unsigned char *in, int inl); int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl); int EVP_CipherInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *type, - unsigned char *key,unsigned char *iv,int enc); + const unsigned char *key,const unsigned char *iv, + int enc); int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, - int *outl, unsigned char *in, int inl); + int *outl, const unsigned char *in, int inl); int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl); int EVP_SignFinal(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s, diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c index 9abb9855ff..e4f9bf073b 100644 --- a/crypto/evp/evp_enc.c +++ b/crypto/evp/evp_enc.c @@ -73,7 +73,7 @@ void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx) } int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, - unsigned char *key, unsigned char *iv, int enc) + const unsigned char *key, const unsigned char *iv, int enc) { if(enc && (enc != -1)) enc = 1; if (cipher) @@ -133,7 +133,7 @@ int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, } int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, - unsigned char *in, int inl) + const unsigned char *in, int inl) { if (ctx->encrypt) return EVP_EncryptUpdate(ctx,out,outl,in,inl); @@ -148,19 +148,19 @@ int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) } int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, - unsigned char *key, unsigned char *iv) + const unsigned char *key, const unsigned char *iv) { return EVP_CipherInit(ctx, cipher, key, iv, 1); } int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, - unsigned char *key, unsigned char *iv) + const unsigned char *key, const unsigned char *iv) { return EVP_CipherInit(ctx, cipher, key, iv, 0); } int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, - unsigned char *in, int inl) + const unsigned char *in, int inl) { int i,j,bl; @@ -252,7 +252,7 @@ int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) } int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, - unsigned char *in, int inl) + const unsigned char *in, int inl) { int b; diff --git a/crypto/evp/evp_test.c b/crypto/evp/evp_test.c new file mode 100644 index 0000000000..811574b21b --- /dev/null +++ b/crypto/evp/evp_test.c @@ -0,0 +1,255 @@ +/* Written by Ben Laurie, 2001 */ +/* + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +static void hexdump(FILE *f,const char *title,const unsigned char *s,int l) + { + int n=0; + + fprintf(f,"%s",title); + for( ; n < l ; ++n) + { + if((n%16) == 0) + fprintf(f,"\n%04x",n); + fprintf(f," %02x",s[n]); + } + fprintf(f,"\n"); + } + +static int convert(unsigned char *s) + { + unsigned char *d; + + for(d=s ; *s ; s+=2,++d) + { + int n; + + if(!s[1]) + { + fprintf(stderr,"Odd number of hex digits!"); + exit(4); + } + sscanf((char *)s,"%2x",&n); + *d=(unsigned char)n; + } + return s-d; + } + +static unsigned char *ustrsep(char **p,const char *sep) + { return (unsigned char *)strsep((char **)p,sep); } + +static void test1(const EVP_CIPHER *c,const unsigned char *key,int kn, + const unsigned char *iv,int in, + const unsigned char *plaintext,int pn, + const unsigned char *ciphertext,int cn) + { + EVP_CIPHER_CTX ctx; + unsigned char out[4096]; + int outl,outl2; + + printf("Testing cipher %s\n",EVP_CIPHER_name(c)); + hexdump(stdout,"Key",key,kn); + if(in) + hexdump(stdout,"IV",iv,in); + hexdump(stdout,"Plaintext",plaintext,pn); + hexdump(stdout,"Ciphertext",ciphertext,cn); + + + if(kn != c->key_len) + { + fprintf(stderr,"Key length doesn't match, got %d expected %d\n",kn, + c->key_len); + exit(5); + } + + if(!EVP_EncryptInit(&ctx,c,key,iv)) + { + fprintf(stderr,"EncryptInit failed\n"); + exit(10); + } + EVP_CIPHER_CTX_set_padding(&ctx,0); + + if(!EVP_EncryptUpdate(&ctx,out,&outl,plaintext,pn)) + { + fprintf(stderr,"Encrypt failed\n"); + exit(6); + } + if(!EVP_EncryptFinal(&ctx,out+outl,&outl2)) + { + fprintf(stderr,"EncryptFinal failed\n"); + exit(7); + } + + if(outl+outl2 != cn) + { + fprintf(stderr,"Ciphertext length mismatch got %d expected %d\n", + outl+outl2,cn); + exit(8); + } + + if(memcmp(out,ciphertext,cn)) + { + fprintf(stderr,"Ciphertext mismatch\n"); + hexdump(stderr,"Got",out,cn); + hexdump(stderr,"Expected",ciphertext,cn); + exit(9); + } + + if(!EVP_DecryptInit(&ctx,c,key,iv)) + { + fprintf(stderr,"DecryptInit failed\n"); + exit(10); + } + EVP_CIPHER_CTX_set_padding(&ctx,0); + + if(!EVP_DecryptUpdate(&ctx,out,&outl,ciphertext,pn)) + { + fprintf(stderr,"Decrypt failed\n"); + exit(6); + } + if(!EVP_DecryptFinal(&ctx,out+outl,&outl2)) + { + fprintf(stderr,"DecryptFinal failed\n"); + exit(7); + } + + if(outl+outl2 != cn) + { + fprintf(stderr,"Plaintext length mismatch got %d expected %d\n", + outl+outl2,cn); + exit(8); + } + + if(memcmp(out,plaintext,cn)) + { + fprintf(stderr,"Plaintext mismatch\n"); + hexdump(stderr,"Got",out,cn); + hexdump(stderr,"Expected",plaintext,cn); + exit(9); + } + + printf("\n"); + } + +int main(int argc,char **argv) + { + const char *szTestFile; + FILE *f; + + if(argc != 2) + { + fprintf(stderr,"%s \n",argv[0]); + exit(1); + } + + szTestFile=argv[1]; + + f=fopen(szTestFile,"r"); + if(!f) + { + perror(szTestFile); + exit(2); + } + + OpenSSL_add_all_ciphers(); + ENGINE_load_builtin_engines(); + + for( ; ; ) + { + char acLine[4096]; + char *p; + char *cipher; + unsigned char *iv,*key,*plaintext,*ciphertext; + const EVP_CIPHER *c; + int kn,in,pn,cn; + ENGINE *e; + + if(!fgets((char *)acLine,sizeof acLine,f)) + break; + if(acLine[0] == '#') + continue; + p=acLine; + cipher=strsep(&p,":"); + key=ustrsep(&p,":"); + iv=ustrsep(&p,":"); + plaintext=ustrsep(&p,":"); + ciphertext=ustrsep(&p,"\n"); + + c=EVP_get_cipherbyname(cipher); + if(!c) + { + fprintf(stderr,"Can't find cipher %s!\n",cipher); + exit(3); + } + + kn=convert(key); + in=convert(iv); + pn=convert(plaintext); + cn=convert(ciphertext); + + test1(c,key,kn,iv,in,plaintext,pn,ciphertext,cn); + + for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e)) + { + c=ENGINE_get_cipher_by_name(e,cipher); + if(!c) + continue; + printf("Testing engine %s\n",ENGINE_get_name(e)); + + test1(c,key,kn,iv,in,plaintext,pn,ciphertext,cn); + } + } + + + return 0; + } diff --git a/crypto/evp/evptests.txt b/crypto/evp/evptests.txt new file mode 100644 index 0000000000..05094a8d74 --- /dev/null +++ b/crypto/evp/evptests.txt @@ -0,0 +1,16 @@ +#cipher:key:iv:input:output +# AES 128 CBC tests (from NIST test vectors, encrypt) +#AES-128-CBC:00000000000000000000000000000000:00000000000000000000000000000000:00000000000000000000000000000000:8A05FC5E095AF4848A08D328D3688E3D +# AES 128 CBC tests (from NIST test vectors, decrypt) +#AES-128-CBC:00000000000000000000000000000000:00000000000000000000000000000000:FACA37E0B0C85373DF706E73F7C9AF86:00000000000000000000000000000000 +# DES ECB tests (from destest) +DES-ECB:0000000000000000::0000000000000000:8CA64DE9C1B123A7 +# DES EDE3 CBC tests (from destest) +DES-EDE3-CBC:0123456789abcdeff1e0d3c2b5a49786fedcba9876543210:fedcba9876543210:37363534333231204E6F77206973207468652074696D6520666F722000000000:3FE301C962AC01D02213763C1CBD4CDC799657C064ECF5D41C673812CFDE9675 +# RC4 tests (from rc4test) +RC4:0123456789abcdef0123456789abcdef::0123456789abcdef:75b7878099e0c596 +RC4:0123456789abcdef0123456789abcdef::0000000000000000:7494c2e7104b0879 +RC4:00000000000000000000000000000000::0000000000000000:de188941a3375d3a +RC4:ef012345ef012345ef012345ef012345::0000000000000000000000000000000000000000:d6a141a7ec3c38dfbd615a1162e1c7ba36b67858 +RC4:0123456789abcdef0123456789abcdef::123456789ABCDEF0123456789ABCDEF0123456789ABCDEF012345678:66a0949f8af7d6891f7f832ba833c00c892ebe30143ce28740011ecf +RC4:ef012345ef012345ef012345ef012345::00000000000000000000:d6a141a7ec3c38dfbd61 diff --git a/crypto/evp/openbsd_hw.c b/crypto/evp/openbsd_hw.c index e60eafcefb..7de06ba171 100644 --- a/crypto/evp/openbsd_hw.c +++ b/crypto/evp/openbsd_hw.c @@ -1,5 +1,6 @@ +/* Written by Ben Laurie, 2001 */ /* - * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/test/Makefile.ssl b/test/Makefile.ssl index a0c33a363c..91e093ec9d 100644 --- a/test/Makefile.ssl +++ b/test/Makefile.ssl @@ -56,6 +56,7 @@ METHTEST= methtest SSLTEST= ssltest RSATEST= rsa_test ENGINETEST= enginetest +EVPTEST= evp_test TESTS= alltests @@ -63,7 +64,8 @@ EXE= $(BNTEST) $(ECTEST) $(IDEATEST) $(MD2TEST) $(MD4TEST) $(MD5TEST) $(HMACTES $(RC2TEST) $(RC4TEST) $(RC5TEST) \ $(DESTEST) $(SHATEST) $(SHA1TEST) $(MDC2TEST) $(RMDTEST) \ $(RANDTEST) $(DHTEST) $(ENGINETEST) \ - $(BFTEST) $(CASTTEST) $(SSLTEST) $(EXPTEST) $(DSATEST) $(RSATEST) + $(BFTEST) $(CASTTEST) $(SSLTEST) $(EXPTEST) $(DSATEST) $(RSATEST) \ + $(EVPTEST) # $(METHTEST) @@ -72,13 +74,15 @@ OBJ= $(BNTEST).o $(ECTEST).o $(IDEATEST).o $(MD2TEST).o $(MD4TEST).o $(MD5TEST). $(RC2TEST).o $(RC4TEST).o $(RC5TEST).o \ $(DESTEST).o $(SHATEST).o $(SHA1TEST).o $(MDC2TEST).o $(RMDTEST).o \ $(RANDTEST).o $(DHTEST).o $(ENGINETEST).o $(CASTTEST).o \ - $(BFTEST).o $(SSLTEST).o $(DSATEST).o $(EXPTEST).o $(RSATEST).o + $(BFTEST).o $(SSLTEST).o $(DSATEST).o $(EXPTEST).o $(RSATEST).o \ + $(EVPTEST).o SRC= $(BNTEST).c $(ECTEST).c $(IDEATEST).c $(MD2TEST).c $(MD4TEST).c $(MD5TEST).c \ $(HMACTEST).c \ $(RC2TEST).c $(RC4TEST).c $(RC5TEST).c \ $(DESTEST).c $(SHATEST).c $(SHA1TEST).c $(MDC2TEST).c $(RMDTEST).c \ $(RANDTEST).c $(DHTEST).c $(ENGINETEST).c $(CASTTEST).c \ - $(BFTEST).c $(SSLTEST).c $(DSATEST).c $(EXPTEST).c $(RSATEST).c + $(BFTEST).c $(SSLTEST).c $(DSATEST).c $(EXPTEST).c $(RSATEST).c \ + $(EVPTEST).c EXHEADER= HEADER= $(EXHEADER) @@ -116,7 +120,10 @@ alltests: \ test_rmd test_rc2 test_rc4 test_rc5 test_bf test_cast test_rd \ test_rand test_bn test_ec test_enc test_x509 test_rsa test_crl test_sid \ test_gen test_req test_pkcs7 test_verify test_dh test_dsa \ - test_ss test_ca test_engine test_ssl + test_ss test_ca test_engine test_ssl test_evp + +test_evp: + ./$(EVPTEST) evptests.txt test_des: ./$(DESTEST) @@ -342,6 +349,9 @@ $(SSLTEST): $(SSLTEST).o $(DLIBSSL) $(DLIBCRYPTO) $(ENGINETEST): $(ENGINETEST).o $(DLIBCRYPTO) $(CC) -o $(ENGINETEST) $(CFLAGS) $(ENGINETEST).o $(PEX_LIBS) $(LIBCRYPTO) $(EX_LIBS) +$(EVPTEST): $(EVPTEST).o $(DLIBCRYPTO) + $(CC) -o $(EVPTEST) $(CFLAGS) $(EVPTEST).o $(PEX_LIBS) $(LIBCRYPTO) $(EX_LIBS) + #$(RDTEST).o: $(RDTEST).c # $(CC) -c $(CFLAGS) -DINTERMEDIATE_VALUE_KAT -DTRACE_KAT_MCT $(RDTEST).c @@ -401,6 +411,16 @@ enginetest.o: ../include/openssl/rand.h ../include/openssl/rsa.h enginetest.o: ../include/openssl/safestack.h ../include/openssl/stack.h enginetest.o: ../include/openssl/symhacks.h ../include/openssl/types.h enginetest.o: ../include/openssl/ui.h enginetest.c +evp_test.o: ../include/openssl/asn1.h ../include/openssl/bio.h +evp_test.o: ../include/openssl/bn.h ../include/openssl/crypto.h +evp_test.o: ../include/openssl/dh.h ../include/openssl/dsa.h +evp_test.o: ../include/openssl/e_os2.h ../include/openssl/engine.h +evp_test.o: ../include/openssl/evp.h ../include/openssl/obj_mac.h +evp_test.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h +evp_test.o: ../include/openssl/opensslv.h ../include/openssl/rand.h +evp_test.o: ../include/openssl/rsa.h ../include/openssl/safestack.h +evp_test.o: ../include/openssl/stack.h ../include/openssl/symhacks.h +evp_test.o: ../include/openssl/types.h ../include/openssl/ui.h evp_test.c exptest.o: ../include/openssl/bio.h ../include/openssl/bn.h exptest.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h exptest.o: ../include/openssl/err.h ../include/openssl/lhash.h