diff options
| author | Cy Schubert <cy@FreeBSD.org> | 2017-07-07 17:03:42 +0000 |
|---|---|---|
| committer | Cy Schubert <cy@FreeBSD.org> | 2017-07-07 17:03:42 +0000 |
| commit | 33a9b234e7087f573ef08cd7318c6497ba08b439 (patch) | |
| tree | d0ea40ad3bf5463a3c55795977c71bcb7d781b4b /src/lib/crypto/openssl | |
Diffstat (limited to 'src/lib/crypto/openssl')
34 files changed, 2172 insertions, 0 deletions
diff --git a/src/lib/crypto/openssl/Makefile.in b/src/lib/crypto/openssl/Makefile.in new file mode 100644 index 000000000000..aa434b16859b --- /dev/null +++ b/src/lib/crypto/openssl/Makefile.in @@ -0,0 +1,49 @@ +mydir=lib$(S)crypto$(S)openssl +BUILDTOP=$(REL)..$(S)..$(S).. +SUBDIRS=camellia des aes md4 md5 sha1 sha2 enc_provider hash_provider +LOCALINCLUDES = -I$(srcdir)/../krb -I$(srcdir) + +STLIBOBJS=\ + hmac.o \ + init.o \ + pbkdf2.o \ + sha256.o \ + stubs.o + +OBJS=\ + $(OUTPRE)hmac.$(OBJEXT) \ + $(OUTPRE)init.$(OBJEXT) \ + $(OUTPRE)pbkdf2.$(OBJEXT) \ + $(OUTPRE)sha256.$(OBJEXT) \ + $(OUTPRE)stubs.$(OBJEXT) + +SRCS=\ + $(srcdir)/hmac.c \ + $(srcdir)/init.c \ + $(srcdir)/pbkdf2.c \ + $(srcdir)/sha256.c \ + $(srcdir)/stubs.c + +STOBJLISTS= des/OBJS.ST md4/OBJS.ST \ + md5/OBJS.ST sha1/OBJS.ST sha2/OBJS.ST \ + enc_provider/OBJS.ST \ + hash_provider/OBJS.ST \ + aes/OBJS.ST \ + OBJS.ST + +SUBDIROBJLISTS= des/OBJS.ST md4/OBJS.ST \ + md5/OBJS.ST sha1/OBJS.ST sha2/OBJS.ST \ + enc_provider/OBJS.ST \ + hash_provider/OBJS.ST \ + aes/OBJS.ST + +all-unix: all-libobjs +includes: depend + +depend: $(SRCS) + +clean-unix:: clean-libobjs + +@lib_frag@ +@libobj_frag@ + diff --git a/src/lib/crypto/openssl/aes/Makefile.in b/src/lib/crypto/openssl/aes/Makefile.in new file mode 100644 index 000000000000..feaaba959a7b --- /dev/null +++ b/src/lib/crypto/openssl/aes/Makefile.in @@ -0,0 +1,6 @@ +# Placeholder since all crypto modules must have the same structure. +mydir=lib$(S)crypto$(S)openssl$(S)aes +BUILDTOP=$(REL)..$(S)..$(S)..$(S).. +all-unix: all-libobjs +clean-unix:: clean-libobjs +@libobj_frag@ diff --git a/src/lib/crypto/openssl/aes/deps b/src/lib/crypto/openssl/aes/deps new file mode 100644 index 000000000000..2feac3c9d388 --- /dev/null +++ b/src/lib/crypto/openssl/aes/deps @@ -0,0 +1 @@ +# No dependencies here. diff --git a/src/lib/crypto/openssl/camellia/Makefile.in b/src/lib/crypto/openssl/camellia/Makefile.in new file mode 100644 index 000000000000..83930f6e363b --- /dev/null +++ b/src/lib/crypto/openssl/camellia/Makefile.in @@ -0,0 +1,6 @@ +# Placeholder since all crypto modules must have the same structure. +mydir=lib$(S)crypto$(S)openssl$(S)camellia +BUILDTOP=$(REL)..$(S)..$(S)..$(S).. +all-unix: all-libobjs +clean-unix:: clean-libobjs +@libobj_frag@ diff --git a/src/lib/crypto/openssl/camellia/deps b/src/lib/crypto/openssl/camellia/deps new file mode 100644 index 000000000000..2feac3c9d388 --- /dev/null +++ b/src/lib/crypto/openssl/camellia/deps @@ -0,0 +1 @@ +# No dependencies here. diff --git a/src/lib/crypto/openssl/crypto_mod.h b/src/lib/crypto/openssl/crypto_mod.h new file mode 100644 index 000000000000..6f6badbe5ae8 --- /dev/null +++ b/src/lib/crypto/openssl/crypto_mod.h @@ -0,0 +1,54 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* lib/crypto/openssl/crypto_mod.h - OpenSSL crypto module declarations */ +/* + * Copyright (C) 2011 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. + */ + +/* + * This header is included from lib/crypto/krb/crypto_int.h to provide + * module-specific declarations. It is not included directly from source + * files. + */ + +#ifndef CRYPTO_MOD_H +#define CRYPTO_MOD_H + +#include <openssl/crypto.h> +#include <openssl/aes.h> +#include <openssl/sha.h> + +/* 1.1 standardizes constructor and destructor names, renaming + * EVP_MD_CTX_create and EVP_MD_CTX_destroy. */ +#if OPENSSL_VERSION_NUMBER < 0x10100000L +#define EVP_MD_CTX_new EVP_MD_CTX_create +#define EVP_MD_CTX_free EVP_MD_CTX_destroy +#endif + +#define aes_ctx AES_KEY +#define krb5int_aes_enc_key(k, len, ctx) AES_set_encrypt_key(k, 8*(len), ctx) +#define krb5int_aes_enc_blk(in, out, ctx) AES_encrypt(in, out, ctx) +#define k5_sha256_init SHA256_Init +#define k5_sha256_update SHA256_Update +#define k5_sha256_final SHA256_Final + +#endif /* CRYPTO_MOD_H */ diff --git a/src/lib/crypto/openssl/deps b/src/lib/crypto/openssl/deps new file mode 100644 index 000000000000..e47ac2737dd7 --- /dev/null +++ b/src/lib/crypto/openssl/deps @@ -0,0 +1,46 @@ +# +# Generated makefile dependencies follow. +# +hmac.so hmac.po $(OUTPRE)hmac.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../krb/crypto_int.h \ + $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ + $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ + $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ + $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ + $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ + $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ + $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ + crypto_mod.h hmac.c +init.so init.po $(OUTPRE)init.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../krb/crypto_int.h \ + $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ + $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ + $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ + $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ + $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ + $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ + $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ + crypto_mod.h init.c +pbkdf2.so pbkdf2.po $(OUTPRE)pbkdf2.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../krb/crypto_int.h \ + $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ + $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ + $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ + $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ + $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ + $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ + $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ + crypto_mod.h pbkdf2.c +stubs.so stubs.po $(OUTPRE)stubs.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ + $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ + $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ + $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ + $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ + $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ + $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ + $(top_srcdir)/include/socket-utils.h stubs.c diff --git a/src/lib/crypto/openssl/des/Makefile.in b/src/lib/crypto/openssl/des/Makefile.in new file mode 100644 index 000000000000..4392fb8eaa52 --- /dev/null +++ b/src/lib/crypto/openssl/des/Makefile.in @@ -0,0 +1,20 @@ +mydir=lib$(S)crypto$(S)openssl$(S)des +BUILDTOP=$(REL)..$(S)..$(S)..$(S).. +LOCALINCLUDES = -I$(srcdir)/../../krb -I$(srcdir)/.. + +STLIBOBJS= des_keys.o + +OBJS= $(OUTPRE)des_keys.$(OBJEXT) + +SRCS= $(srcdir)/des_keys.c + +all-unix: all-libobjs + +includes: depend + +depend: $(SRCS) + +clean-unix:: clean-libobjs + +@libobj_frag@ + diff --git a/src/lib/crypto/openssl/des/deps b/src/lib/crypto/openssl/des/deps new file mode 100644 index 000000000000..21b904f8962b --- /dev/null +++ b/src/lib/crypto/openssl/des/deps @@ -0,0 +1,15 @@ +# +# Generated makefile dependencies follow. +# +des_keys.so des_keys.po $(OUTPRE)des_keys.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h $(srcdir)/../crypto_mod.h \ + $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ + $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ + $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ + $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ + $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ + $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ + $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ + des_keys.c diff --git a/src/lib/crypto/openssl/des/des_keys.c b/src/lib/crypto/openssl/des/des_keys.c new file mode 100644 index 000000000000..51d9db216c6b --- /dev/null +++ b/src/lib/crypto/openssl/des/des_keys.c @@ -0,0 +1,40 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* lib/crypto/openssl/des/des_keys.c - Key functions used by Kerberos code */ +/* + * Copyright (C) 2011 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. + */ + +#include "crypto_int.h" +#include <openssl/des.h> + +void +k5_des_fixup_key_parity(unsigned char *keybits) +{ + DES_set_odd_parity((DES_cblock *)keybits); +} + +krb5_boolean +k5_des_is_weak_key(unsigned char *keybits) +{ + return DES_is_weak_key((DES_cblock *)keybits); +} diff --git a/src/lib/crypto/openssl/enc_provider/Makefile.in b/src/lib/crypto/openssl/enc_provider/Makefile.in new file mode 100644 index 000000000000..b9e28c9cdc94 --- /dev/null +++ b/src/lib/crypto/openssl/enc_provider/Makefile.in @@ -0,0 +1,34 @@ +mydir=lib$(S)crypto$(S)openssl$(S)enc_provider +BUILDTOP=$(REL)..$(S)..$(S)..$(S).. +LOCALINCLUDES = -I$(srcdir)/../../krb -I$(srcdir)/.. + +STLIBOBJS= \ + des.o \ + des3.o \ + rc4.o \ + aes.o \ + camellia.o + +OBJS= \ + $(OUTPRE)des.$(OBJEXT) \ + $(OUTPRE)des3.$(OBJEXT) \ + $(OUTPRE)aes.$(OBJEXT) \ + $(OUTPRE)camellia.$(OBJEXT) \ + $(OUTPRE)rc4.$(OBJEXT) + +SRCS= \ + $(srcdir)/des.c \ + $(srcdir)/des3.c \ + $(srcdir)/aes.c \ + $(srcdir)/camellia.c \ + $(srcdir)/rc4.c + +all-unix: all-libobjs + +includes: depend + +depend: $(SRCS) + +clean-unix:: clean-libobjs + +@libobj_frag@ diff --git a/src/lib/crypto/openssl/enc_provider/aes.c b/src/lib/crypto/openssl/enc_provider/aes.c new file mode 100644 index 000000000000..6b4622fe93eb --- /dev/null +++ b/src/lib/crypto/openssl/enc_provider/aes.c @@ -0,0 +1,303 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* lib/crypto/openssl/enc_provider/aes.c */ +/* + * Copyright (C) 2003, 2007, 2008, 2009 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. + */ + +#include "crypto_int.h" +#include <openssl/evp.h> +#include <openssl/aes.h> +#include <openssl/modes.h> + +/* proto's */ +static krb5_error_code +cbc_enc(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, + size_t num_data); +static krb5_error_code +cbc_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, + size_t num_data); +static krb5_error_code +cts_encr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, + size_t num_data, size_t dlen); +static krb5_error_code +cts_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, + size_t num_data, size_t dlen); + +#define BLOCK_SIZE 16 +#define NUM_BITS 8 +#define IV_CTS_BUF_SIZE 16 /* 16 - hardcoded in CRYPTO_cts128_en/decrypt */ + +static const EVP_CIPHER * +map_mode(unsigned int len) +{ + if (len==16) + return EVP_aes_128_cbc(); + if (len==32) + return EVP_aes_256_cbc(); + else + return NULL; +} + +/* Encrypt one block using CBC. */ +static krb5_error_code +cbc_enc(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, + size_t num_data) +{ + int ret, olen = BLOCK_SIZE; + unsigned char iblock[BLOCK_SIZE], oblock[BLOCK_SIZE]; + EVP_CIPHER_CTX *ctx; + struct iov_cursor cursor; + + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) + return ENOMEM; + + ret = EVP_EncryptInit_ex(ctx, map_mode(key->keyblock.length), + NULL, key->keyblock.contents, (ivec) ? (unsigned char*)ivec->data : NULL); + if (ret == 0) { + EVP_CIPHER_CTX_free(ctx); + return KRB5_CRYPTO_INTERNAL; + } + + k5_iov_cursor_init(&cursor, data, num_data, BLOCK_SIZE, FALSE); + k5_iov_cursor_get(&cursor, iblock); + EVP_CIPHER_CTX_set_padding(ctx,0); + ret = EVP_EncryptUpdate(ctx, oblock, &olen, iblock, BLOCK_SIZE); + if (ret == 1) + k5_iov_cursor_put(&cursor, oblock); + EVP_CIPHER_CTX_free(ctx); + + zap(iblock, BLOCK_SIZE); + zap(oblock, BLOCK_SIZE); + return (ret == 1) ? 0 : KRB5_CRYPTO_INTERNAL; +} + +/* Decrypt one block using CBC. */ +static krb5_error_code +cbc_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, + size_t num_data) +{ + int ret = 0, olen = BLOCK_SIZE; + unsigned char iblock[BLOCK_SIZE], oblock[BLOCK_SIZE]; + EVP_CIPHER_CTX *ctx; + struct iov_cursor cursor; + + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) + return ENOMEM; + + ret = EVP_DecryptInit_ex(ctx, map_mode(key->keyblock.length), + NULL, key->keyblock.contents, (ivec) ? (unsigned char*)ivec->data : NULL); + if (ret == 0) { + EVP_CIPHER_CTX_free(ctx); + return KRB5_CRYPTO_INTERNAL; + } + + k5_iov_cursor_init(&cursor, data, num_data, BLOCK_SIZE, FALSE); + k5_iov_cursor_get(&cursor, iblock); + EVP_CIPHER_CTX_set_padding(ctx,0); + ret = EVP_DecryptUpdate(ctx, oblock, &olen, iblock, BLOCK_SIZE); + if (ret == 1) + k5_iov_cursor_put(&cursor, oblock); + EVP_CIPHER_CTX_free(ctx); + + zap(iblock, BLOCK_SIZE); + zap(oblock, BLOCK_SIZE); + return (ret == 1) ? 0 : KRB5_CRYPTO_INTERNAL; +} + +static krb5_error_code +cts_encr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, + size_t num_data, size_t dlen) +{ + int ret = 0; + size_t size = 0; + unsigned char *oblock = NULL, *dbuf = NULL; + unsigned char iv_cts[IV_CTS_BUF_SIZE]; + struct iov_cursor cursor; + AES_KEY enck; + + memset(iv_cts,0,sizeof(iv_cts)); + if (ivec && ivec->data){ + if (ivec->length != sizeof(iv_cts)) + return KRB5_CRYPTO_INTERNAL; + memcpy(iv_cts, ivec->data,ivec->length); + } + + oblock = OPENSSL_malloc(dlen); + if (!oblock){ + return ENOMEM; + } + dbuf = OPENSSL_malloc(dlen); + if (!dbuf){ + OPENSSL_free(oblock); + return ENOMEM; + } + + k5_iov_cursor_init(&cursor, data, num_data, dlen, FALSE); + k5_iov_cursor_get(&cursor, dbuf); + + AES_set_encrypt_key(key->keyblock.contents, + NUM_BITS * key->keyblock.length, &enck); + + size = CRYPTO_cts128_encrypt((unsigned char *)dbuf, oblock, dlen, &enck, + iv_cts, (cbc128_f)AES_cbc_encrypt); + if (size <= 0) + ret = KRB5_CRYPTO_INTERNAL; + else + k5_iov_cursor_put(&cursor, oblock); + + if (!ret && ivec && ivec->data) + memcpy(ivec->data, iv_cts, sizeof(iv_cts)); + + zap(oblock, dlen); + zap(dbuf, dlen); + OPENSSL_free(oblock); + OPENSSL_free(dbuf); + + return ret; +} + +static krb5_error_code +cts_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, + size_t num_data, size_t dlen) +{ + int ret = 0; + size_t size = 0; + unsigned char *oblock = NULL; + unsigned char *dbuf = NULL; + unsigned char iv_cts[IV_CTS_BUF_SIZE]; + struct iov_cursor cursor; + AES_KEY deck; + + memset(iv_cts,0,sizeof(iv_cts)); + if (ivec && ivec->data){ + if (ivec->length != sizeof(iv_cts)) + return KRB5_CRYPTO_INTERNAL; + memcpy(iv_cts, ivec->data,ivec->length); + } + + oblock = OPENSSL_malloc(dlen); + if (!oblock) + return ENOMEM; + dbuf = OPENSSL_malloc(dlen); + if (!dbuf){ + OPENSSL_free(oblock); + return ENOMEM; + } + + AES_set_decrypt_key(key->keyblock.contents, + NUM_BITS * key->keyblock.length, &deck); + + k5_iov_cursor_init(&cursor, data, num_data, dlen, FALSE); + k5_iov_cursor_get(&cursor, dbuf); + + size = CRYPTO_cts128_decrypt((unsigned char *)dbuf, oblock, + dlen, &deck, + iv_cts, (cbc128_f)AES_cbc_encrypt); + if (size <= 0) + ret = KRB5_CRYPTO_INTERNAL; + else + k5_iov_cursor_put(&cursor, oblock); + + if (!ret && ivec && ivec->data) + memcpy(ivec->data, iv_cts, sizeof(iv_cts)); + + zap(oblock, dlen); + zap(dbuf, dlen); + OPENSSL_free(oblock); + OPENSSL_free(dbuf); + + return ret; +} + +krb5_error_code +krb5int_aes_encrypt(krb5_key key, const krb5_data *ivec, + krb5_crypto_iov *data, size_t num_data) +{ + int ret = 0; + size_t input_length, nblocks; + + input_length = iov_total_length(data, num_data, FALSE); + nblocks = (input_length + BLOCK_SIZE - 1) / BLOCK_SIZE; + if (nblocks == 1) { + if (input_length != BLOCK_SIZE) + return KRB5_BAD_MSIZE; + ret = cbc_enc(key, ivec, data, num_data); + } else if (nblocks > 1) { + ret = cts_encr(key, ivec, data, num_data, input_length); + } + + return ret; +} + +krb5_error_code +krb5int_aes_decrypt(krb5_key key, const krb5_data *ivec, + krb5_crypto_iov *data, size_t num_data) +{ + int ret = 0; + size_t input_length, nblocks; + + input_length = iov_total_length(data, num_data, FALSE); + nblocks = (input_length + BLOCK_SIZE - 1) / BLOCK_SIZE; + if (nblocks == 1) { + if (input_length != BLOCK_SIZE) + return KRB5_BAD_MSIZE; + ret = cbc_decr(key, ivec, data, num_data); + } else if (nblocks > 1) { + ret = cts_decr(key, ivec, data, num_data, input_length); + } + + return ret; +} + +static krb5_error_code +krb5int_aes_init_state (const krb5_keyblock *key, krb5_keyusage usage, + krb5_data *state) +{ + state->length = 16; + state->data = (void *) malloc(16); + if (state->data == NULL) + return ENOMEM; + memset(state->data, 0, state->length); + return 0; +} +const struct krb5_enc_provider krb5int_enc_aes128 = { + 16, + 16, 16, + krb5int_aes_encrypt, + krb5int_aes_decrypt, + NULL, + krb5int_aes_init_state, + krb5int_default_free_state +}; + +const struct krb5_enc_provider krb5int_enc_aes256 = { + 16, + 32, 32, + krb5int_aes_encrypt, + krb5int_aes_decrypt, + NULL, + krb5int_aes_init_state, + krb5int_default_free_state +}; diff --git a/src/lib/crypto/openssl/enc_provider/camellia.c b/src/lib/crypto/openssl/enc_provider/camellia.c new file mode 100644 index 000000000000..2da691329277 --- /dev/null +++ b/src/lib/crypto/openssl/enc_provider/camellia.c @@ -0,0 +1,359 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* lib/crypto/openssl/enc_provider/camellia.c */ +/* + * Copyright (C) 2003, 2007, 2008, 2009, 2010 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. + */ + +#include "crypto_int.h" +#include <openssl/evp.h> +#include <openssl/camellia.h> +#include <openssl/modes.h> + +static krb5_error_code +cbc_enc(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, + size_t num_data); +static krb5_error_code +cbc_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, + size_t num_data); +static krb5_error_code +cts_encr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, + size_t num_data, size_t dlen); +static krb5_error_code +cts_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, + size_t num_data, size_t dlen); + +#define BLOCK_SIZE 16 +#define NUM_BITS 8 +#define IV_CTS_BUF_SIZE 16 /* 16 - hardcoded in CRYPTO_cts128_en/decrypt */ + +static void +xorblock(unsigned char *out, const unsigned char *in) +{ + int z; + for (z = 0; z < CAMELLIA_BLOCK_SIZE / 4; z++) { + unsigned char *outptr = &out[z * 4]; + unsigned char *inptr = (unsigned char *)&in[z * 4]; + /* + * Use unaligned accesses. On x86, this will probably still be faster + * than multiple byte accesses for unaligned data, and for aligned data + * should be far better. (One test indicated about 2.4% faster + * encryption for 1024-byte messages.) + * + * If some other CPU has really slow unaligned-word or byte accesses, + * perhaps this function (or the load/store helpers?) should test for + * alignment first. + * + * If byte accesses are faster than unaligned words, we may need to + * conditionalize on CPU type, as that may be hard to determine + * automatically. + */ + store_32_n(load_32_n(outptr) ^ load_32_n(inptr), outptr); + } +} + +static const EVP_CIPHER * +map_mode(unsigned int len) +{ + if (len==16) + return EVP_camellia_128_cbc(); + if (len==32) + return EVP_camellia_256_cbc(); + else + return NULL; +} + +/* Encrypt one block using CBC. */ +static krb5_error_code +cbc_enc(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, + size_t num_data) +{ + int ret, olen = BLOCK_SIZE; + unsigned char iblock[BLOCK_SIZE], oblock[BLOCK_SIZE]; + EVP_CIPHER_CTX *ctx; + struct iov_cursor cursor; + + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) + return ENOMEM; + + ret = EVP_EncryptInit_ex(ctx, map_mode(key->keyblock.length), + NULL, key->keyblock.contents, (ivec) ? (unsigned char*)ivec->data : NULL); + if (ret == 0) { + EVP_CIPHER_CTX_free(ctx); + return KRB5_CRYPTO_INTERNAL; + } + + k5_iov_cursor_init(&cursor, data, num_data, BLOCK_SIZE, FALSE); + k5_iov_cursor_get(&cursor, iblock); + EVP_CIPHER_CTX_set_padding(ctx,0); + ret = EVP_EncryptUpdate(ctx, oblock, &olen, iblock, BLOCK_SIZE); + if (ret == 1) + k5_iov_cursor_put(&cursor, oblock); + EVP_CIPHER_CTX_free(ctx); + + zap(iblock, BLOCK_SIZE); + zap(oblock, BLOCK_SIZE); + return (ret == 1) ? 0 : KRB5_CRYPTO_INTERNAL; +} + +/* Decrypt one block using CBC. */ +static krb5_error_code +cbc_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, + size_t num_data) +{ + int ret = 0, olen = BLOCK_SIZE; + unsigned char iblock[BLOCK_SIZE], oblock[BLOCK_SIZE]; + EVP_CIPHER_CTX *ctx; + struct iov_cursor cursor; + + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) + return ENOMEM; + + ret = EVP_DecryptInit_ex(ctx, map_mode(key->keyblock.length), + NULL, key->keyblock.contents, (ivec) ? (unsigned char*)ivec->data : NULL); + if (ret == 0) { + EVP_CIPHER_CTX_free(ctx); + return KRB5_CRYPTO_INTERNAL; + } + + k5_iov_cursor_init(&cursor, data, num_data, BLOCK_SIZE, FALSE); + k5_iov_cursor_get(&cursor, iblock); + EVP_CIPHER_CTX_set_padding(ctx,0); + ret = EVP_DecryptUpdate(ctx, oblock, &olen, iblock, BLOCK_SIZE); + if (ret == 1) + k5_iov_cursor_put(&cursor, oblock); + EVP_CIPHER_CTX_free(ctx); + + zap(iblock, BLOCK_SIZE); + zap(oblock, BLOCK_SIZE); + return (ret == 1) ? 0 : KRB5_CRYPTO_INTERNAL; +} + +static krb5_error_code +cts_encr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, + size_t num_data, size_t dlen) +{ + int ret = 0; + size_t size = 0; + unsigned char *oblock = NULL, *dbuf = NULL; + unsigned char iv_cts[IV_CTS_BUF_SIZE]; + struct iov_cursor cursor; + CAMELLIA_KEY enck; + + memset(iv_cts,0,sizeof(iv_cts)); + if (ivec && ivec->data){ + if (ivec->length != sizeof(iv_cts)) + return KRB5_CRYPTO_INTERNAL; + memcpy(iv_cts, ivec->data,ivec->length); + } + + oblock = OPENSSL_malloc(dlen); + if (!oblock){ + return ENOMEM; + } + dbuf = OPENSSL_malloc(dlen); + if (!dbuf){ + OPENSSL_free(oblock); + return ENOMEM; + } + + k5_iov_cursor_init(&cursor, data, num_data, dlen, FALSE); + k5_iov_cursor_get(&cursor, dbuf); + + Camellia_set_key(key->keyblock.contents, NUM_BITS * key->keyblock.length, + &enck); + + size = CRYPTO_cts128_encrypt((unsigned char *)dbuf, oblock, dlen, &enck, + iv_cts, (cbc128_f)Camellia_cbc_encrypt); + if (size <= 0) + ret = KRB5_CRYPTO_INTERNAL; + else + k5_iov_cursor_put(&cursor, oblock); + + if (!ret && ivec && ivec->data) + memcpy(ivec->data, iv_cts, sizeof(iv_cts)); + + zap(oblock, dlen); + zap(dbuf, dlen); + OPENSSL_free(oblock); + OPENSSL_free(dbuf); + + return ret; +} + +static krb5_error_code +cts_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, + size_t num_data, size_t dlen) +{ + int ret = 0; + size_t size = 0; + unsigned char *oblock = NULL; + unsigned char *dbuf = NULL; + unsigned char iv_cts[IV_CTS_BUF_SIZE]; + struct iov_cursor cursor; + CAMELLIA_KEY deck; + + memset(iv_cts,0,sizeof(iv_cts)); + if (ivec && ivec->data){ + if (ivec->length != sizeof(iv_cts)) + return KRB5_CRYPTO_INTERNAL; + memcpy(iv_cts, ivec->data,ivec->length); + } + + oblock = OPENSSL_malloc(dlen); + if (!oblock) + return ENOMEM; + dbuf = OPENSSL_malloc(dlen); + if (!dbuf){ + OPENSSL_free(oblock); + return ENOMEM; + } + + Camellia_set_key(key->keyblock.contents, NUM_BITS * key->keyblock.length, + &deck); + + k5_iov_cursor_init(&cursor, data, num_data, dlen, FALSE); + k5_iov_cursor_get(&cursor, dbuf); + + size = CRYPTO_cts128_decrypt((unsigned char *)dbuf, oblock, + dlen, &deck, + iv_cts, (cbc128_f)Camellia_cbc_encrypt); + if (size <= 0) + ret = KRB5_CRYPTO_INTERNAL; + else + k5_iov_cursor_put(&cursor, oblock); + + if (!ret && ivec && ivec->data) + memcpy(ivec->data, iv_cts, sizeof(iv_cts)); + + zap(oblock, dlen); + zap(dbuf, dlen); + OPENSSL_free(oblock); + OPENSSL_free(dbuf); + + return ret; +} + +static krb5_error_code +krb5int_camellia_encrypt(krb5_key key, const krb5_data *ivec, + krb5_crypto_iov *data, size_t num_data) +{ + int ret = 0; + size_t input_length, nblocks; + + input_length = iov_total_length(data, num_data, FALSE); + nblocks = (input_length + BLOCK_SIZE - 1) / BLOCK_SIZE; + if (nblocks == 1) { + if (input_length != BLOCK_SIZE) + return KRB5_BAD_MSIZE; + ret = cbc_enc(key, ivec, data, num_data); + } else if (nblocks > 1) { + ret = cts_encr(key, ivec, data, num_data, input_length); + } + + return ret; +} + +static krb5_error_code +krb5int_camellia_decrypt(krb5_key key, const krb5_data *ivec, + krb5_crypto_iov *data, size_t num_data) +{ + int ret = 0; + size_t input_length, nblocks; + + input_length = iov_total_length(data, num_data, FALSE); + nblocks = (input_length + BLOCK_SIZE - 1) / BLOCK_SIZE; + if (nblocks == 1) { + if (input_length != BLOCK_SIZE) + return KRB5_BAD_MSIZE; + ret = cbc_decr(key, ivec, data, num_data); + } else if (nblocks > 1) { + ret = cts_decr(key, ivec, data, num_data, input_length); + } + + return ret; +} + +krb5_error_code +krb5int_camellia_cbc_mac(krb5_key key, const krb5_crypto_iov *data, + size_t num_data, const krb5_data *iv, + krb5_data *output) +{ + CAMELLIA_KEY enck; + unsigned char blockY[CAMELLIA_BLOCK_SIZE], blockB[CAMELLIA_BLOCK_SIZE]; + struct iov_cursor cursor; + + if (output->length < CAMELLIA_BLOCK_SIZE) + return KRB5_BAD_MSIZE; + + Camellia_set_key(key->keyblock.contents, + NUM_BITS * key->keyblock.length, &enck); + + if (iv != NULL) + memcpy(blockY, iv->data, CAMELLIA_BLOCK_SIZE); + else + memset(blockY, 0, CAMELLIA_BLOCK_SIZE); + + k5_iov_cursor_init(&cursor, data, num_data, CAMELLIA_BLOCK_SIZE, FALSE); + while (k5_iov_cursor_get(&cursor, blockB)) { + xorblock(blockB, blockY); + Camellia_ecb_encrypt(blockB, blockY, &enck, 1); + } + + output->length = CAMELLIA_BLOCK_SIZE; + memcpy(output->data, blockY, CAMELLIA_BLOCK_SIZE); + + return 0; +} + +static krb5_error_code +krb5int_camellia_init_state (const krb5_keyblock *key, krb5_keyusage usage, + krb5_data *state) +{ + state->length = 16; + state->data = (void *) malloc(16); + if (state->data == NULL) + return ENOMEM; + memset(state->data, 0, state->length); + return 0; +} +const struct krb5_enc_provider krb5int_enc_camellia128 = { + 16, + 16, 16, + krb5int_camellia_encrypt, + krb5int_camellia_decrypt, + krb5int_camellia_cbc_mac, + krb5int_camellia_init_state, + krb5int_default_free_state +}; + +const struct krb5_enc_provider krb5int_enc_camellia256 = { + 16, + 32, 32, + krb5int_camellia_encrypt, + krb5int_camellia_decrypt, + krb5int_camellia_cbc_mac, + krb5int_camellia_init_state, + krb5int_default_free_state +}; diff --git a/src/lib/crypto/openssl/enc_provider/deps b/src/lib/crypto/openssl/enc_provider/deps new file mode 100644 index 000000000000..428fcf6f5f15 --- /dev/null +++ b/src/lib/crypto/openssl/enc_provider/deps @@ -0,0 +1,59 @@ +# +# 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) $(srcdir)/../../krb/crypto_int.h \ + $(srcdir)/../crypto_mod.h $(top_srcdir)/include/k5-buf.h \ + $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ + $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ + $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ + $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ + $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ + $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ + $(top_srcdir)/include/socket-utils.h des.c +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) $(srcdir)/../../krb/crypto_int.h \ + $(srcdir)/../crypto_mod.h $(top_srcdir)/include/k5-buf.h \ + $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ + $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ + $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ + $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ + $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ + $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ + $(top_srcdir)/include/socket-utils.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) $(srcdir)/../../krb/crypto_int.h \ + $(srcdir)/../crypto_mod.h $(top_srcdir)/include/k5-buf.h \ + $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ + $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ + $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ + $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ + $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ + $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ + $(top_srcdir)/include/socket-utils.h aes.c +camellia.so camellia.po $(OUTPRE)camellia.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h $(srcdir)/../crypto_mod.h \ + $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ + $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ + $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ + $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ + $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ + $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ + $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ + camellia.c +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) $(srcdir)/../../krb/crypto_int.h \ + $(srcdir)/../crypto_mod.h $(top_srcdir)/include/k5-buf.h \ + $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ + $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ + $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ + $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ + $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ + $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ + $(top_srcdir)/include/socket-utils.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 000000000000..a662db512512 --- /dev/null +++ b/src/lib/crypto/openssl/enc_provider/des.c @@ -0,0 +1,218 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* lib/crypto/openssl/enc_provider/des.c */ +/* + * Copyright (C) 2009 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. + */ + +/* + * 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 "crypto_int.h" +#include <openssl/evp.h> +#include <openssl/des.h> + +#define DES_BLOCK_SIZE 8 +#define DES_KEY_SIZE 8 +#define DES_KEY_BYTES 7 + +static krb5_error_code +validate(krb5_key key, const krb5_data *ivec, const krb5_crypto_iov *data, + size_t num_data, krb5_boolean *empty) +{ + size_t input_length = iov_total_length(data, num_data, FALSE); + + if (key->keyblock.length != DES_KEY_SIZE) + return(KRB5_BAD_KEYSIZE); + if ((input_length%DES_BLOCK_SIZE) != 0) + return(KRB5_BAD_MSIZE); + if (ivec && (ivec->length != 8)) + return(KRB5_BAD_MSIZE); + + *empty = (input_length == 0); + return 0; +} + +static krb5_error_code +k5_des_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, + size_t num_data) +{ + int ret, olen = DES_BLOCK_SIZE; + unsigned char iblock[DES_BLOCK_SIZE], oblock[DES_BLOCK_SIZE]; + struct iov_cursor cursor; + EVP_CIPHER_CTX *ctx; + krb5_boolean empty; + + ret = validate(key, ivec, data, num_data, &empty); + if (ret != 0 || empty) + return ret; + + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) + return ENOMEM; + + ret = EVP_EncryptInit_ex(ctx, EVP_des_cbc(), NULL, + key->keyblock.contents, (ivec && ivec->data) ? (unsigned char*)ivec->data : NULL); + if (!ret) { + EVP_CIPHER_CTX_free(ctx); + return KRB5_CRYPTO_INTERNAL; + } + + EVP_CIPHER_CTX_set_padding(ctx, 0); + + k5_iov_cursor_init(&cursor, data, num_data, DES_BLOCK_SIZE, FALSE); + while (k5_iov_cursor_get(&cursor, iblock)) { + ret = EVP_EncryptUpdate(ctx, oblock, &olen, iblock, DES_BLOCK_SIZE); + if (!ret) + break; + k5_iov_cursor_put(&cursor, oblock); + } + + if (ivec != NULL) + memcpy(ivec->data, oblock, DES_BLOCK_SIZE); + + EVP_CIPHER_CTX_free(ctx); + + zap(iblock, sizeof(iblock)); + zap(oblock, sizeof(oblock)); + + if (ret != 1) + return KRB5_CRYPTO_INTERNAL; + return 0; +} + +static krb5_error_code +k5_des_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, + size_t num_data) +{ + int ret, olen = DES_BLOCK_SIZE; + unsigned char iblock[DES_BLOCK_SIZE], oblock[DES_BLOCK_SIZE]; + struct iov_cursor cursor; + EVP_CIPHER_CTX *ctx; + krb5_boolean empty; + + ret = validate(key, ivec, data, num_data, &empty); + if (ret != 0 || empty) + return ret; + + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) + return ENOMEM; + + ret = EVP_DecryptInit_ex(ctx, EVP_des_cbc(), NULL, + key->keyblock.contents, + (ivec) ? (unsigned char*)ivec->data : NULL); + if (!ret) { + EVP_CIPHER_CTX_free(ctx); + return KRB5_CRYPTO_INTERNAL; + } + + EVP_CIPHER_CTX_set_padding(ctx,0); + + k5_iov_cursor_init(&cursor, data, num_data, DES_BLOCK_SIZE, FALSE); + while (k5_iov_cursor_get(&cursor, iblock)) { + ret = EVP_DecryptUpdate(ctx, oblock, &olen, iblock, DES_BLOCK_SIZE); + if (!ret) + break; + k5_iov_cursor_put(&cursor, oblock); + } + + if (ivec != NULL) + memcpy(ivec->data, iblock, DES_BLOCK_SIZE); + + EVP_CIPHER_CTX_free(ctx); + + zap(iblock, sizeof(iblock)); + zap(oblock, sizeof(oblock)); + + if (ret != 1) + return KRB5_CRYPTO_INTERNAL; + return 0; +} + +static krb5_error_code +k5_des_cbc_mac(krb5_key key, const krb5_crypto_iov *data, size_t num_data, + const krb5_data *ivec, krb5_data *output) +{ + int ret; + struct iov_cursor cursor; + DES_cblock blockY, blockB; + DES_key_schedule sched; + krb5_boolean empty; + + ret = validate(key, ivec, data, num_data, &empty); + if (ret != 0) + return ret; + + if (output->length != DES_BLOCK_SIZE) + return KRB5_BAD_MSIZE; + + if (DES_set_key((DES_cblock *)key->keyblock.contents, &sched) != 0) + return KRB5_CRYPTO_INTERNAL; + + if (ivec != NULL) + memcpy(blockY, ivec->data, DES_BLOCK_SIZE); + else + memset(blockY, 0, DES_BLOCK_SIZE); + + k5_iov_cursor_init(&cursor, data, num_data, DES_BLOCK_SIZE, FALSE); + while (k5_iov_cursor_get(&cursor, blockB)) { + store_64_n(load_64_n(blockB) ^ load_64_n(blockY), blockB); + DES_ecb_encrypt(&blockB, &blockY, &sched, 1); + } + + memcpy(output->data, blockY, DES_BLOCK_SIZE); + return 0; +} + +const struct krb5_enc_provider krb5int_enc_des = { + DES_BLOCK_SIZE, + DES_KEY_BYTES, DES_KEY_SIZE, + k5_des_encrypt, + k5_des_decrypt, + k5_des_cbc_mac, + krb5int_des_init_state, + krb5int_default_free_state +}; 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 000000000000..1c439c2cd23a --- /dev/null +++ b/src/lib/crypto/openssl/enc_provider/des3.c @@ -0,0 +1,184 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* lib/crypto/openssl/enc_provider/des3.c */ +/* + * Copyright (C) 2009 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. + */ +/* + * 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 "crypto_int.h" +#include <openssl/evp.h> + + +#define DES3_BLOCK_SIZE 8 +#define DES3_KEY_SIZE 24 +#define DES3_KEY_BYTES 21 + +static krb5_error_code +validate(krb5_key key, const krb5_data *ivec, const krb5_crypto_iov *data, + size_t num_data, krb5_boolean *empty) +{ + size_t input_length = iov_total_length(data, num_data, FALSE); + + if (key->keyblock.length != DES3_KEY_SIZE) + return(KRB5_BAD_KEYSIZE); + if ((input_length%DES3_BLOCK_SIZE) != 0) + return(KRB5_BAD_MSIZE); + if (ivec && (ivec->length != 8)) + return(KRB5_BAD_MSIZE); + + *empty = (input_length == 0); + return 0; +} + +static krb5_error_code +k5_des3_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, + size_t num_data) +{ + int ret, olen = DES3_BLOCK_SIZE; + unsigned char iblock[DES3_BLOCK_SIZE], oblock[DES3_BLOCK_SIZE]; + struct iov_cursor cursor; + EVP_CIPHER_CTX *ctx; + krb5_boolean empty; + + ret = validate(key, ivec, data, num_data, &empty); + if (ret != 0 || empty) + return ret; + + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) + return ENOMEM; + + ret = EVP_EncryptInit_ex(ctx, EVP_des_ede3_cbc(), NULL, + key->keyblock.contents, + (ivec) ? (unsigned char*)ivec->data : NULL); + if (!ret) { + EVP_CIPHER_CTX_free(ctx); + return KRB5_CRYPTO_INTERNAL; + } + + EVP_CIPHER_CTX_set_padding(ctx,0); + + k5_iov_cursor_init(&cursor, data, num_data, DES3_BLOCK_SIZE, FALSE); + while (k5_iov_cursor_get(&cursor, iblock)) { + ret = EVP_EncryptUpdate(ctx, oblock, &olen, iblock, DES3_BLOCK_SIZE); + if (!ret) + break; + k5_iov_cursor_put(&cursor, oblock); + } + + if (ivec != NULL) + memcpy(ivec->data, oblock, DES3_BLOCK_SIZE); + + EVP_CIPHER_CTX_free(ctx); + + zap(iblock, sizeof(iblock)); + zap(oblock, sizeof(oblock)); + + if (ret != 1) + return KRB5_CRYPTO_INTERNAL; + return 0; +} + +static krb5_error_code +k5_des3_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, + size_t num_data) +{ + int ret, olen = DES3_BLOCK_SIZE; + unsigned char iblock[DES3_BLOCK_SIZE], oblock[DES3_BLOCK_SIZE]; + struct iov_cursor cursor; + EVP_CIPHER_CTX *ctx; + krb5_boolean empty; + + ret = validate(key, ivec, data, num_data, &empty); + if (ret != 0 || empty) + return ret; + + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) + return ENOMEM; + + ret = EVP_DecryptInit_ex(ctx, EVP_des_ede3_cbc(), NULL, + key->keyblock.contents, + (ivec) ? (unsigned char*)ivec->data : NULL); + if (!ret) { + EVP_CIPHER_CTX_free(ctx); + return KRB5_CRYPTO_INTERNAL; + } + + EVP_CIPHER_CTX_set_padding(ctx,0); + + k5_iov_cursor_init(&cursor, data, num_data, DES3_BLOCK_SIZE, FALSE); + while (k5_iov_cursor_get(&cursor, iblock)) { + ret = EVP_DecryptUpdate(ctx, oblock, &olen, + (unsigned char *)iblock, DES3_BLOCK_SIZE); + if (!ret) + break; + k5_iov_cursor_put(&cursor, oblock); + } + + if (ivec != NULL) + memcpy(ivec->data, iblock, DES3_BLOCK_SIZE); + + EVP_CIPHER_CTX_free(ctx); + + zap(iblock, sizeof(iblock)); + zap(oblock, sizeof(oblock)); + + if (ret != 1) + return KRB5_CRYPTO_INTERNAL; + return 0; +} + +const struct krb5_enc_provider krb5int_enc_des3 = { + DES3_BLOCK_SIZE, + DES3_KEY_BYTES, DES3_KEY_SIZE, + k5_des3_encrypt, + k5_des3_decrypt, + NULL, + krb5int_des_init_state, + krb5int_default_free_state +}; 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 000000000000..7f3c086ed75d --- /dev/null +++ b/src/lib/crypto/openssl/enc_provider/rc4.c @@ -0,0 +1,156 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* lib/crypto/openssl/enc_provider/rc4.c */ +/* + * Copyright (C) 2009 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. + */ + +/* + * Copyright (c) 2000 by Computer Science Laboratory, + * Rensselaer Polytechnic Institute + * + * #include STD_DISCLAIMER + */ + + +#include "crypto_int.h" +#include <openssl/evp.h> + +/* + * The loopback field is a pointer to the structure. If the application copies + * the state (not a valid operation, but one which happens to works with some + * other enc providers), we can detect it via the loopback field and return a + * sane error code. + */ +struct arcfour_state { + struct arcfour_state *loopback; + EVP_CIPHER_CTX *ctx; +}; + +#define RC4_KEY_SIZE 16 +#define RC4_BLOCK_SIZE 1 + +/* Interface layer to krb5 crypto layer */ + +/* The workhorse of the arcfour system, + * this impliments the cipher + */ + +/* In-place IOV crypto */ +static krb5_error_code +k5_arcfour_docrypt(krb5_key key,const krb5_data *state, krb5_crypto_iov *data, + size_t num_data) +{ + size_t i; + int ret = 1, tmp_len = 0; + krb5_crypto_iov *iov = NULL; + EVP_CIPHER_CTX *ctx = NULL; + struct arcfour_state *arcstate; + + arcstate = (state != NULL) ? (struct arcfour_state *) state->data : NULL; + if (arcstate != NULL) { + ctx = arcstate->ctx; + if (arcstate->loopback != arcstate) + return KRB5_CRYPTO_INTERNAL; + } + + if (ctx == NULL) { + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) + return ENOMEM; + + ret = EVP_EncryptInit_ex(ctx, EVP_rc4(), NULL, key->keyblock.contents, + NULL); + if (!ret) { + EVP_CIPHER_CTX_free(ctx); + return KRB5_CRYPTO_INTERNAL; + } + + if (arcstate != NULL) + arcstate->ctx = ctx; + } + + for (i = 0; i < num_data; i++) { + iov = &data[i]; + if (ENCRYPT_IOV(iov)) { + ret = EVP_EncryptUpdate(ctx, + (unsigned char *) iov->data.data, &tmp_len, + (unsigned char *) iov->data.data, + iov->data.length); + if (!ret) + break; + } + } + + if (arcstate == NULL) + EVP_CIPHER_CTX_free(ctx); + + if (!ret) + return KRB5_CRYPTO_INTERNAL; + + return 0; +} + +static void +k5_arcfour_free_state(krb5_data *state) +{ + struct arcfour_state *arcstate = (struct arcfour_state *) state->data; + + EVP_CIPHER_CTX_free(arcstate->ctx); + free(arcstate); +} + +static krb5_error_code +k5_arcfour_init_state(const krb5_keyblock *key, + krb5_keyusage keyusage, krb5_data *new_state) +{ + struct arcfour_state *arcstate; + + /* Create a state structure with an uninitialized context. */ + arcstate = calloc(1, sizeof(*arcstate)); + if (arcstate == NULL) + return ENOMEM; + arcstate->loopback = arcstate; + arcstate->ctx = NULL; + new_state->data = (char *) arcstate; + new_state->length = sizeof(*arcstate); + return 0; +} + +/* 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, + NULL, + k5_arcfour_init_state, + k5_arcfour_free_state +}; diff --git a/src/lib/crypto/openssl/hash_provider/Makefile.in b/src/lib/crypto/openssl/hash_provider/Makefile.in new file mode 100644 index 000000000000..7762e20a5543 --- /dev/null +++ b/src/lib/crypto/openssl/hash_provider/Makefile.in @@ -0,0 +1,24 @@ +mydir=lib$(S)crypto$(S)openssl$(S)hash_provider +BUILDTOP=$(REL)..$(S)..$(S)..$(S).. +LOCALINCLUDES = -I$(srcdir)/../../krb -I$(srcdir)/.. + +STLIBOBJS= \ + hash_crc32.o \ + hash_evp.o + +OBJS= $(OUTPRE)hash_crc32.$(OBJEXT) \ + $(OUTPRE)hash_evp.$(OBJEXT) + +SRCS= $(srcdir)/hash_crc32.c \ + $(srcdir)/hash_evp.c + +all-unix: all-libobjs + +includes: depend + +depend: $(SRCS) + +clean-unix:: clean-libobjs + +@libobj_frag@ + diff --git a/src/lib/crypto/openssl/hash_provider/deps b/src/lib/crypto/openssl/hash_provider/deps new file mode 100644 index 000000000000..87dd0201295a --- /dev/null +++ b/src/lib/crypto/openssl/hash_provider/deps @@ -0,0 +1,27 @@ +# +# Generated makefile dependencies follow. +# +hash_crc32.so hash_crc32.po $(OUTPRE)hash_crc32.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h $(srcdir)/../crypto_mod.h \ + $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ + $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ + $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ + $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ + $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ + $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ + $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ + hash_crc32.c +hash_evp.so hash_evp.po $(OUTPRE)hash_evp.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h $(srcdir)/../crypto_mod.h \ + $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ + $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ + $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ + $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ + $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ + $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ + $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ + hash_evp.c diff --git a/src/lib/crypto/openssl/hash_provider/hash_crc32.c b/src/lib/crypto/openssl/hash_provider/hash_crc32.c new file mode 100644 index 000000000000..4013843edfd7 --- /dev/null +++ b/src/lib/crypto/openssl/hash_provider/hash_crc32.c @@ -0,0 +1,56 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* + * 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 "crypto_int.h" + +static krb5_error_code +k5_crc32_hash(const krb5_crypto_iov *data, size_t num_data, krb5_data *output) +{ + unsigned long c; + unsigned int i; + + if (output->length != CRC32_CKSUM_LENGTH) + return(KRB5_CRYPTO_INTERNAL); + + c = 0; + for (i = 0; i < num_data; i++) { + const krb5_crypto_iov *iov = &data[i]; + + if (SIGN_IOV(iov)) + mit_crc32(iov->data.data, iov->data.length, &c); + } + + store_32_le(c, output->data); + return(0); +} + +const struct krb5_hash_provider krb5int_hash_crc32 = { + "CRC32", + CRC32_CKSUM_LENGTH, + 1, + k5_crc32_hash +}; diff --git a/src/lib/crypto/openssl/hash_provider/hash_evp.c b/src/lib/crypto/openssl/hash_provider/hash_evp.c new file mode 100644 index 000000000000..957ed8d9caaf --- /dev/null +++ b/src/lib/crypto/openssl/hash_provider/hash_evp.c @@ -0,0 +1,112 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* lib/crypto/openssl/hash_provider/hash_evp.c - OpenSSL hash providers */ +/* + * Copyright (C) 2015 by the Massachusetts Institute of Technology. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS 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 + * COPYRIGHT HOLDER OR 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 "crypto_int.h" +#include <openssl/evp.h> + +static krb5_error_code +hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data, + krb5_data *output) +{ + EVP_MD_CTX *ctx; + const krb5_data *d; + size_t i; + int ok; + + if (output->length != (unsigned int)EVP_MD_size(type)) + return KRB5_CRYPTO_INTERNAL; + + ctx = EVP_MD_CTX_new(); + if (ctx == NULL) + return ENOMEM; + + ok = EVP_DigestInit_ex(ctx, type, NULL); + for (i = 0; i < num_data; i++) { + if (!SIGN_IOV(&data[i])) + continue; + d = &data[i].data; + ok = ok && EVP_DigestUpdate(ctx, d->data, d->length); + } + ok = ok && EVP_DigestFinal_ex(ctx, (uint8_t *)output->data, NULL); + EVP_MD_CTX_free(ctx); + return ok ? 0 : ENOMEM; +} + +static krb5_error_code +hash_md4(const krb5_crypto_iov *data, size_t num_data, krb5_data *output) +{ + return hash_evp(EVP_md4(), data, num_data, output); +} + +static krb5_error_code +hash_md5(const krb5_crypto_iov *data, size_t num_data, krb5_data *output) +{ + return hash_evp(EVP_md5(), data, num_data, output); +} + +static krb5_error_code +hash_sha1(const krb5_crypto_iov *data, size_t num_data, krb5_data *output) +{ + return hash_evp(EVP_sha1(), data, num_data, output); +} + +static krb5_error_code +hash_sha256(const krb5_crypto_iov *data, size_t num_data, krb5_data *output) +{ + return hash_evp(EVP_sha256(), data, num_data, output); +} + +static krb5_error_code +hash_sha384(const krb5_crypto_iov *data, size_t num_data, krb5_data *output) +{ + return hash_evp(EVP_sha384(), data, num_data, output); +} + +const struct krb5_hash_provider krb5int_hash_md4 = { + "MD4", 16, 64, hash_md4 +}; + +const struct krb5_hash_provider krb5int_hash_md5 = { + "MD5", 16, 64, hash_md5 +}; + +const struct krb5_hash_provider krb5int_hash_sha1 = { + "SHA1", 20, 64, hash_sha1 +}; + +const struct krb5_hash_provider krb5int_hash_sha256 = { + "SHA-256", 32, 64, hash_sha256 +}; + +const struct krb5_hash_provider krb5int_hash_sha384 = { + "SHA-384", 48, 128, hash_sha384 +}; diff --git a/src/lib/crypto/openssl/hmac.c b/src/lib/crypto/openssl/hmac.c new file mode 100644 index 000000000000..b2db6ec02ac0 --- /dev/null +++ b/src/lib/crypto/openssl/hmac.c @@ -0,0 +1,164 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* lib/crypto/openssl/hmac.c */ +/* + * Copyright (C) 2009 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. + */ + +/* + * 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 "crypto_int.h" +#include <openssl/hmac.h> +#include <openssl/evp.h> + +#if OPENSSL_VERSION_NUMBER < 0x10100000L + +/* OpenSSL 1.1 makes HMAC_CTX opaque, while 1.0 does not have pointer + * constructors or destructors. */ + +#define HMAC_CTX_new compat_hmac_ctx_new +static HMAC_CTX * +compat_hmac_ctx_new() +{ + HMAC_CTX *ctx; + + ctx = calloc(1, sizeof(*ctx)); + if (ctx != NULL) + HMAC_CTX_init(ctx); + return ctx; +} + +#define HMAC_CTX_free compat_hmac_ctx_free +static void +compat_hmac_ctx_free(HMAC_CTX *ctx) +{ + HMAC_CTX_cleanup(ctx); + free(ctx); +} + +#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ + +/* + * 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, "SHA-256",7)) + return EVP_sha256(); + else if (!strncmp(hash->hash_name, "SHA-384",7)) + return EVP_sha384(); + 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 +krb5int_hmac_keyblock(const struct krb5_hash_provider *hash, + const krb5_keyblock *keyblock, + const krb5_crypto_iov *data, size_t num_data, + krb5_data *output) +{ + unsigned int i = 0, md_len = 0; + unsigned char md[EVP_MAX_MD_SIZE]; + HMAC_CTX *ctx; + size_t hashsize, blocksize; + + hashsize = hash->hashsize; + blocksize = hash->blocksize; + + if (keyblock->length > blocksize) + return(KRB5_CRYPTO_INTERNAL); + if (output->length < hashsize) + return(KRB5_BAD_MSIZE); + + if (!map_digest(hash)) + return(KRB5_CRYPTO_INTERNAL); // unsupported alg + + ctx = HMAC_CTX_new(); + if (ctx == NULL) + return ENOMEM; + + HMAC_Init(ctx, keyblock->contents, keyblock->length, map_digest(hash)); + for (i = 0; i < num_data; i++) { + const krb5_crypto_iov *iov = &data[i]; + + if (SIGN_IOV(iov)) + HMAC_Update(ctx, (uint8_t *)iov->data.data, iov->data.length); + } + HMAC_Final(ctx, md, &md_len); + if ( md_len <= output->length) { + output->length = md_len; + memcpy(output->data, md, output->length); + } + HMAC_CTX_free(ctx); + return 0; + + +} + +krb5_error_code +krb5int_hmac(const struct krb5_hash_provider *hash, krb5_key key, + const krb5_crypto_iov *data, size_t num_data, + krb5_data *output) +{ + return krb5int_hmac_keyblock(hash, &key->keyblock, data, num_data, output); +} diff --git a/src/lib/crypto/openssl/init.c b/src/lib/crypto/openssl/init.c new file mode 100644 index 000000000000..1139bce533cb --- /dev/null +++ b/src/lib/crypto/openssl/init.c @@ -0,0 +1,38 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* lib/crypto/openssl/init.c - Module init and cleanup functions */ +/* + * Copyright (C) 2010 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. + */ + +#include "crypto_int.h" + +int +krb5int_crypto_impl_init(void) +{ + return 0; +} + +void +krb5int_crypto_impl_cleanup(void) +{ +} diff --git a/src/lib/crypto/openssl/md4/Makefile.in b/src/lib/crypto/openssl/md4/Makefile.in new file mode 100644 index 000000000000..c6c6ea0bf631 --- /dev/null +++ b/src/lib/crypto/openssl/md4/Makefile.in @@ -0,0 +1,6 @@ +# Placeholder since all crypto modules must have the same structure. +mydir=lib$(S)crypto$(S)openssl$(S)md4 +BUILDTOP=$(REL)..$(S)..$(S)..$(S).. +all-unix: all-libobjs +clean-unix:: clean-libobjs +@libobj_frag@ diff --git a/src/lib/crypto/openssl/md4/deps b/src/lib/crypto/openssl/md4/deps new file mode 100644 index 000000000000..2feac3c9d388 --- /dev/null +++ b/src/lib/crypto/openssl/md4/deps @@ -0,0 +1 @@ +# No dependencies here. diff --git a/src/lib/crypto/openssl/md5/Makefile.in b/src/lib/crypto/openssl/md5/Makefile.in new file mode 100644 index 000000000000..38a289c74915 --- /dev/null +++ b/src/lib/crypto/openssl/md5/Makefile.in @@ -0,0 +1,6 @@ +# Placeholder since all crypto modules must have the same structure. +mydir=lib$(S)crypto$(S)openssl$(S)md5 +BUILDTOP=$(REL)..$(S)..$(S)..$(S).. +all-unix: all-libobjs +clean-unix:: clean-libobjs +@libobj_frag@ diff --git a/src/lib/crypto/openssl/md5/deps b/src/lib/crypto/openssl/md5/deps new file mode 100644 index 000000000000..2feac3c9d388 --- /dev/null +++ b/src/lib/crypto/openssl/md5/deps @@ -0,0 +1 @@ +# No dependencies here. diff --git a/src/lib/crypto/openssl/pbkdf2.c b/src/lib/crypto/openssl/pbkdf2.c new file mode 100644 index 000000000000..00c2116fc136 --- /dev/null +++ b/src/lib/crypto/openssl/pbkdf2.c @@ -0,0 +1,53 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* lib/crypto/openssl/pbkdf2.c */ +/* + * Copyright 2002, 2008, 2009 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. + */ + +#include "crypto_int.h" +#include <openssl/x509.h> +#include <openssl/evp.h> +#include <openssl/hmac.h> + +krb5_error_code +krb5int_pbkdf2_hmac(const struct krb5_hash_provider *hash, + const krb5_data *out, unsigned long count, + const krb5_data *pass, const krb5_data *salt) +{ + const EVP_MD *md = NULL; + + /* Get the message digest handle corresponding to the hash. */ + if (hash == &krb5int_hash_sha1) + md = EVP_sha1(); + else if (hash == &krb5int_hash_sha256) + md = EVP_sha256(); + else if (hash == &krb5int_hash_sha384) + md = EVP_sha384(); + if (md == NULL) + return KRB5_CRYPTO_INTERNAL; + + PKCS5_PBKDF2_HMAC(pass->data, pass->length, (unsigned char *)salt->data, + salt->length, count, md, out->length, + (unsigned char *)out->data); + return 0; +} diff --git a/src/lib/crypto/openssl/sha1/Makefile.in b/src/lib/crypto/openssl/sha1/Makefile.in new file mode 100644 index 000000000000..49142e87da00 --- /dev/null +++ b/src/lib/crypto/openssl/sha1/Makefile.in @@ -0,0 +1,6 @@ +# Placeholder since all crypto modules must have the same structure. +mydir=lib$(S)crypto$(S)openssl$(S)sha1 +BUILDTOP=$(REL)..$(S)..$(S)..$(S).. +all-unix: all-libobjs +clean-unix:: clean-libobjs +@libobj_frag@ diff --git a/src/lib/crypto/openssl/sha1/deps b/src/lib/crypto/openssl/sha1/deps new file mode 100644 index 000000000000..2feac3c9d388 --- /dev/null +++ b/src/lib/crypto/openssl/sha1/deps @@ -0,0 +1 @@ +# No dependencies here. diff --git a/src/lib/crypto/openssl/sha2/Makefile.in b/src/lib/crypto/openssl/sha2/Makefile.in new file mode 100644 index 000000000000..feaaba959a7b --- /dev/null +++ b/src/lib/crypto/openssl/sha2/Makefile.in @@ -0,0 +1,6 @@ +# Placeholder since all crypto modules must have the same structure. +mydir=lib$(S)crypto$(S)openssl$(S)aes +BUILDTOP=$(REL)..$(S)..$(S)..$(S).. +all-unix: all-libobjs +clean-unix:: clean-libobjs +@libobj_frag@ diff --git a/src/lib/crypto/openssl/sha2/deps b/src/lib/crypto/openssl/sha2/deps new file mode 100644 index 000000000000..2feac3c9d388 --- /dev/null +++ b/src/lib/crypto/openssl/sha2/deps @@ -0,0 +1 @@ +# No dependencies here. diff --git a/src/lib/crypto/openssl/sha256.c b/src/lib/crypto/openssl/sha256.c new file mode 100644 index 000000000000..fa095d47200d --- /dev/null +++ b/src/lib/crypto/openssl/sha256.c @@ -0,0 +1,50 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* lib/crypto/openssl/sha256.c - k5_sha256() implementation */ +/* + * Copyright (C) 2016 by the Massachusetts Institute of Technology. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS 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 + * COPYRIGHT HOLDER OR 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 "crypto_int.h" +#include <openssl/evp.h> + +krb5_error_code +k5_sha256(const krb5_data *in, uint8_t out[K5_SHA256_HASHLEN]) +{ + EVP_MD_CTX *ctx; + int ok; + + ctx = EVP_MD_CTX_new(); + if (ctx == NULL) + return ENOMEM; + ok = EVP_DigestInit_ex(ctx, EVP_sha256(), NULL); + ok = ok && EVP_DigestUpdate(ctx, in->data, in->length); + ok = ok && EVP_DigestFinal_ex(ctx, out, NULL); + EVP_MD_CTX_free(ctx); + return ok ? 0 : ENOMEM; +} diff --git a/src/lib/crypto/openssl/stubs.c b/src/lib/crypto/openssl/stubs.c new file mode 100644 index 000000000000..1ee4d7b35f68 --- /dev/null +++ b/src/lib/crypto/openssl/stubs.c @@ -0,0 +1,69 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* lib/crypto/openssl/stubs.c - OpenSSL stub functions */ +/* + * Copyright (C) 2011 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. + */ + +/* + * This file defines symbols which must be exported by libk5crypto because they + * are in the export list (for the sake of test programs), but which are not + * used when OpenSSL is the back end. + */ + +#include "k5-int.h" + +/* + * These functions are used by the Fortuna PRNG and test program. They are + * defined to OpenSSL equivalents when the OpenSSL back end headers are + * used. + */ +void krb5int_aes_enc_blk(void); +void krb5int_aes_enc_key(void); +void k5_sha256_final(void); +void k5_sha256_init(void); +void k5_sha256_update(void); + +void krb5int_aes_enc_blk(void) +{ + abort(); +} + +void krb5int_aes_enc_key(void) +{ + abort(); +} + +void k5_sha256_final(void) +{ + abort(); +} + +void k5_sha256_init(void) +{ + abort(); +} + +void k5_sha256_update(void) +{ + abort(); +} |
