From: Zhanna Tsitkov Date: Thu, 3 Sep 2009 18:33:13 +0000 (+0000) Subject: Crypto modularity proj: OpemSSL crypto feed for hmac/md5/md4/sha1/rc4/des/des3(w... X-Git-Tag: krb5-1.8-alpha1~364 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=65cc35ec82d56b8cd89751ddc5f68751271b985c;p=krb5.git Crypto modularity proj: OpemSSL crypto feed for hmac/md5/md4/sha1/rc4/des/des3(w/o iov) bigredbutton: whitespace git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@22709 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/include/k5-int.h b/src/include/k5-int.h index c2f112709..90b6d9cf7 100644 --- a/src/include/k5-int.h +++ b/src/include/k5-int.h @@ -675,6 +675,7 @@ struct krb5_enc_provider { }; struct krb5_hash_provider { + char hash_name[8]; size_t hashsize, blocksize; /* this takes multiple inputs to avoid lots of copying. */ diff --git a/src/lib/crypto/builtin/arcfour/Makefile.in b/src/lib/crypto/builtin/arcfour/Makefile.in index cf6c51153..499c0a076 100644 --- a/src/lib/crypto/builtin/arcfour/Makefile.in +++ b/src/lib/crypto/builtin/arcfour/Makefile.in @@ -12,20 +12,22 @@ DEFS= PROG_LIBPATH=-L$(TOPLIBD) PROG_RPATH=$(KRB5_LIBDIR) +CIMPL = @CRYPTO_IMPL@/arcfour + STLIBOBJS=\ - arcfour.o \ - arcfour_aead.o \ - arcfour_s2k.o + ../../$(CIMPL)/arcfour.o \ + ../../$(CIMPL)/arcfour_aead.o \ + ../../$(CIMPL)/arcfour_s2k.o OBJS=\ - $(OUTPRE)arcfour.$(OBJEXT) \ - $(OUTPRE)arcfour_aead.$(OBJEXT) \ - $(OUTPRE)arcfour_s2k.$(OBJEXT) + $(OUTPRE)../../$(CIMPL)/arcfour.$(OBJEXT) \ + $(OUTPRE)../../$(CIMPL)/arcfour_aead.$(OBJEXT) \ + $(OUTPRE)../../$(CIMPL)/arcfour_s2k.$(OBJEXT) SRCS=\ - $(srcdir)/arcfour.c \ - $(srcdir)/arcfour_aead.c\ - $(srcdir)/arcfour_s2k.c + $(srcdir)/../../$(CIMPL)/arcfour.c \ + $(srcdir)/../../$(CIMPL)/arcfour_aead.c\ + $(srcdir)/../../$(CIMPL)/arcfour_s2k.c ##DOS##LIBOBJS = $(OBJS) diff --git a/src/lib/crypto/crypto_tests/Makefile.in b/src/lib/crypto/crypto_tests/Makefile.in index 4e33e83b8..41704c85c 100644 --- a/src/lib/crypto/crypto_tests/Makefile.in +++ b/src/lib/crypto/crypto_tests/Makefile.in @@ -2,7 +2,7 @@ thisconfigdir=../../.. myfulldir=lib/crypto/crypto_tests mydir=lib/crypto/crypto_tests BUILDTOP=$(REL)..$(S)..$(S).. -LOCALINCLUDES = -I$(srcdir)/../krb -I$(srcdir)/../krb/enc_provider \ +LOCALINCLUDES = -I$(srcdir)/../krb -I$(srcdir)/../@CRYPTO_IMPL@/enc_provider \ -I$(srcdir)/../krb/hash_provider -I$(srcdir)/../krb/keyhash_provider \ -I$(srcdir)/../krb/dk -I$(srcdir)/../@CRYPTO_IMPL@/ \ -I$(srcdir)/../krb/yarrow \ diff --git a/src/lib/crypto/krb/deps b/src/lib/crypto/krb/deps index a84ee03cb..58a614bdf 100644 --- a/src/lib/crypto/krb/deps +++ b/src/lib/crypto/krb/deps @@ -192,7 +192,7 @@ etypes.so etypes.po $(OUTPRE)etypes.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ $(srcdir)/../builtin/aes/aes_s2k.h $(srcdir)/../builtin/arcfour/arcfour.h \ $(srcdir)/../builtin/des/des_int.h $(srcdir)/dk/dk.h \ - $(srcdir)/../builtin/../builtin/enc_provider/enc_provider.h $(srcdir)/hash_provider/hash_provider.h \ + $(srcdir)/../builtin/enc_provider/enc_provider.h $(srcdir)/hash_provider/hash_provider.h \ $(srcdir)/old/old.h $(srcdir)/raw/raw.h etypes.c etypes.h keyblocks.so keyblocks.po $(OUTPRE)keyblocks.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ diff --git a/src/lib/crypto/krb/hash_provider/hash_crc32.c b/src/lib/crypto/krb/hash_provider/hash_crc32.c index ca2681067..780e1589d 100644 --- a/src/lib/crypto/krb/hash_provider/hash_crc32.c +++ b/src/lib/crypto/krb/hash_provider/hash_crc32.c @@ -49,6 +49,7 @@ k5_crc32_hash(unsigned int icount, const krb5_data *input, } const struct krb5_hash_provider krb5int_hash_crc32 = { + "CRC32", CRC32_CKSUM_LENGTH, 1, k5_crc32_hash diff --git a/src/lib/crypto/krb/hash_provider/hash_md4.c b/src/lib/crypto/krb/hash_provider/hash_md4.c index 1fa23c214..f507aaaf7 100644 --- a/src/lib/crypto/krb/hash_provider/hash_md4.c +++ b/src/lib/crypto/krb/hash_provider/hash_md4.c @@ -49,6 +49,7 @@ k5_md4_hash(unsigned int icount, const krb5_data *input, } const struct krb5_hash_provider krb5int_hash_md4 = { + "MD4", RSA_MD4_CKSUM_LENGTH, 64, k5_md4_hash diff --git a/src/lib/crypto/krb/hash_provider/hash_md5.c b/src/lib/crypto/krb/hash_provider/hash_md5.c index 174c432a4..a6e380ae2 100644 --- a/src/lib/crypto/krb/hash_provider/hash_md5.c +++ b/src/lib/crypto/krb/hash_provider/hash_md5.c @@ -49,6 +49,7 @@ k5_md5_hash(unsigned int icount, const krb5_data *input, } const struct krb5_hash_provider krb5int_hash_md5 = { + "MD5", RSA_MD5_CKSUM_LENGTH, 64, k5_md5_hash diff --git a/src/lib/crypto/krb/hash_provider/hash_sha1.c b/src/lib/crypto/krb/hash_provider/hash_sha1.c index ffc073cf1..00ab72bda 100644 --- a/src/lib/crypto/krb/hash_provider/hash_sha1.c +++ b/src/lib/crypto/krb/hash_provider/hash_sha1.c @@ -51,6 +51,7 @@ k5_sha1_hash(unsigned int icount, const krb5_data *input, } const struct krb5_hash_provider krb5int_hash_sha1 = { + "SHA1", SHS_DIGESTSIZE, SHS_DATASIZE, k5_sha1_hash diff --git a/src/lib/crypto/openssl/enc_provider/deps b/src/lib/crypto/openssl/enc_provider/deps new file mode 100644 index 000000000..1d4dcbe97 --- /dev/null +++ b/src/lib/crypto/openssl/enc_provider/deps @@ -0,0 +1,50 @@ +# +# Generated makefile dependencies follow. +# +des.so des.po $(OUTPRE)des.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../../builtin/des/des_int.h \ + $(srcdir)/../../krb/aead.h $(srcdir)/../cksumtypes.h des.c \ + enc_provider.h +des3.so des3.po $(OUTPRE)des3.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../../builtin/des/des_int.h \ + $(srcdir)/../../krb/aead.h $(srcdir)/../cksumtypes.h des3.c +aes.so aes.po $(OUTPRE)aes.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../../builtin/aes/aes.h \ + $(srcdir)/../../builtin/aes/uitypes.h $(srcdir)/../../krb/aead.h \ + $(srcdir)/../cksumtypes.h aes.c enc_provider.h +rc4.so rc4.po $(OUTPRE)rc4.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h $(srcdir)/../../builtin/arcfour/arcfour-int.h \ + $(srcdir)/../../builtin/arcfour/arcfour.h $(srcdir)/../../krb/aead.h \ + $(srcdir)/../cksumtypes.h enc_provider.h rc4.c diff --git a/src/lib/crypto/openssl/enc_provider/des.c b/src/lib/crypto/openssl/enc_provider/des.c new file mode 100644 index 000000000..bc4313659 --- /dev/null +++ b/src/lib/crypto/openssl/enc_provider/des.c @@ -0,0 +1,271 @@ +/* + */ + +#include "k5-int.h" +#include "des_int.h" +#include "enc_provider.h" +#include +#include + +#define DES_BLOCK_SIZE 8 +#define DES_KEY_BYTES 7 +#define DES_KEY_LEN 8 + +static krb5_error_code +k5_des_encrypt(const krb5_keyblock *key, const krb5_data *ivec, + const krb5_data *input, krb5_data *output) +{ + int ret = 0, tmp_len = 0; + EVP_CIPHER_CTX ciph_ctx; + unsigned char *keybuf = NULL; + unsigned char *tmp_buf = NULL; + unsigned char iv[EVP_MAX_IV_LENGTH]; + + if (key->length != DES_KEY_LEN) + return(KRB5_BAD_KEYSIZE); + if ((input->length%8) != 0) + return(KRB5_BAD_MSIZE); + if (ivec && (ivec->length != 8)) + return(KRB5_BAD_MSIZE); + if (input->length != output->length) + return(KRB5_BAD_MSIZE); + + keybuf=key->contents; + keybuf[key->length] = '\0'; + + if ( ivec && ivec->data ) { + memset(iv,0,sizeof(iv)); + memcpy(iv,ivec->data,ivec->length); + } + + tmp_buf=OPENSSL_malloc(output->length); + if (!tmp_buf) + return ENOMEM; + memset(tmp_buf,0,output->length); + + EVP_CIPHER_CTX_init(&ciph_ctx); + + ret = EVP_EncryptInit_ex(&ciph_ctx, EVP_des_cbc(), NULL, keybuf, + (ivec && ivec->data) ? iv : NULL); + if (ret) { + EVP_CIPHER_CTX_set_padding(&ciph_ctx,0); + ret = EVP_EncryptUpdate(&ciph_ctx, tmp_buf, &tmp_len, + (unsigned char *)input->data, input->length); + if (ret) { + output->length = tmp_len; + ret = EVP_EncryptFinal_ex(&ciph_ctx, tmp_buf + tmp_len, &tmp_len); + } + } + + EVP_CIPHER_CTX_cleanup(&ciph_ctx); + + if (ret) + memcpy(output->data,tmp_buf, output->length); + + memset(tmp_buf,0,output->length); + OPENSSL_free(tmp_buf); + + if (!ret) + return KRB5_CRYPTO_INTERNAL; + return 0; +} + +static krb5_error_code +k5_des_decrypt(const krb5_keyblock *key, const krb5_data *ivec, + const krb5_data *input, krb5_data *output) +{ + /* key->enctype was checked by the caller */ + int ret = 0, tmp_len = 0; + EVP_CIPHER_CTX ciph_ctx; + unsigned char *keybuf = NULL; + unsigned char *tmp_buf; + unsigned char iv[EVP_MAX_IV_LENGTH]; + + if (key->length != DES_KEY_LEN) + return(KRB5_BAD_KEYSIZE); + if ((input->length%8) != 0) + return(KRB5_BAD_MSIZE); + if (ivec && (ivec->length != 8)) + return(KRB5_BAD_MSIZE); + if (input->length != output->length) + return(KRB5_BAD_MSIZE); + + keybuf=key->contents; + keybuf[key->length] = '\0'; + + if ( ivec != NULL && ivec->data ){ + memset(iv,0,sizeof(iv)); + memcpy(iv,ivec->data,ivec->length); + } + + tmp_buf=OPENSSL_malloc(output->length); + if (!tmp_buf) + return ENOMEM; + memset(tmp_buf,0,output->length); + + EVP_CIPHER_CTX_init(&ciph_ctx); + + ret = EVP_DecryptInit_ex(&ciph_ctx, EVP_des_cbc(), NULL, keybuf, + (ivec && ivec->data) ? iv : NULL); + if (ret) { + EVP_CIPHER_CTX_set_padding(&ciph_ctx,0); + ret = EVP_DecryptUpdate(&ciph_ctx, tmp_buf, &tmp_len, + (unsigned char *)input->data, input->length); + if (ret) { + output->length = tmp_len; + ret = EVP_DecryptFinal_ex(&ciph_ctx, tmp_buf+tmp_len, &tmp_len); + } + } + + EVP_CIPHER_CTX_cleanup(&ciph_ctx); + + if (ret) + memcpy(output->data,tmp_buf, output->length); + + memset(tmp_buf,0,output->length ); + OPENSSL_free(tmp_buf); + + if (!ret) + return KRB5_CRYPTO_INTERNAL; + return 0; +} + +static krb5_error_code +k5_des_make_key(const krb5_data *randombits, krb5_keyblock *key) +{ + if (key->length != DES_KEY_LEN) + return(KRB5_BAD_KEYSIZE); + if (randombits->length != 7) + return(KRB5_CRYPTO_INTERNAL); + + key->magic = KV5M_KEYBLOCK; + + /* take the seven bytes, move them around into the top 7 bits of the + 8 key bytes, then compute the parity bits */ + + memcpy(key->contents, randombits->data, randombits->length); + key->contents[7] = (((key->contents[0]&1)<<1) | ((key->contents[1]&1)<<2) | + ((key->contents[2]&1)<<3) | ((key->contents[3]&1)<<4) | + ((key->contents[4]&1)<<5) | ((key->contents[5]&1)<<6) | + ((key->contents[6]&1)<<7)); + + mit_des_fixup_key_parity(key->contents); + + return(0); +} + +static krb5_error_code +k5_des_encrypt_iov(const krb5_keyblock *key, + const krb5_data *ivec, + krb5_crypto_iov *data, + size_t num_data) +{ + int ret = 0, tmp_len = 0; + unsigned int i = 0; + EVP_CIPHER_CTX ciph_ctx; + unsigned char *keybuf = NULL ; + krb5_crypto_iov *iov = NULL; + unsigned char *tmp_buf = NULL; + unsigned char iv[EVP_MAX_IV_LENGTH]; + + if (ivec && ivec->data){ + memset(iv,0,sizeof(iv)); + memcpy(iv,ivec->data,ivec->length); + } + + EVP_CIPHER_CTX_init(&ciph_ctx); + + ret = EVP_EncryptInit_ex(&ciph_ctx, EVP_des_cbc(), NULL, + keybuf, (ivec && ivec->data) ? iv : NULL); + if (!ret) + return KRB5_CRYPTO_INTERNAL; + + for (i = 0; i < num_data; i++) { + iov = &data[i]; + if (iov->data.length <= 0) break; + tmp_len = iov->data.length; + + if (ENCRYPT_DATA_IOV(iov)) { + tmp_buf=(unsigned char *)iov->data.data; + ret = EVP_EncryptUpdate(&ciph_ctx, tmp_buf, &tmp_len, + (unsigned char *)iov->data.data, iov->data.length); + if (!ret) break; + iov->data.length = tmp_len; + } + } + if(ret) + ret = EVP_EncryptFinal_ex(&ciph_ctx, (unsigned char *)tmp_buf, &tmp_len); + + if (ret) + iov->data.length += tmp_len; + + EVP_CIPHER_CTX_cleanup(&ciph_ctx); + + if (!ret) + return KRB5_CRYPTO_INTERNAL; + return 0; + +} + +static krb5_error_code +k5_des_decrypt_iov(const krb5_keyblock *key, + const krb5_data *ivec, + krb5_crypto_iov *data, + size_t num_data) +{ + int ret = 0, tmp_len = 0; + unsigned int i = 0; + EVP_CIPHER_CTX ciph_ctx; + unsigned char *keybuf = NULL ; + krb5_crypto_iov *iov = NULL; + unsigned char *tmp_buf = NULL; + unsigned char iv[EVP_MAX_IV_LENGTH]; + + if (ivec && ivec->data){ + memset(iv,0,sizeof(iv)); + memcpy(iv,ivec->data,ivec->length); + } + + ret = EVP_DecryptInit_ex(&ciph_ctx, EVP_des_cbc(), NULL, + keybuf, (ivec && ivec->data) ? iv : NULL); + if (!ret) + return KRB5_CRYPTO_INTERNAL; + + for (i = 0; i < num_data; i++) { + iov = &data[i]; + if (iov->data.length <= 0) break; + tmp_len = iov->data.length; + + if (ENCRYPT_DATA_IOV(iov)) { + tmp_buf=(unsigned char *)iov->data.data; + ret = EVP_DecryptUpdate(&ciph_ctx, tmp_buf, &tmp_len, + (unsigned char *)iov->data.data, iov->data.length); + if (!ret) break; + iov->data.length = tmp_len; + } + } + if(ret) + ret = EVP_DecryptFinal_ex(&ciph_ctx, (unsigned char *)tmp_buf, &tmp_len); + + if (ret) + iov->data.length += tmp_len; + + EVP_CIPHER_CTX_cleanup(&ciph_ctx); + + if (!ret) + return KRB5_CRYPTO_INTERNAL; + return 0; +} + +const struct krb5_enc_provider krb5int_enc_des = { + DES_BLOCK_SIZE, + DES_KEY_BYTES, DES_KEY_LEN, + k5_des_encrypt, + k5_des_decrypt, + k5_des_make_key, + krb5int_des_init_state, + krb5int_default_free_state, + k5_des_encrypt_iov, + k5_des_decrypt_iov +}; + diff --git a/src/lib/crypto/openssl/enc_provider/des3.c b/src/lib/crypto/openssl/enc_provider/des3.c new file mode 100644 index 000000000..1cc67483d --- /dev/null +++ b/src/lib/crypto/openssl/enc_provider/des3.c @@ -0,0 +1,352 @@ +/* + */ + +#include "k5-int.h" +#include "des_int.h" +#include +#include + + +#define DES_BLOCK_SIZE 8 +#define DES3_KEY_BYTES 21 +#define DES3_KEY_LEN 24 + +static krb5_error_code +validate(const krb5_keyblock *key, const krb5_data *ivec, + const krb5_data *input, const krb5_data *output) +{ + mit_des3_key_schedule schedule; + + /* key->enctype was checked by the caller */ + + if (key->length != DES3_KEY_LEN) + return(KRB5_BAD_KEYSIZE); + if ((input->length%DES_BLOCK_SIZE) != 0) + return(KRB5_BAD_MSIZE); + if (ivec && (ivec->length != 8)) + return(KRB5_BAD_MSIZE); + if (input->length != output->length) + return(KRB5_BAD_MSIZE); + + switch (mit_des3_key_sched(*(mit_des3_cblock *)key->contents, + schedule)) { + case -1: + return(KRB5DES_BAD_KEYPAR); + case -2: + return(KRB5DES_WEAK_KEY); + } + return 0; +} + +static krb5_error_code +validate_iov(const krb5_keyblock *key, const krb5_data *ivec, + const krb5_crypto_iov *data, size_t num_data) +{ + size_t i, input_length; + mit_des3_key_schedule schedule; + + for (i = 0, input_length = 0; i < num_data; i++) { + const krb5_crypto_iov *iov = &data[i]; + + if (ENCRYPT_IOV(iov)) + input_length += iov->data.length; + } + + if (key->length != DES3_KEY_LEN) + return(KRB5_BAD_KEYSIZE); + if ((input_length%DES_BLOCK_SIZE) != 0) + return(KRB5_BAD_MSIZE); + if (ivec && (ivec->length != 8)) + return(KRB5_BAD_MSIZE); + + switch (mit_des3_key_sched(*(mit_des3_cblock *)key->contents, + schedule)) { + case -1: + return(KRB5DES_BAD_KEYPAR); + case -2: + return(KRB5DES_WEAK_KEY); + } + return 0; +} + +static krb5_error_code +k5_des3_encrypt(const krb5_keyblock *key, const krb5_data *ivec, + const krb5_data *input, krb5_data *output) +{ + + int ret = 0, tmp_len = 0; + EVP_CIPHER_CTX ciph_ctx; + unsigned char *keybuf = NULL; + unsigned char *tmp_buf = NULL; + unsigned char iv[EVP_MAX_IV_LENGTH]; + + ret = validate(key, ivec, input, output); + if (ret) + return ret; + + keybuf=key->contents; + keybuf[key->length] = '\0'; + + if (ivec && ivec->data) { + memset(iv,0,sizeof(iv)); + memcpy(iv,ivec->data,ivec->length); + } + + tmp_buf = OPENSSL_malloc(output->length); + if (!tmp_buf) + return ENOMEM; + + EVP_CIPHER_CTX_init(&ciph_ctx); + + ret = EVP_EncryptInit_ex(&ciph_ctx, EVP_des_ede3_cbc(), NULL, keybuf, + (ivec && ivec->data) ? iv : NULL); + if (ret) { + EVP_CIPHER_CTX_set_padding(&ciph_ctx,0); + ret = EVP_EncryptUpdate(&ciph_ctx, tmp_buf, &tmp_len, + (unsigned char *)input->data, input->length); + if (ret) { + output->length = tmp_len; + ret = EVP_EncryptFinal_ex(&ciph_ctx, tmp_buf+tmp_len, &tmp_len); + } + } + + EVP_CIPHER_CTX_cleanup(&ciph_ctx); + + if (ret) + memcpy(output->data,tmp_buf, output->length); + memset(tmp_buf,0,output->length); + OPENSSL_free(tmp_buf); + + if (!ret) + return KRB5_CRYPTO_INTERNAL; + return 0; + +} + +static krb5_error_code +k5_des3_decrypt(const krb5_keyblock *key, const krb5_data *ivec, + const krb5_data *input, krb5_data *output) +{ + int ret = 0, tmp_len = 0; + EVP_CIPHER_CTX ciph_ctx; + unsigned char *keybuf = NULL; + unsigned char *tmp_buf = NULL; + unsigned char iv[EVP_MAX_IV_LENGTH]; + + ret = validate(key, ivec, input, output); + if (ret) + return ret; + + keybuf=key->contents; + keybuf[key->length] = '\0'; + + if (ivec && ivec->data) { + memset(iv,0,sizeof(iv)); + memcpy(iv,ivec->data,ivec->length); + } + + tmp_buf=OPENSSL_malloc(output->length); + if (!tmp_buf) + return ENOMEM; + + EVP_CIPHER_CTX_init(&ciph_ctx); + + ret = EVP_DecryptInit_ex(&ciph_ctx, EVP_des_ede3_cbc(), NULL, keybuf, + (ivec && ivec->data) ? iv: NULL); + if (ret) { + EVP_CIPHER_CTX_set_padding(&ciph_ctx,0); + ret = EVP_DecryptUpdate(&ciph_ctx, tmp_buf, &tmp_len, + (unsigned char *)input->data, input->length); + if (ret) { + output->length = tmp_len; + ret = EVP_DecryptFinal_ex(&ciph_ctx, tmp_buf+tmp_len, &tmp_len); + } + } + + EVP_CIPHER_CTX_cleanup(&ciph_ctx); + + if (ret) + memcpy(output->data,tmp_buf, output->length); + + memset(tmp_buf,0,output->length); + OPENSSL_free(tmp_buf); + + if (!ret) + return KRB5_CRYPTO_INTERNAL; + return 0; + +} + +static krb5_error_code +k5_des3_make_key(const krb5_data *randombits, krb5_keyblock *key) +{ + int i; + + if (key->length != DES3_KEY_LEN) + return(KRB5_BAD_KEYSIZE); + if (randombits->length != DES3_KEY_BYTES) + return(KRB5_CRYPTO_INTERNAL); + + key->magic = KV5M_KEYBLOCK; + + /* take the seven bytes, move them around into the top 7 bits of the + 8 key bytes, then compute the parity bits. Do this three times. */ + + for (i=0; i<3; i++) { + memcpy(key->contents+i*8, randombits->data+i*7, 7); + key->contents[i*8+7] = (((key->contents[i*8]&1)<<1) | + ((key->contents[i*8+1]&1)<<2) | + ((key->contents[i*8+2]&1)<<3) | + ((key->contents[i*8+3]&1)<<4) | + ((key->contents[i*8+4]&1)<<5) | + ((key->contents[i*8+5]&1)<<6) | + ((key->contents[i*8+6]&1)<<7)); + + mit_des_fixup_key_parity(key->contents+i*8); + } + + return(0); +} + +static krb5_error_code +validate_and_schedule_iov(const krb5_keyblock *key, const krb5_data *ivec, + const krb5_crypto_iov *data, size_t num_data, + mit_des3_key_schedule *schedule) +{ + size_t i, input_length; + + for (i = 0, input_length = 0; i < num_data; i++) { + const krb5_crypto_iov *iov = &data[i]; + + if (ENCRYPT_IOV(iov)) + input_length += iov->data.length; + } + + if (key->length != 24) + return(KRB5_BAD_KEYSIZE); + if ((input_length%8) != 0) + return(KRB5_BAD_MSIZE); + if (ivec && (ivec->length != 8)) + return(KRB5_BAD_MSIZE); + + switch (mit_des3_key_sched(*(mit_des3_cblock *)key->contents, + *schedule)) { + case -1: + return(KRB5DES_BAD_KEYPAR); + case -2: + return(KRB5DES_WEAK_KEY); + } + return 0; +} + +static krb5_error_code +k5_des3_encrypt_iov(const krb5_keyblock *key, + const krb5_data *ivec, + krb5_crypto_iov *data, + size_t num_data) +{ +#if 0 + int ret = 0, tmp_len = 0; + unsigned int i = 0; + EVP_CIPHER_CTX ciph_ctx; + unsigned char *keybuf = NULL ; + krb5_crypto_iov *iov = NULL; + unsigned char *tmp_buf = NULL; + unsigned char iv[EVP_MAX_IV_LENGTH]; + + ret = validate_iov(key, ivec, data, num_data); + if (ret) + return ret; + + if (ivec && ivec->data){ + memset(iv,0,sizeof(iv)); + memcpy(iv,ivec->data,ivec->length); + } + + + EVP_CIPHER_CTX_init(&ciph_ctx); + + ret = EVP_EncryptInit_ex(&ciph_ctx, EVP_des_ede3_cbc(), NULL, + keybuf, (ivec && ivec->data) ? iv : NULL); + if (!ret) + return KRB5_CRYPTO_INTERNAL; + + for (i = 0; i < num_data; i++) { + iov = &data[i]; + if (iov->data.length <= 0) break; + tmp_len = iov->data.length; + + if (ENCRYPT_IOV(iov)) { + tmp_buf=(unsigned char *)iov->data.data; + ret = EVP_EncryptUpdate(&ciph_ctx, tmp_buf, &tmp_len, + (unsigned char *)iov->data.data, iov->data.length); + if (!ret) break; + iov->data.length = tmp_len; + } + } + if(ret) + ret = EVP_EncryptFinal_ex(&ciph_ctx, (unsigned char *)tmp_buf, &tmp_len); + + if (ret) + iov->data.length += tmp_len; + + EVP_CIPHER_CTX_cleanup(&ciph_ctx); + + if (!ret) + return KRB5_CRYPTO_INTERNAL; + return 0; +#endif + +//#if 0 + mit_des3_key_schedule schedule; + krb5_error_code err; + + err = validate_and_schedule_iov(key, ivec, data, num_data, &schedule); + if (err) + return err; + + /* this has a return value, but the code always returns zero */ + krb5int_des3_cbc_encrypt_iov(data, num_data, + schedule[0], schedule[1], schedule[2], + ivec != NULL ? (unsigned char *) ivec->data : NULL); + + zap(schedule, sizeof(schedule)); + return(0); +//#endif +} + +static krb5_error_code +k5_des3_decrypt_iov(const krb5_keyblock *key, + const krb5_data *ivec, + krb5_crypto_iov *data, + size_t num_data) +{ + mit_des3_key_schedule schedule; + krb5_error_code err; + + err = validate_and_schedule_iov(key, ivec, data, num_data, &schedule); + if (err) + return err; + + /* this has a return value, but the code always returns zero */ + krb5int_des3_cbc_decrypt_iov(data, num_data, + schedule[0], schedule[1], schedule[2], + ivec != NULL ? (unsigned char *) ivec->data : NULL); + + zap(schedule, sizeof(schedule)); + + return(0); +} + +const struct krb5_enc_provider krb5int_enc_des3 = { + DES_BLOCK_SIZE, + DES3_KEY_BYTES, DES3_KEY_LEN, + k5_des3_encrypt, + k5_des3_decrypt, + k5_des3_make_key, + krb5int_des_init_state, + krb5int_default_free_state, + k5_des3_encrypt_iov, + k5_des3_decrypt_iov +}; + diff --git a/src/lib/crypto/openssl/enc_provider/enc_provider.h b/src/lib/crypto/openssl/enc_provider/enc_provider.h new file mode 100644 index 000000000..d46e1b446 --- /dev/null +++ b/src/lib/crypto/openssl/enc_provider/enc_provider.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" + +extern const struct krb5_enc_provider krb5int_enc_des; +extern const struct krb5_enc_provider krb5int_enc_des3; +extern const struct krb5_enc_provider krb5int_enc_arcfour; +extern const struct krb5_enc_provider krb5int_enc_aes128; +extern const struct krb5_enc_provider krb5int_enc_aes256; +extern const struct krb5_enc_provider krb5int_enc_aes128_ctr; +extern const struct krb5_enc_provider krb5int_enc_aes256_ctr; + diff --git a/src/lib/crypto/openssl/enc_provider/rc4.c b/src/lib/crypto/openssl/enc_provider/rc4.c new file mode 100644 index 000000000..b82af5247 --- /dev/null +++ b/src/lib/crypto/openssl/enc_provider/rc4.c @@ -0,0 +1,167 @@ +/* arcfour.c + * + * #include STD_DISCLAIMER + */ + +#include "k5-int.h" +#include "arcfour-int.h" +#include "enc_provider.h" +#include +#include + +#define RC4_KEY_SIZE 16 +#define RC4_BLOCK_SIZE 1 + +/* Interface layer to kerb5 crypto layer */ +static krb5_error_code +k5_arcfour_docrypt(const krb5_keyblock *, const krb5_data *, + const krb5_data *, krb5_data *); + +/* from a random bitstrem, construct a key */ +static krb5_error_code +k5_arcfour_make_key(const krb5_data *, krb5_keyblock *); + +static krb5_error_code +k5_arcfour_free_state ( krb5_data *state); +static krb5_error_code +k5_arcfour_init_state (const krb5_keyblock *key, + krb5_keyusage keyusage, krb5_data *new_state); + +/* The workhorse of the arcfour system, this impliments the cipher */ +static krb5_error_code +k5_arcfour_docrypt(const krb5_keyblock *key, const krb5_data *state, + const krb5_data *input, krb5_data *output) +{ + int ret = 0, tmp_len = 0; + unsigned char *keybuf = NULL; + unsigned char *tmp_buf = NULL; + EVP_CIPHER_CTX ciph_ctx; + + if (key->length != RC4_KEY_SIZE) + return(KRB5_BAD_KEYSIZE); + + if (input->length != output->length) + return(KRB5_BAD_MSIZE); + + keybuf=key->contents; + keybuf[key->length] = '\0'; + + EVP_CIPHER_CTX_init(&ciph_ctx); + ret = EVP_EncryptInit_ex(&ciph_ctx, EVP_rc4(), NULL, keybuf, NULL); + if (ret) { + tmp_buf=(unsigned char *)output->data; + ret = EVP_EncryptUpdate(&ciph_ctx, tmp_buf, &tmp_len, (unsigned char *)input->data, input->length); + output->length = tmp_len; + } + if (ret) { + tmp_buf += tmp_len; + ret = EVP_EncryptFinal_ex(&ciph_ctx, tmp_buf, &tmp_len); + } + EVP_CIPHER_CTX_cleanup(&ciph_ctx); + output->length += tmp_len; + + if (!ret) + return KRB5_CRYPTO_INTERNAL; + return 0; +} + + +/* In-place decryption */ +static krb5_error_code +k5_arcfour_docrypt_iov(const krb5_keyblock *key, + const krb5_data *state, + krb5_crypto_iov *data, + size_t num_data) +{ + size_t i; + int ret = 0, tmp_len = 0; + EVP_CIPHER_CTX ciph_ctx; + unsigned char *keybuf = NULL ; + krb5_crypto_iov *iov = NULL; + unsigned char *tmp_buf = NULL; + + keybuf=key->contents; + keybuf[key->length] = '\0'; + + EVP_CIPHER_CTX_init(&ciph_ctx); + + ret = EVP_EncryptInit_ex(&ciph_ctx, EVP_rc4(), NULL, keybuf, NULL); + if (!ret) + return -1; + + for (i = 0; i < num_data; i++) { + iov = &data[i]; + if (iov->data.length <= 0) break; + tmp_len = iov->data.length; + + if (ENCRYPT_IOV(iov)) { + tmp_buf=(unsigned char *)iov->data.data; + ret = EVP_EncryptUpdate(&ciph_ctx, + tmp_buf, &tmp_len, + (unsigned char *)iov->data.data, iov->data.length); + if (!ret) break; + iov->data.length = tmp_len; + } + } + if(ret) + ret = EVP_EncryptFinal_ex(&ciph_ctx, (unsigned char *)tmp_buf, &tmp_len); + if (ret) + iov->data.length += tmp_len; + EVP_CIPHER_CTX_cleanup(&ciph_ctx); + + if (!ret) + return -1; + return 0; +} + + +static krb5_error_code +k5_arcfour_make_key(const krb5_data *randombits, krb5_keyblock *key) +{ + if (key->length != RC4_KEY_SIZE) + return(KRB5_BAD_KEYSIZE); + if (randombits->length != RC4_KEY_SIZE) + return(KRB5_CRYPTO_INTERNAL); + + key->magic = KV5M_KEYBLOCK; + + memcpy(key->contents, randombits->data, randombits->length); + + return(0); +} + +static krb5_error_code +k5_arcfour_free_state ( krb5_data *state) +{ + return 0; /* not implemented */ +} + +static krb5_error_code +k5_arcfour_init_state (const krb5_keyblock *key, + krb5_keyusage keyusage, krb5_data *new_state) +{ + return 0; /* not implemented */ + +} + +/* Since the arcfour cipher is identical going forwards and backwards, + we just call "docrypt" directly +*/ +const struct krb5_enc_provider krb5int_enc_arcfour = { + /* This seems to work... although I am not sure what the + implications are in other places in the kerberos library */ + RC4_BLOCK_SIZE, + /* Keysize is arbitrary in arcfour, but the constraints of the + system, and to attempt to work with the MSFT system forces us + to 16byte/128bit. Since there is no parity in the key, the + byte and length are the same. */ + RC4_KEY_SIZE, RC4_KEY_SIZE, + k5_arcfour_docrypt, + k5_arcfour_docrypt, + k5_arcfour_make_key, + k5_arcfour_init_state, /*xxx not implemented */ + k5_arcfour_free_state, /*xxx not implemented */ + k5_arcfour_docrypt_iov, + k5_arcfour_docrypt_iov +}; + diff --git a/src/lib/crypto/openssl/hmac.c b/src/lib/crypto/openssl/hmac.c new file mode 100644 index 000000000..a5543c977 --- /dev/null +++ b/src/lib/crypto/openssl/hmac.c @@ -0,0 +1,110 @@ +/* + */ + +#include "k5-int.h" +#include "aead.h" +#include +#include + +/* + * the HMAC transform looks like: + * + * H(K XOR opad, H(K XOR ipad, text)) + * + * where H is a cryptographic hash + * K is an n byte key + * ipad is the byte 0x36 repeated blocksize times + * opad is the byte 0x5c repeated blocksize times + * and text is the data being protected + */ + +static const EVP_MD * +map_digest(const struct krb5_hash_provider *hash) +{ + if (!strncmp(hash->hash_name, "SHA1",4)) + return EVP_sha1(); + else if (!strncmp(hash->hash_name, "MD5", 3)) + return EVP_md5(); + else if (!strncmp(hash->hash_name, "MD4", 3)) + return EVP_md4(); + else + return NULL; +} + +krb5_error_code +krb5_hmac(const struct krb5_hash_provider *hash, const krb5_keyblock *key, + unsigned int icount, const krb5_data *input, krb5_data *output) +{ + unsigned int i = 0, md_len = 0; + unsigned char md[EVP_MAX_MD_SIZE]; + HMAC_CTX c; + size_t hashsize, blocksize; + + hashsize = hash->hashsize; + blocksize = hash->blocksize; + + if (key->length > blocksize) + return(KRB5_CRYPTO_INTERNAL); + if (output->length < hashsize) + return(KRB5_BAD_MSIZE); + /* if this isn't > 0, then there won't be enough space in this + array to compute the outer hash */ + if (icount == 0) + return(KRB5_CRYPTO_INTERNAL); + + if (!map_digest(hash)) + return(KRB5_CRYPTO_INTERNAL); // unsupported alg + + HMAC_CTX_init(&c); + HMAC_Init(&c, key->contents, key->length, map_digest(hash)); + for ( i = 0; i < icount; i++ ) { + HMAC_Update(&c,(const unsigned char*)input[i].data, input[i].length); + } + HMAC_Final(&c,(unsigned char *)md, &md_len); + if ( md_len <= output->length) { + output->length = md_len; + memcpy(output->data, md, output->length); + } + HMAC_CTX_cleanup(&c); + return 0; + + +} + +krb5_error_code +krb5int_hmac_iov(const struct krb5_hash_provider *hash, const krb5_keyblock *key, + const krb5_crypto_iov *data, size_t num_data, krb5_data *output) +{ + krb5_data *sign_data; + size_t num_sign_data; + krb5_error_code ret; + size_t i, j; + + /* Create a checksum over all the data to be signed */ + for (i = 0, num_sign_data = 0; i < num_data; i++) { + const krb5_crypto_iov *iov = &data[i]; + + if (SIGN_IOV(iov)) + num_sign_data++; + } + + /* XXX cleanup to avoid alloc */ + sign_data = (krb5_data *)calloc(num_sign_data, sizeof(krb5_data)); + if (sign_data == NULL) + return ENOMEM; + + for (i = 0, j = 0; i < num_data; i++) { + const krb5_crypto_iov *iov = &data[i]; + + if (SIGN_IOV(iov)) + sign_data[j++] = iov->data; + } + + /* caller must store checksum in iov as it may be TYPE_TRAILER or TYPE_CHECKSUM */ + ret = krb5_hmac(hash, key, num_sign_data, sign_data, output); + + free(sign_data); + + return ret; +} + diff --git a/src/lib/crypto/openssl/md4/deps b/src/lib/crypto/openssl/md4/deps new file mode 100644 index 000000000..1decaf971 --- /dev/null +++ b/src/lib/crypto/openssl/md4/deps @@ -0,0 +1,13 @@ +# +# Generated makefile dependencies follow. +# +md4.so md4.po $(OUTPRE)md4.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h md4.c rsa-md4.h diff --git a/src/lib/crypto/openssl/md4/md4.c b/src/lib/crypto/openssl/md4/md4.c new file mode 100644 index 000000000..88d519188 --- /dev/null +++ b/src/lib/crypto/openssl/md4/md4.c @@ -0,0 +1,29 @@ +/* + * lib/crypto/openssl/md4/md4.c + */ + +#include "k5-int.h" +#include "rsa-md4.h" +#include +#include + +void +krb5_MD4Init (krb5_MD4_CTX *mdContext) +{ + EVP_MD_CTX_init(&mdContext->ossl_md4_ctx ); + EVP_DigestInit_ex(&mdContext->ossl_md4_ctx, EVP_md4(), NULL); + +} +void +krb5_MD4Update (krb5_MD4_CTX *mdContext, const unsigned char *inBuf, unsigned int inLen) +{ + EVP_DigestUpdate(&mdContext->ossl_md4_ctx, inBuf, inLen); +} + +void +krb5_MD4Final (krb5_MD4_CTX *mdContext) +{ + EVP_DigestFinal_ex(&mdContext->ossl_md4_ctx, mdContext->digest , NULL); + EVP_MD_CTX_cleanup(&mdContext->ossl_md4_ctx ); +} + diff --git a/src/lib/crypto/openssl/md4/rsa-md4.h b/src/lib/crypto/openssl/md4/rsa-md4.h new file mode 100644 index 000000000..4b0204727 --- /dev/null +++ b/src/lib/crypto/openssl/md4/rsa-md4.h @@ -0,0 +1,99 @@ +/* + * lib/crypto/md4/rsa-md4.h + * + * Copyright 1991 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * + * RSA MD4 header file, with Kerberos/STDC additions. + */ + +#ifndef __KRB5_RSA_MD4_H__ +#define __KRB5_RSA_MD4_H__ + +#ifdef unicos61 +#include +#endif /* unicos61 */ + +#include +#include + +/* 16 u_char's in the digest */ +#define RSA_MD4_CKSUM_LENGTH 16 +/* des blocksize is 8, so this works nicely... */ +#define OLD_RSA_MD4_DES_CKSUM_LENGTH 16 +#define NEW_RSA_MD4_DES_CKSUM_LENGTH 24 +#define RSA_MD4_DES_CONFOUND_LENGTH 8 + +/* + ********************************************************************** + ** md4.h -- Header file for implementation of MD4 ** + ** RSA Data Security, Inc. MD4 Message Digest Algorithm ** + ** Created: 2/17/90 RLR ** + ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version ** + ********************************************************************** + */ + +/* + ********************************************************************** + ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** + ** ** + ** License to copy and use this software is granted provided that ** + ** it is identified as the "RSA Data Security, Inc. MD4 Message ** + ** Digest Algorithm" in all material mentioning or referencing this ** + ** software or this function. ** + ** ** + ** License is also granted to make and use derivative works ** + ** provided that such works are identified as "derived from the RSA ** + ** Data Security, Inc. MD4 Message Digest Algorithm" in all ** + ** material mentioning or referencing the derived work. ** + ** ** + ** RSA Data Security, Inc. makes no representations concerning ** + ** either the merchantability of this software or the suitability ** + ** of this software for any particular purpose. It is provided "as ** + ** is" without express or implied warranty of any kind. ** + ** ** + ** These notices must be retained in any copies of any part of this ** + ** documentation and/or software. ** + ********************************************************************** + */ + +/* Data structure for MD4 (Message Digest) computation */ +typedef struct { + EVP_MD_CTX ossl_md4_ctx; + krb5_int32 * digest_len; + krb5_ui_4 i[2]; /* number of _bits_ handled mod 2^64 */ + krb5_ui_4 buf[4]; /* scratch buffer */ + unsigned char in[64]; /* input buffer */ + unsigned char digest[16]; /* actual digest after MD4Final call */ +} krb5_MD4_CTX; + +extern void krb5_MD4Init(krb5_MD4_CTX *); +extern void krb5_MD4Update(krb5_MD4_CTX *, const unsigned char *, unsigned int); +extern void krb5_MD4Final(krb5_MD4_CTX *); + +/* + ********************************************************************** + ** End of md4.h ** + ******************************* (cut) ******************************** + */ +#endif /* __KRB5_RSA_MD4_H__ */ diff --git a/src/lib/crypto/openssl/md5/deps b/src/lib/crypto/openssl/md5/deps new file mode 100644 index 000000000..fc3378d2e --- /dev/null +++ b/src/lib/crypto/openssl/md5/deps @@ -0,0 +1,13 @@ +# +# Generated makefile dependencies follow. +# +md5.so md5.po $(OUTPRE)md5.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h md5.c rsa-md5.h diff --git a/src/lib/crypto/openssl/md5/md5.c b/src/lib/crypto/openssl/md5/md5.c new file mode 100644 index 000000000..8519dd535 --- /dev/null +++ b/src/lib/crypto/openssl/md5/md5.c @@ -0,0 +1,36 @@ + +#include "k5-int.h" +#include "rsa-md5.h" +#include +#include + +/* The routine krb5_MD5Init initializes the message-digest context + mdContext. All fields are set to zero. + */ +void +krb5_MD5Init (krb5_MD5_CTX *mdContext) +{ + EVP_MD_CTX_init(&mdContext->ossl_md5_ctx); + EVP_DigestInit_ex(&mdContext->ossl_md5_ctx, EVP_md5(), NULL); +} + +/* The routine krb5_MD5Update updates the message-digest context to + account for the presence of each of the characters inBuf[0..inLen-1] + in the message whose digest is being computed. + */ +void +krb5_MD5Update (krb5_MD5_CTX *mdContext, const unsigned char *inBuf, unsigned int inLen) +{ + EVP_DigestUpdate(&mdContext->ossl_md5_ctx, inBuf, inLen); +} + +/* The routine krb5_MD5Final terminates the message-digest computation and + ends with the desired message digest in mdContext->digest[0...15]. + */ +void +krb5_MD5Final (krb5_MD5_CTX *mdContext) +{ + EVP_DigestFinal_ex(&mdContext->ossl_md5_ctx, mdContext->digest, NULL); + EVP_MD_CTX_cleanup(&mdContext->ossl_md5_ctx); +} + diff --git a/src/lib/crypto/openssl/md5/rsa-md5.h b/src/lib/crypto/openssl/md5/rsa-md5.h new file mode 100644 index 000000000..7240b20ca --- /dev/null +++ b/src/lib/crypto/openssl/md5/rsa-md5.h @@ -0,0 +1,27 @@ + +#ifndef KRB5_RSA_MD5__ +#define KRB5_RSA_MD5__ + +#include +#include + +/* Data structure for MD5 (Message-Digest) computation */ +typedef struct { + EVP_MD_CTX ossl_md5_ctx; + krb5_int32 * digest_len; + krb5_ui_4 i[2]; /* number of _bits_ handled mod 2^64 */ + krb5_ui_4 buf[4]; /* scratch buffer */ + unsigned char in[64]; /* input buffer */ + unsigned char digest[16]; /* actual digest after MD5Final call */ +} krb5_MD5_CTX; + +extern void krb5_MD5Init(krb5_MD5_CTX *); +extern void krb5_MD5Update(krb5_MD5_CTX *,const unsigned char *,unsigned int); +extern void krb5_MD5Final(krb5_MD5_CTX *); + +#define RSA_MD5_CKSUM_LENGTH 16 +#define OLD_RSA_MD5_DES_CKSUM_LENGTH 16 +#define NEW_RSA_MD5_DES_CKSUM_LENGTH 24 +#define RSA_MD5_DES_CONFOUND_LENGTH 8 + +#endif /* KRB5_RSA_MD5__ */ diff --git a/src/lib/crypto/openssl/pbkdf2.c b/src/lib/crypto/openssl/pbkdf2.c new file mode 100644 index 000000000..bef8be2e9 --- /dev/null +++ b/src/lib/crypto/openssl/pbkdf2.c @@ -0,0 +1,53 @@ +/* + * lib/crypto/openssl/pbkdf2.c + * + * Copyright 2002, 2008 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * + * Implementation of PBKDF2 from RFC 2898. + * Not currently used; likely to be used when we get around to AES support. + */ + +#include +#include "k5-int.h" +#include "hash_provider.h" + +#include +#include +#include + + +krb5_error_code +krb5int_pbkdf2_hmac_sha1 (const krb5_data *out, unsigned long count, + const krb5_data *pass, const krb5_data *salt) +{ +/* + * This is an implementation of PKCS#5 v2.0 + * Does not return an error + */ + PKCS5_PBKDF2_HMAC_SHA1(pass->data, pass->length, + (unsigned char *)salt->data, salt->length, count, + out->length, (unsigned char *)out->data); + return 0; +} + diff --git a/src/lib/crypto/openssl/sha1/deps b/src/lib/crypto/openssl/sha1/deps new file mode 100644 index 000000000..a8f51a8e6 --- /dev/null +++ b/src/lib/crypto/openssl/sha1/deps @@ -0,0 +1,13 @@ +# +# Generated makefile dependencies follow. +# +shs.so shs.po $(OUTPRE)shs.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/autoconf.h \ + $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \ + $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \ + $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \ + $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ + $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ + $(SRCTOP)/include/socket-utils.h shs.c shs.h diff --git a/src/lib/crypto/openssl/sha1/shs.c b/src/lib/crypto/openssl/sha1/shs.c new file mode 100644 index 000000000..9fb60f87c --- /dev/null +++ b/src/lib/crypto/openssl/sha1/shs.c @@ -0,0 +1,34 @@ +#include "shs.h" +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#include + +/* Initialize the SHS values */ +void shsInit(SHS_INFO *shsInfo) +{ + EVP_MD_CTX_init(&shsInfo->ossl_sha1_ctx ); + EVP_DigestInit_ex(&shsInfo->ossl_sha1_ctx , EVP_sha1(), NULL); +} + +/* Update SHS for a block of data */ + +void shsUpdate(SHS_INFO *shsInfo, const SHS_BYTE *buffer, unsigned int count) +{ + EVP_DigestUpdate(&shsInfo->ossl_sha1_ctx , buffer, count); +} +/* Final wrapup - pad to SHS_DATASIZE-byte boundary with the bit pattern + 1 0* (64-bit count of bits processed, MSB-first) */ + +void shsFinal(SHS_INFO *shsInfo) +{ + unsigned char *digest_buf = NULL; + + digest_buf = (unsigned char *)OPENSSL_malloc( sizeof(shsInfo->digest)); + + EVP_DigestFinal_ex(&shsInfo->ossl_sha1_ctx , digest_buf , &shsInfo->digest_len); + + memcpy(shsInfo->digest, digest_buf, shsInfo->digest_len); + OPENSSL_free(digest_buf); + EVP_MD_CTX_cleanup(&shsInfo->ossl_sha1_ctx ); +} diff --git a/src/lib/crypto/openssl/sha1/shs.h b/src/lib/crypto/openssl/sha1/shs.h new file mode 100644 index 000000000..66e91b69b --- /dev/null +++ b/src/lib/crypto/openssl/sha1/shs.h @@ -0,0 +1,49 @@ +#ifndef _SHS_DEFINED + +#include "k5-int.h" +#include +#include + +#define _SHS_DEFINED + +/* Some useful types */ + +typedef krb5_octet SHS_BYTE; +typedef krb5_ui_4 SHS_LONG; + +/* Define the following to use the updated SHS implementation */ +#define NEW_SHS /**/ + +/* The SHS block size and message digest sizes, in bytes */ + +#define SHS_DATASIZE 64 +#define SHS_DIGESTSIZE 20 + +/* The structure for storing SHS info */ + +typedef struct { + EVP_MD_CTX ossl_sha1_ctx; + unsigned int digest_len; + SHS_LONG digest[ 5 ]; /* Message digest */ + SHS_LONG countLo, countHi; /* 64-bit bit count */ + SHS_LONG data[ 16 ]; /* SHS data buffer */ +} SHS_INFO; + +/* Message digest functions (shs.c) */ +void shsInit(SHS_INFO *shsInfo); +void shsUpdate(SHS_INFO *shsInfo, const SHS_BYTE *buffer, unsigned int count); +void shsFinal(SHS_INFO *shsInfo); + + +/* Keyed Message digest functions (hmac_sha.c) */ +krb5_error_code hmac_sha(krb5_octet *text, + int text_len, + krb5_octet *key, + int key_len, + krb5_octet *digest); + + +#define NIST_SHA_CKSUM_LENGTH SHS_DIGESTSIZE +#define HMAC_SHA_CKSUM_LENGTH SHS_DIGESTSIZE + +#endif /* _SHS_DEFINED */ diff --git a/src/util/collected-client-lib/Makefile.in b/src/util/collected-client-lib/Makefile.in index bd8b5d3ab..68ede9849 100644 --- a/src/util/collected-client-lib/Makefile.in +++ b/src/util/collected-client-lib/Makefile.in @@ -43,7 +43,7 @@ STOBJLISTS= \ ../../lib/crypto/krb/crc32/OBJS.ST \ ../../lib/crypto/builtin/des/OBJS.ST \ ../../lib/crypto/krb/dk/OBJS.ST \ - ../../lib/crypto/krb/enc_provider/OBJS.ST \ + ../../lib/crypto/builtin/enc_provider/OBJS.ST \ ../../lib/crypto/krb/hash_provider/OBJS.ST \ ../../lib/crypto/krb/keyhash_provider/OBJS.ST \ ../../lib/crypto/builtin/md4/OBJS.ST \