From cd964fce751ca752af4158842063a9579a2d4331 Mon Sep 17 00:00:00 2001 From: Matt Barden Date: Mon, 4 Sep 2017 07:25:59 -0500 Subject: [PATCH] 5869 Need AES CMAC support in KCF+PKCS11 Portions contributed by: Jason King Reviewed by: Robert Mustacchi Reviewed by: Dan McDonald Approved by: Gordon Ross --- usr/src/common/crypto/aes/aes_impl.h | 3 +- usr/src/common/crypto/aes/aes_modes.c | 2 +- usr/src/common/crypto/modes/cbc.c | 190 +++++- usr/src/common/crypto/modes/ctr.c | 24 +- usr/src/common/crypto/modes/modes.c | 218 +++++- usr/src/common/crypto/modes/modes.h | 15 + .../lib/pkcs11/libsoftcrypto/common/mapfile-vers | 4 + usr/src/lib/pkcs11/pkcs11_kernel/Makefile.com | 3 +- .../pkcs11/pkcs11_softtoken/common/softAESCrypt.c | 252 ++++++- .../lib/pkcs11/pkcs11_softtoken/common/softCrypt.h | 24 +- .../pkcs11_softtoken/common/softEncryptUtil.c | 90 ++- .../pkcs11/pkcs11_softtoken/common/softSignUtil.c | 67 +- .../pkcs11/pkcs11_softtoken/common/softSlotToken.c | 6 + .../pkcs11_softtoken/common/softVerifyUtil.c | 67 +- usr/src/pkg/manifests/system-test-cryptotest.mf | 52 ++ usr/src/test/Makefile | 2 +- usr/src/test/{ => crypto-tests}/Makefile | 7 +- usr/src/test/{ => crypto-tests/cmd}/Makefile | 7 +- usr/src/test/{ => crypto-tests/cmd/kcf}/Makefile | 25 +- .../{Makefile => crypto-tests/cmd/kcf/cleanup.ksh} | 11 +- .../{Makefile => crypto-tests/cmd/kcf/setup.ksh} | 11 +- .../test/{ => crypto-tests/cmd/scripts}/Makefile | 25 +- .../test/crypto-tests/cmd/scripts/cryptotest.ksh | 49 ++ usr/src/test/{ => crypto-tests/doc}/Makefile | 23 +- usr/src/test/crypto-tests/doc/README | 60 ++ usr/src/test/{ => crypto-tests/runfiles}/Makefile | 27 +- .../runfiles/default.run} | 19 +- usr/src/test/{ => crypto-tests/tests}/Makefile | 9 +- .../test/{ => crypto-tests/tests/common}/Makefile | 20 +- .../test/crypto-tests/tests/common/cryptotest.h | 102 +++ .../crypto-tests/tests/common/cryptotest_kcf.c | 378 +++++++++++ .../crypto-tests/tests/common/cryptotest_pkcs.c | 401 +++++++++++ usr/src/test/crypto-tests/tests/common/testfuncs.c | 268 ++++++++ .../test/{ => crypto-tests/tests/modes}/Makefile | 6 +- .../{ => crypto-tests/tests/modes/aes}/Makefile | 6 +- .../crypto-tests/tests/modes/aes/Makefile.subdirs | 82 +++ .../tests/modes/aes/cbc}/Makefile | 9 +- .../crypto-tests/tests/modes/aes/cbc/aes_cbc.c | 69 ++ .../crypto-tests/tests/modes/aes/cbc/aes_cbc.h | 173 +++++ .../tests/modes/aes/ccm}/Makefile | 9 +- .../crypto-tests/tests/modes/aes/ccm/aes_ccm.c | 120 ++++ .../crypto-tests/tests/modes/aes/ccm/aes_ccm.h | 481 ++++++++++++++ .../tests/modes/aes/cmac}/Makefile | 9 +- .../crypto-tests/tests/modes/aes/cmac/aes_cmac.c | 51 ++ .../crypto-tests/tests/modes/aes/cmac/aes_cmac.h | 72 ++ .../tests/modes/aes/ctr}/Makefile | 9 +- .../crypto-tests/tests/modes/aes/ctr/aes_ctr.c | 85 +++ .../crypto-tests/tests/modes/aes/ctr/aes_ctr.h | 289 ++++++++ .../tests/modes/aes/ecb}/Makefile | 9 +- .../crypto-tests/tests/modes/aes/ecb/aes_ecb.c | 60 ++ .../crypto-tests/tests/modes/aes/ecb/aes_ecb.h | 110 +++ .../tests/modes/aes/gcm}/Makefile | 9 +- .../crypto-tests/tests/modes/aes/gcm/aes_gcm.c | 87 +++ .../crypto-tests/tests/modes/aes/gcm/aes_gcm.h | 737 +++++++++++++++++++++ usr/src/uts/common/crypto/core/kcf_cryptoadm.c | 12 +- usr/src/uts/common/crypto/core/kcf_mech_tabs.c | 6 +- usr/src/uts/common/crypto/core/kcf_prov_lib.c | 198 ------ usr/src/uts/common/crypto/io/aes.c | 177 ++++- usr/src/uts/common/crypto/io/crypto.c | 210 +++++- usr/src/uts/common/crypto/io/dprov.c | 16 +- usr/src/uts/common/sys/crypto/common.h | 1 + usr/src/uts/common/sys/crypto/impl.h | 1 + usr/src/uts/common/sys/crypto/ioctl.h | 11 + usr/src/uts/common/sys/crypto/spi.h | 4 +- 64 files changed, 5155 insertions(+), 424 deletions(-) create mode 100644 usr/src/pkg/manifests/system-test-cryptotest.mf copy usr/src/test/{ => crypto-tests}/Makefile (69%) copy usr/src/test/{ => crypto-tests/cmd}/Makefile (69%) copy usr/src/test/{ => crypto-tests/cmd/kcf}/Makefile (53%) copy usr/src/test/{Makefile => crypto-tests/cmd/kcf/cleanup.ksh} (65%) copy usr/src/test/{Makefile => crypto-tests/cmd/kcf/setup.ksh} (65%) copy usr/src/test/{ => crypto-tests/cmd/scripts}/Makefile (54%) create mode 100644 usr/src/test/crypto-tests/cmd/scripts/cryptotest.ksh copy usr/src/test/{ => crypto-tests/doc}/Makefile (57%) create mode 100644 usr/src/test/crypto-tests/doc/README copy usr/src/test/{ => crypto-tests/runfiles}/Makefile (50%) copy usr/src/test/{Makefile => crypto-tests/runfiles/default.run} (52%) copy usr/src/test/{ => crypto-tests/tests}/Makefile (65%) copy usr/src/test/{ => crypto-tests/tests/common}/Makefile (55%) create mode 100644 usr/src/test/crypto-tests/tests/common/cryptotest.h create mode 100644 usr/src/test/crypto-tests/tests/common/cryptotest_kcf.c create mode 100644 usr/src/test/crypto-tests/tests/common/cryptotest_pkcs.c create mode 100644 usr/src/test/crypto-tests/tests/common/testfuncs.c copy usr/src/test/{ => crypto-tests/tests/modes}/Makefile (77%) copy usr/src/test/{ => crypto-tests/tests/modes/aes}/Makefile (77%) create mode 100644 usr/src/test/crypto-tests/tests/modes/aes/Makefile.subdirs copy usr/src/test/{ => crypto-tests/tests/modes/aes/cbc}/Makefile (74%) create mode 100644 usr/src/test/crypto-tests/tests/modes/aes/cbc/aes_cbc.c create mode 100644 usr/src/test/crypto-tests/tests/modes/aes/cbc/aes_cbc.h copy usr/src/test/{ => crypto-tests/tests/modes/aes/ccm}/Makefile (74%) create mode 100644 usr/src/test/crypto-tests/tests/modes/aes/ccm/aes_ccm.c create mode 100644 usr/src/test/crypto-tests/tests/modes/aes/ccm/aes_ccm.h copy usr/src/test/{ => crypto-tests/tests/modes/aes/cmac}/Makefile (74%) create mode 100644 usr/src/test/crypto-tests/tests/modes/aes/cmac/aes_cmac.c create mode 100644 usr/src/test/crypto-tests/tests/modes/aes/cmac/aes_cmac.h copy usr/src/test/{ => crypto-tests/tests/modes/aes/ctr}/Makefile (74%) create mode 100644 usr/src/test/crypto-tests/tests/modes/aes/ctr/aes_ctr.c create mode 100644 usr/src/test/crypto-tests/tests/modes/aes/ctr/aes_ctr.h copy usr/src/test/{ => crypto-tests/tests/modes/aes/ecb}/Makefile (74%) create mode 100644 usr/src/test/crypto-tests/tests/modes/aes/ecb/aes_ecb.c create mode 100644 usr/src/test/crypto-tests/tests/modes/aes/ecb/aes_ecb.h copy usr/src/test/{ => crypto-tests/tests/modes/aes/gcm}/Makefile (74%) create mode 100644 usr/src/test/crypto-tests/tests/modes/aes/gcm/aes_gcm.c create mode 100644 usr/src/test/crypto-tests/tests/modes/aes/gcm/aes_gcm.h diff --git a/usr/src/common/crypto/aes/aes_impl.h b/usr/src/common/crypto/aes/aes_impl.h index d44e261dda..d73729c03d 100644 --- a/usr/src/common/crypto/aes/aes_impl.h +++ b/usr/src/common/crypto/aes/aes_impl.h @@ -159,7 +159,8 @@ typedef enum aes_mech_type { AES_CTR_MECH_INFO_TYPE, /* SUN_CKM_AES_CTR */ AES_CCM_MECH_INFO_TYPE, /* SUN_CKM_AES_CCM */ AES_GCM_MECH_INFO_TYPE, /* SUN_CKM_AES_GCM */ - AES_GMAC_MECH_INFO_TYPE /* SUN_CKM_AES_GMAC */ + AES_GMAC_MECH_INFO_TYPE, /* SUN_CKM_AES_GMAC */ + AES_CMAC_MECH_INFO_TYPE /* SUN_CKM_AES_CMAC */ } aes_mech_type_t; #endif /* _KERNEL */ diff --git a/usr/src/common/crypto/aes/aes_modes.c b/usr/src/common/crypto/aes/aes_modes.c index a41f4d9fe4..884bfa934c 100644 --- a/usr/src/common/crypto/aes/aes_modes.c +++ b/usr/src/common/crypto/aes/aes_modes.c @@ -93,7 +93,7 @@ aes_encrypt_contiguous_blocks(void *ctx, char *data, size_t length, out, AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block, aes_xor_block); #endif - } else if (aes_ctx->ac_flags & CBC_MODE) { + } else if (aes_ctx->ac_flags & (CBC_MODE|CMAC_MODE)) { rv = cbc_encrypt_contiguous_blocks(ctx, data, length, out, AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block, aes_xor_block); diff --git a/usr/src/common/crypto/modes/cbc.c b/usr/src/common/crypto/modes/cbc.c index 3fb17ee173..69f43eba61 100644 --- a/usr/src/common/crypto/modes/cbc.c +++ b/usr/src/common/crypto/modes/cbc.c @@ -21,6 +21,7 @@ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2017 Nexenta Systems, Inc. All rights reserved. */ #ifndef _KERNEL @@ -30,10 +31,16 @@ #include #endif +#include #include #include #include #include +#include + +/* These are the CMAC Rb constants from NIST SP 800-38B */ +#define CONST_RB_128 0x87 +#define CONST_RB_64 0x1B /* * Algorithm independent CBC functions. @@ -56,7 +63,7 @@ cbc_encrypt_contiguous_blocks(cbc_ctx_t *ctx, char *data, size_t length, uint8_t *out_data_2; size_t out_data_1_len; - if (length + ctx->cbc_remainder_len < block_size) { + if (length + ctx->cbc_remainder_len < ctx->max_remain) { /* accumulate bytes here and return */ bcopy(datap, (uint8_t *)ctx->cbc_remainder + ctx->cbc_remainder_len, @@ -97,7 +104,8 @@ cbc_encrypt_contiguous_blocks(cbc_ctx_t *ctx, char *data, size_t length, ctx->cbc_lastp = blockp; lastp = blockp; - if (ctx->cbc_remainder_len > 0) { + if ((ctx->cbc_flags & CMAC_MODE) == 0 && + ctx->cbc_remainder_len > 0) { bcopy(blockp, ctx->cbc_copy_to, ctx->cbc_remainder_len); bcopy(blockp + ctx->cbc_remainder_len, datap, @@ -110,22 +118,31 @@ cbc_encrypt_contiguous_blocks(cbc_ctx_t *ctx, char *data, size_t length, */ xor_block(blockp, lastp); encrypt(ctx->cbc_keysched, lastp, lastp); - crypto_get_ptrs(out, &iov_or_mp, &offset, &out_data_1, - &out_data_1_len, &out_data_2, block_size); - /* copy block to where it belongs */ - if (out_data_1_len == block_size) { - copy_block(lastp, out_data_1); - } else { - bcopy(lastp, out_data_1, out_data_1_len); - if (out_data_2 != NULL) { - bcopy(lastp + out_data_1_len, - out_data_2, - block_size - out_data_1_len); + /* + * CMAC doesn't output until encrypt_final + */ + if ((ctx->cbc_flags & CMAC_MODE) == 0) { + crypto_get_ptrs(out, &iov_or_mp, &offset, + &out_data_1, &out_data_1_len, + &out_data_2, block_size); + + /* copy block to where it belongs */ + if (out_data_1_len == block_size) { + copy_block(lastp, out_data_1); + } else { + bcopy(lastp, out_data_1, + out_data_1_len); + if (out_data_2 != NULL) { + bcopy(lastp + out_data_1_len, + out_data_2, + block_size - + out_data_1_len); + } } + /* update offset */ + out->cd_offset += block_size; } - /* update offset */ - out->cd_offset += block_size; } /* Update pointer to next block of data to be processed. */ @@ -139,7 +156,7 @@ cbc_encrypt_contiguous_blocks(cbc_ctx_t *ctx, char *data, size_t length, remainder = (size_t)&data[length] - (size_t)datap; /* Incomplete last block. */ - if (remainder > 0 && remainder < block_size) { + if (remainder > 0 && remainder < ctx->max_remain) { bcopy(datap, ctx->cbc_remainder, remainder); ctx->cbc_remainder_len = remainder; ctx->cbc_copy_to = datap; @@ -299,14 +316,19 @@ cbc_init_ctx(cbc_ctx_t *cbc_ctx, char *param, size_t param_len, cbc_ctx->cbc_lastp = (uint8_t *)&cbc_ctx->cbc_iv[0]; cbc_ctx->cbc_flags |= CBC_MODE; + cbc_ctx->max_remain = block_size; return (CRYPTO_SUCCESS); } /* ARGSUSED */ -void * -cbc_alloc_ctx(int kmflag) +static void * +cbc_cmac_alloc_ctx(int kmflag, uint32_t mode) { cbc_ctx_t *cbc_ctx; + uint32_t modeval = mode & (CBC_MODE|CMAC_MODE); + + /* Only one of the two modes can be set */ + VERIFY(modeval == CBC_MODE || modeval == CMAC_MODE); #ifdef _KERNEL if ((cbc_ctx = kmem_zalloc(sizeof (cbc_ctx_t), kmflag)) == NULL) @@ -315,6 +337,136 @@ cbc_alloc_ctx(int kmflag) #endif return (NULL); - cbc_ctx->cbc_flags = CBC_MODE; + cbc_ctx->cbc_flags = mode; return (cbc_ctx); } + +void * +cbc_alloc_ctx(int kmflag) +{ + return (cbc_cmac_alloc_ctx(kmflag, CBC_MODE)); +} + +/* + * Algorithms for supporting AES-CMAC + * NOTE: CMAC is generally just a wrapper for CBC + */ + +void * +cmac_alloc_ctx(int kmflag) +{ + return (cbc_cmac_alloc_ctx(kmflag, CMAC_MODE)); +} + + +/* + * Typically max_remain is set to block_size - 1, since we usually + * will process the data once we have a full block. However with CMAC, + * we must preprocess the final block of data. Since we cannot know + * when we've received the final block of data until the _final() method + * is called, we must not process the last block of data until we know + * it is the last block, or we receive a new block of data. As such, + * max_remain for CMAC is block_size + 1. + */ +int +cmac_init_ctx(cbc_ctx_t *cbc_ctx, size_t block_size) +{ + /* + * CMAC is only approved for block sizes 64 and 128 bits / + * 8 and 16 bytes. + */ + + if (block_size != 16 && block_size != 8) + return (CRYPTO_INVALID_CONTEXT); + + /* + * For CMAC, cbc_iv is always 0. + */ + + cbc_ctx->cbc_iv[0] = 0; + cbc_ctx->cbc_iv[1] = 0; + + cbc_ctx->cbc_lastp = (uint8_t *)&cbc_ctx->cbc_iv[0]; + cbc_ctx->cbc_flags |= CMAC_MODE; + + cbc_ctx->max_remain = block_size + 1; + return (CRYPTO_SUCCESS); +} + +/* + * Left shifts blocks by one and returns the leftmost bit + */ +static uint8_t +cmac_left_shift_block_by1(uint8_t *block, size_t block_size) +{ + uint8_t carry = 0, old; + size_t i; + for (i = block_size; i > 0; i--) { + old = carry; + carry = (block[i - 1] & 0x80) ? 1 : 0; + block[i - 1] = (block[i - 1] << 1) | old; + } + return (carry); +} + +/* + * Generate subkeys to preprocess the last block according to RFC 4493. + * Store the final block_size MAC generated in 'out'. + */ +int +cmac_mode_final(cbc_ctx_t *cbc_ctx, crypto_data_t *out, + int (*encrypt_block)(const void *, const uint8_t *, uint8_t *), + void (*xor_block)(uint8_t *, uint8_t *)) +{ + uint8_t buf[AES_BLOCK_LEN] = {0}; + uint8_t *M_last = (uint8_t *)cbc_ctx->cbc_remainder; + size_t length = cbc_ctx->cbc_remainder_len; + size_t block_size = cbc_ctx->max_remain - 1; + uint8_t const_rb; + + if (length > block_size) + return (CRYPTO_INVALID_CONTEXT); + + if (out->cd_length < block_size) + return (CRYPTO_DATA_LEN_RANGE); + + if (block_size == 16) + const_rb = CONST_RB_128; + else if (block_size == 8) + const_rb = CONST_RB_64; + else + return (CRYPTO_INVALID_CONTEXT); + + /* k_0 = E_k(0) */ + encrypt_block(cbc_ctx->cbc_keysched, buf, buf); + + if (cmac_left_shift_block_by1(buf, block_size)) + buf[block_size - 1] ^= const_rb; + + if (length == block_size) { + /* Last block complete, so m_n = k_1 + m_n' */ + xor_block(buf, M_last); + xor_block(cbc_ctx->cbc_lastp, M_last); + encrypt_block(cbc_ctx->cbc_keysched, M_last, M_last); + } else { + /* Last block incomplete, so m_n = k_2 + (m_n' | 100...0_bin) */ + if (cmac_left_shift_block_by1(buf, block_size)) + buf[block_size - 1] ^= const_rb; + + M_last[length] = 0x80; + bzero(M_last + length + 1, block_size - length - 1); + xor_block(buf, M_last); + xor_block(cbc_ctx->cbc_lastp, M_last); + encrypt_block(cbc_ctx->cbc_keysched, M_last, M_last); + } + + /* + * zero out the sub-key. + */ +#ifndef _KERNEL + explicit_bzero(&buf, sizeof (buf)); +#else + bzero(&buf, sizeof (buf)); +#endif + return (crypto_put_output_data(M_last, out, block_size)); +} diff --git a/usr/src/common/crypto/modes/ctr.c b/usr/src/common/crypto/modes/ctr.c index e44dc3e642..919ed3ab53 100644 --- a/usr/src/common/crypto/modes/ctr.c +++ b/usr/src/common/crypto/modes/ctr.c @@ -169,13 +169,9 @@ ctr_mode_final(ctr_ctx_t *ctx, crypto_data_t *out, int (*encrypt_block)(const void *, const uint8_t *, uint8_t *)) { uint8_t *lastp; - void *iov_or_mp; - offset_t offset; - uint8_t *out_data_1; - uint8_t *out_data_2; - size_t out_data_1_len; uint8_t *p; int i; + int rv; if (out->cd_length < ctx->ctr_remainder_len) return (CRYPTO_DATA_LEN_RANGE); @@ -189,23 +185,17 @@ ctr_mode_final(ctr_ctx_t *ctx, crypto_data_t *out, p[i] ^= lastp[i]; } - crypto_init_ptrs(out, &iov_or_mp, &offset); - crypto_get_ptrs(out, &iov_or_mp, &offset, &out_data_1, - &out_data_1_len, &out_data_2, ctx->ctr_remainder_len); - - bcopy(p, out_data_1, out_data_1_len); - if (out_data_2 != NULL) { - bcopy((uint8_t *)p + out_data_1_len, - out_data_2, ctx->ctr_remainder_len - out_data_1_len); + rv = crypto_put_output_data(p, out, ctx->ctr_remainder_len); + if (rv == CRYPTO_SUCCESS) { + out->cd_offset += ctx->ctr_remainder_len; + ctx->ctr_remainder_len = 0; } - out->cd_offset += ctx->ctr_remainder_len; - ctx->ctr_remainder_len = 0; - return (CRYPTO_SUCCESS); + return (rv); } int ctr_init_ctx(ctr_ctx_t *ctr_ctx, ulong_t count, uint8_t *cb, -void (*copy_block)(uint8_t *, uint8_t *)) + void (*copy_block)(uint8_t *, uint8_t *)) { uint64_t upper_mask = 0; uint64_t lower_mask = 0; diff --git a/usr/src/common/crypto/modes/modes.c b/usr/src/common/crypto/modes/modes.c index 19bf8cc16c..fbf66c0531 100644 --- a/usr/src/common/crypto/modes/modes.c +++ b/usr/src/common/crypto/modes/modes.c @@ -21,10 +21,14 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright 2014 Nexenta Systems, Inc. All rights reserved. */ #ifndef _KERNEL #include +#include +#include #endif #include @@ -170,8 +174,8 @@ crypto_free_mode_ctx(void *ctx) { common_ctx_t *common_ctx = (common_ctx_t *)ctx; - switch (common_ctx->cc_flags & - (ECB_MODE|CBC_MODE|CTR_MODE|CCM_MODE|GCM_MODE|GMAC_MODE)) { + switch (common_ctx->cc_flags & (ECB_MODE|CBC_MODE|CMAC_MODE|CTR_MODE| + CCM_MODE|GCM_MODE|GMAC_MODE)) { case ECB_MODE: #ifdef _KERNEL kmem_free(common_ctx, sizeof (ecb_ctx_t)); @@ -181,6 +185,7 @@ crypto_free_mode_ctx(void *ctx) break; case CBC_MODE: + case CMAC_MODE: #ifdef _KERNEL kmem_free(common_ctx, sizeof (cbc_ctx_t)); #else @@ -225,3 +230,212 @@ crypto_free_mode_ctx(void *ctx) #endif } } + +/* + * Utility routine to apply the command, 'cmd', to the + * data in the uio structure. + */ +int +crypto_uio_data(crypto_data_t *data, uchar_t *buf, int len, cmd_type_t cmd, + void *digest_ctx, void (*update)()) +{ + uio_t *uiop = data->cd_uio; + off_t offset = data->cd_offset; + size_t length = len; + uint_t vec_idx; + size_t cur_len; + uchar_t *datap; + +#ifdef _KERNEL + ASSERT3U(data->cd_format, ==, CRYPTO_DATA_UIO); +#else + assert(data->cd_format == CRYPTO_DATA_UIO); +#endif + if (uiop->uio_segflg != UIO_SYSSPACE) { + return (CRYPTO_ARGUMENTS_BAD); + } + + /* + * Jump to the first iovec containing data to be + * processed. + */ + for (vec_idx = 0; vec_idx < uiop->uio_iovcnt && + offset >= uiop->uio_iov[vec_idx].iov_len; + offset -= uiop->uio_iov[vec_idx++].iov_len) + ; + + if (vec_idx == uiop->uio_iovcnt) { + /* + * The caller specified an offset that is larger than + * the total size of the buffers it provided. + */ + return (CRYPTO_DATA_LEN_RANGE); + } + + while (vec_idx < uiop->uio_iovcnt && length > 0) { + cur_len = MIN(uiop->uio_iov[vec_idx].iov_len - + offset, length); + + datap = (uchar_t *)(uiop->uio_iov[vec_idx].iov_base + + offset); + switch (cmd) { + case COPY_FROM_DATA: + bcopy(datap, buf, cur_len); + buf += cur_len; + break; + case COPY_TO_DATA: + bcopy(buf, datap, cur_len); + buf += cur_len; + break; + case COMPARE_TO_DATA: + if (bcmp(datap, buf, cur_len)) + return (CRYPTO_SIGNATURE_INVALID); + buf += cur_len; + break; + case MD5_DIGEST_DATA: + case SHA1_DIGEST_DATA: + case SHA2_DIGEST_DATA: + case GHASH_DATA: + update(digest_ctx, datap, cur_len); + break; + } + + length -= cur_len; + vec_idx++; + offset = 0; + } + + if (vec_idx == uiop->uio_iovcnt && length > 0) { + /* + * The end of the specified iovec's was reached but + * the length requested could not be processed. + */ + switch (cmd) { + case COPY_TO_DATA: + data->cd_length = len; + return (CRYPTO_BUFFER_TOO_SMALL); + default: + return (CRYPTO_DATA_LEN_RANGE); + } + } + + return (CRYPTO_SUCCESS); +} + +/* + * Utility routine to apply the command, 'cmd', to the + * data in the mblk structure. + */ +int +crypto_mblk_data(crypto_data_t *data, uchar_t *buf, int len, cmd_type_t cmd, + void *digest_ctx, void (*update)()) +{ + off_t offset = data->cd_offset; + size_t length = len; + mblk_t *mp; + size_t cur_len; + uchar_t *datap; + +#ifdef _KERNEL + ASSERT3U(data->cd_format, ==, CRYPTO_DATA_MBLK); +#else + assert(data->cd_format == CRYPTO_DATA_MBLK); +#endif + /* + * Jump to the first mblk_t containing data to be processed. + */ + for (mp = data->cd_mp; mp != NULL && offset >= MBLKL(mp); + offset -= MBLKL(mp), mp = mp->b_cont) + ; + if (mp == NULL) { + /* + * The caller specified an offset that is larger + * than the total size of the buffers it provided. + */ + return (CRYPTO_DATA_LEN_RANGE); + } + + /* + * Now do the processing on the mblk chain. + */ + while (mp != NULL && length > 0) { + cur_len = MIN(MBLKL(mp) - offset, length); + + datap = (uchar_t *)(mp->b_rptr + offset); + switch (cmd) { + case COPY_FROM_DATA: + bcopy(datap, buf, cur_len); + buf += cur_len; + break; + case COPY_TO_DATA: + bcopy(buf, datap, cur_len); + buf += cur_len; + break; + case COMPARE_TO_DATA: + if (bcmp(datap, buf, cur_len)) + return (CRYPTO_SIGNATURE_INVALID); + buf += cur_len; + break; + case MD5_DIGEST_DATA: + case SHA1_DIGEST_DATA: + case SHA2_DIGEST_DATA: + case GHASH_DATA: + update(digest_ctx, datap, cur_len); + break; + } + + length -= cur_len; + offset = 0; + mp = mp->b_cont; + } + + if (mp == NULL && length > 0) { + /* + * The end of the mblk was reached but the length + * requested could not be processed. + */ + switch (cmd) { + case COPY_TO_DATA: + data->cd_length = len; + return (CRYPTO_BUFFER_TOO_SMALL); + default: + return (CRYPTO_DATA_LEN_RANGE); + } + } + + return (CRYPTO_SUCCESS); +} + +/* + * Utility routine to copy a buffer to a crypto_data structure. + */ +int +crypto_put_output_data(uchar_t *buf, crypto_data_t *output, int len) +{ + switch (output->cd_format) { + case CRYPTO_DATA_RAW: + if (MAXOFF_T - output->cd_offset < (off_t)len) { + return (CRYPTO_ARGUMENTS_BAD); + } + if (output->cd_raw.iov_len < len + output->cd_offset) { + output->cd_length = len; + return (CRYPTO_BUFFER_TOO_SMALL); + } + bcopy(buf, (uchar_t *)(output->cd_raw.iov_base + + output->cd_offset), len); + break; + + case CRYPTO_DATA_UIO: + return (crypto_uio_data(output, buf, len, + COPY_TO_DATA, NULL, NULL)); + + case CRYPTO_DATA_MBLK: + return (crypto_mblk_data(output, buf, len, + COPY_TO_DATA, NULL, NULL)); + + default: + return (CRYPTO_ARGUMENTS_BAD); + } + + return (CRYPTO_SUCCESS); +} diff --git a/usr/src/common/crypto/modes/modes.h b/usr/src/common/crypto/modes/modes.h index 26f3b37b0e..efb3770eea 100644 --- a/usr/src/common/crypto/modes/modes.h +++ b/usr/src/common/crypto/modes/modes.h @@ -21,6 +21,8 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright 2014 Nexenta Systems, Inc. All rights reserved. */ #ifndef _COMMON_CRYPTO_MODES_H @@ -46,6 +48,7 @@ extern "C" { #define CCM_MODE 0x00000010 #define GCM_MODE 0x00000020 #define GMAC_MODE 0x00000040 +#define CMAC_MODE 0x00000080 /* * cc_keysched: Pointer to key schedule. @@ -100,9 +103,13 @@ typedef struct ecb_ctx { #define ecb_copy_to ecb_common.cc_copy_to #define ecb_flags ecb_common.cc_flags +/* + * max_remain max bytes in cbc_remainder + */ typedef struct cbc_ctx { struct common_ctx cbc_common; uint64_t cbc_lastblock[2]; + size_t max_remain; } cbc_ctx_t; #define cbc_keysched cbc_common.cc_keysched @@ -345,12 +352,18 @@ extern int gcm_decrypt_final(gcm_ctx_t *, crypto_data_t *, size_t, int (*encrypt_block)(const void *, const uint8_t *, uint8_t *), void (*xor_block)(uint8_t *, uint8_t *)); +extern int cmac_mode_final(cbc_ctx_t *, crypto_data_t *, + int (*encrypt_block)(const void *, const uint8_t *, uint8_t *), + void (*xor_block)(uint8_t *, uint8_t *)); + extern int ctr_mode_final(ctr_ctx_t *, crypto_data_t *, int (*encrypt_block)(const void *, const uint8_t *, uint8_t *)); extern int cbc_init_ctx(cbc_ctx_t *, char *, size_t, size_t, void (*copy_block)(uint8_t *, uint64_t *)); +extern int cmac_init_ctx(cbc_ctx_t *, size_t); + extern int ctr_init_ctx(ctr_ctx_t *, ulong_t, uint8_t *, void (*copy_block)(uint8_t *, uint8_t *)); @@ -379,12 +392,14 @@ extern void crypto_get_ptrs(crypto_data_t *, void **, offset_t *, extern void *ecb_alloc_ctx(int); extern void *cbc_alloc_ctx(int); +extern void *cmac_alloc_ctx(int); extern void *ctr_alloc_ctx(int); extern void *ccm_alloc_ctx(int); extern void *gcm_alloc_ctx(int); extern void *gmac_alloc_ctx(int); extern void crypto_free_mode_ctx(void *); extern void gcm_set_kmflag(gcm_ctx_t *, int); +extern int crypto_put_output_data(uchar_t *, crypto_data_t *, int); #ifdef __cplusplus } diff --git a/usr/src/lib/pkcs11/libsoftcrypto/common/mapfile-vers b/usr/src/lib/pkcs11/libsoftcrypto/common/mapfile-vers index 293319c719..377db64fa5 100644 --- a/usr/src/lib/pkcs11/libsoftcrypto/common/mapfile-vers +++ b/usr/src/lib/pkcs11/libsoftcrypto/common/mapfile-vers @@ -49,6 +49,7 @@ SYMBOL_VERSION SUNWprivate { aes_encrypt_block; aes_encrypt_contiguous_blocks; aes_init_keysched; + aes_xor_block; arcfour_crypt; arcfour_key_init; big_One; @@ -76,6 +77,9 @@ SYMBOL_VERSION SUNWprivate { blowfish_encrypt_contiguous_blocks; blowfish_init_keysched; bytestring2bignum; + cbc_alloc_ctx; + cmac_init_ctx; + cmac_mode_final; ctr_mode_final; ctr_init_ctx; des3_crunch_block; diff --git a/usr/src/lib/pkcs11/pkcs11_kernel/Makefile.com b/usr/src/lib/pkcs11/pkcs11_kernel/Makefile.com index d71ccc01aa..e44f6cfec0 100644 --- a/usr/src/lib/pkcs11/pkcs11_kernel/Makefile.com +++ b/usr/src/lib/pkcs11/pkcs11_kernel/Makefile.com @@ -59,12 +59,13 @@ ARCFOURDIR= $(SRC)/common/crypto/arcfour BLOWFISHDIR= $(SRC)/common/crypto/blowfish DESDIR= $(SRC)/common/crypto/des ECCDIR= $(SRC)/common/crypto/ecc +CRYPTDIR= $(SRC)/common/crypto ST_DIR= $(SRC)/lib/pkcs11/pkcs11_softtoken/common lint \ pics/kernelAttributeUtil.o := \ CPPFLAGS += -I$(AESDIR) -I$(BLOWFISHDIR) -I$(ARCFOURDIR) -I$(DESDIR) \ - -I$(ECCDIR) + -I$(ECCDIR) -I$(CRYPTDIR) pics/kernelKeys.o := \ CPPFLAGS += -I$(ECCDIR) pics/kernelSoftCommon.o := \ diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softAESCrypt.c b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softAESCrypt.c index 7f2810033b..bc8edcdc4c 100644 --- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softAESCrypt.c +++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softAESCrypt.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2014 Nexenta Systems, Inc. All rights reserved. */ #include @@ -29,10 +30,11 @@ #include #include #include +#include #include "softSession.h" #include "softObject.h" #include "softCrypt.h" -#include +#include "softOps.h" /* * Allocate context for the active encryption or decryption operation, and @@ -179,7 +181,8 @@ soft_aes_encrypt_common(soft_session_t *session_p, CK_BYTE_PTR pData, * AES allows any input length for C_Encrypt function with the * mechanism CKM_AES_CBC_PAD and for C_EncryptUpdate function. */ - if ((!update) && (mechanism != CKM_AES_CBC_PAD)) { + if ((!update) && (mechanism != CKM_AES_CBC_PAD) && + (mechanism != CKM_AES_CMAC)) { if ((ulDataLen % AES_BLOCK_LEN) != 0) { rv = CKR_DATA_LEN_RANGE; goto cleanup; @@ -201,6 +204,8 @@ soft_aes_encrypt_common(soft_session_t *session_p, CK_BYTE_PTR pData, */ out_len = AES_BLOCK_LEN * (ulDataLen / AES_BLOCK_LEN + 1); + } else if (mechanism == CKM_AES_CMAC) { + out_len = AES_BLOCK_LEN; } else { /* * For non-padding mode, the output length will @@ -247,6 +252,24 @@ soft_aes_encrypt_common(soft_session_t *session_p, CK_BYTE_PTR pData, * encryption until when more data comes in next * C_EncryptUpdate or when C_EncryptFinal is called. */ + out_buf = pEncrypted; + + /* + * We prefer to let the underlying implementation of CMAC handle + * the storing of extra bytes, and no data is output until + * *_final, so skip that part of the following validation. + */ + if (mechanism == CKM_AES_CMAC) { + if (pEncrypted == NULL) { + *pulEncryptedLen = ulDataLen; + return (CKR_OK); + } + + remain = 0; + in_buf = pData; + goto do_encryption; + } + if ((total_len < AES_BLOCK_LEN) || ((mechanism == CKM_AES_CBC_PAD) && (total_len == AES_BLOCK_LEN))) { @@ -304,7 +327,6 @@ soft_aes_encrypt_common(soft_session_t *session_p, CK_BYTE_PTR pData, } else { in_buf = pData; } - out_buf = pEncrypted; } do_encryption: @@ -344,6 +366,9 @@ do_encryption: break; } + case CKM_AES_CMAC: + out_len = ulDataLen; + /*FALLTHRU*/ case CKM_AES_CBC: case CKM_AES_CBC_PAD: { @@ -397,6 +422,13 @@ do_encryption: (char *)tmpblock, AES_BLOCK_LEN, &out); out_len += AES_BLOCK_LEN; + } else if (mechanism == CKM_AES_CMAC) { + out.cd_length = AES_BLOCK_LEN; + out.cd_raw.iov_base = (char *)out_buf; + out.cd_raw.iov_len = AES_BLOCK_LEN; + + rc = cmac_mode_final(soft_aes_ctx->aes_cbc, &out, + aes_encrypt_block, aes_xor_block); } if (rc == 0) { @@ -435,6 +467,13 @@ encrypt_failed: if (((aes_ctx_t *)soft_aes_ctx->aes_cbc)->ac_remainder_len > 0) rc = ctr_mode_final(soft_aes_ctx->aes_cbc, &out, aes_encrypt_block); + + /* + * Even though success means we've encrypted all of the input, + * we should still behave like the other functions and return + * the encrypted length in pulEncryptedLen + */ + *pulEncryptedLen = ulDataLen; } } /* end switch */ @@ -790,6 +829,14 @@ decrypt_failed: if (rc == CRYPTO_DATA_LEN_RANGE) rc = CRYPTO_ENCRYPTED_DATA_LEN_RANGE; } + + /* + * Even though success means we've decrypted all of the input, + * we should still behave like the other functions and return + * the decrypted length in pulDataLen + */ + *pulDataLen = ulEncryptedLen; + } } /* end switch */ @@ -838,6 +885,26 @@ aes_cbc_ctx_init(void *key_sched, size_t size, uint8_t *ivec) cbc_ctx->cbc_lastp = (uint8_t *)cbc_ctx->cbc_iv; cbc_ctx->cbc_flags |= CBC_MODE; + cbc_ctx->max_remain = AES_BLOCK_LEN; + + return (cbc_ctx); +} + +void * +aes_cmac_ctx_init(void *key_sched, size_t size) +{ + + cbc_ctx_t *cbc_ctx; + + if ((cbc_ctx = calloc(1, sizeof (cbc_ctx_t))) == NULL) + return (NULL); + + cbc_ctx->cbc_keysched = key_sched; + cbc_ctx->cbc_keysched_len = size; + + cbc_ctx->cbc_lastp = (uint8_t *)cbc_ctx->cbc_iv; + cbc_ctx->cbc_flags |= CMAC_MODE; + cbc_ctx->max_remain = AES_BLOCK_LEN + 1; return (cbc_ctx); } @@ -869,3 +936,182 @@ aes_ctr_ctx_init(void *key_sched, size_t size, uint8_t *param) return (ctr_ctx); } + +/* + * Allocate and initialize AES contexts for both signing and encrypting, + * saving both context pointers in the session struct. For general-length AES + * MAC, check the length in the parameter to see if it is in the right range. + */ +CK_RV +soft_aes_sign_verify_init_common(soft_session_t *session_p, + CK_MECHANISM_PTR pMechanism, soft_object_t *key_p, boolean_t sign_op) +{ + soft_aes_ctx_t *soft_aes_ctx; + CK_MECHANISM encrypt_mech; + CK_RV rv; + + if (key_p->key_type != CKK_AES) { + return (CKR_KEY_TYPE_INCONSISTENT); + } + + /* allocate memory for the sign/verify context */ + soft_aes_ctx = malloc(sizeof (soft_aes_ctx_t)); + if (soft_aes_ctx == NULL) { + return (CKR_HOST_MEMORY); + } + + /* initialization vector is zero for AES CMAC */ + bzero(soft_aes_ctx->ivec, AES_BLOCK_LEN); + + switch (pMechanism->mechanism) { + + case CKM_AES_CMAC_GENERAL: + + if (pMechanism->ulParameterLen != + sizeof (CK_MAC_GENERAL_PARAMS)) { + free(soft_aes_ctx); + return (CKR_MECHANISM_PARAM_INVALID); + } + + if (*(CK_MAC_GENERAL_PARAMS *)pMechanism->pParameter > + AES_BLOCK_LEN) { + free(soft_aes_ctx); + return (CKR_MECHANISM_PARAM_INVALID); + } + + soft_aes_ctx->mac_len = *((CK_MAC_GENERAL_PARAMS_PTR) + pMechanism->pParameter); + + /*FALLTHRU*/ + case CKM_AES_CMAC: + + /* + * For non-general AES MAC, output is always block size + */ + if (pMechanism->mechanism == CKM_AES_CMAC) { + soft_aes_ctx->mac_len = AES_BLOCK_LEN; + } + + /* allocate a context for AES encryption */ + encrypt_mech.mechanism = CKM_AES_CMAC; + encrypt_mech.pParameter = (void *)soft_aes_ctx->ivec; + encrypt_mech.ulParameterLen = AES_BLOCK_LEN; + rv = soft_encrypt_init_internal(session_p, &encrypt_mech, + key_p); + if (rv != CKR_OK) { + free(soft_aes_ctx); + return (rv); + } + + (void) pthread_mutex_lock(&session_p->session_mutex); + + if (sign_op) { + session_p->sign.context = soft_aes_ctx; + session_p->sign.mech.mechanism = pMechanism->mechanism; + } else { + session_p->verify.context = soft_aes_ctx; + session_p->verify.mech.mechanism = + pMechanism->mechanism; + } + + (void) pthread_mutex_unlock(&session_p->session_mutex); + + break; + } + return (CKR_OK); +} + +/* + * Called by soft_sign(), soft_sign_final(), soft_verify() or + * soft_verify_final(). + */ +CK_RV +soft_aes_sign_verify_common(soft_session_t *session_p, CK_BYTE_PTR pData, + CK_ULONG ulDataLen, CK_BYTE_PTR pSigned, CK_ULONG_PTR pulSignedLen, + boolean_t sign_op, boolean_t Final) +{ + soft_aes_ctx_t *soft_aes_ctx_sign_verify; + CK_RV rv; + CK_BYTE *pEncrypted = NULL; + CK_ULONG ulEncryptedLen = AES_BLOCK_LEN; + CK_BYTE last_block[AES_BLOCK_LEN]; + + if (sign_op) { + soft_aes_ctx_sign_verify = + (soft_aes_ctx_t *)session_p->sign.context; + + if (soft_aes_ctx_sign_verify->mac_len == 0) { + *pulSignedLen = 0; + goto clean_exit; + } + + /* Application asks for the length of the output buffer. */ + if (pSigned == NULL) { + *pulSignedLen = soft_aes_ctx_sign_verify->mac_len; + return (CKR_OK); + } + + /* Is the application-supplied buffer large enough? */ + if (*pulSignedLen < soft_aes_ctx_sign_verify->mac_len) { + *pulSignedLen = soft_aes_ctx_sign_verify->mac_len; + return (CKR_BUFFER_TOO_SMALL); + } + } else { + soft_aes_ctx_sign_verify = + (soft_aes_ctx_t *)session_p->verify.context; + } + + if (Final) { + rv = soft_encrypt_final(session_p, last_block, + &ulEncryptedLen); + } else { + rv = soft_encrypt(session_p, pData, ulDataLen, + last_block, &ulEncryptedLen); + } + + if (rv == CKR_OK) { + *pulSignedLen = soft_aes_ctx_sign_verify->mac_len; + + /* the leftmost mac_len bytes of last_block is our MAC */ + (void) memcpy(pSigned, last_block, *pulSignedLen); + } + +clean_exit: + + (void) pthread_mutex_lock(&session_p->session_mutex); + + /* soft_encrypt_common() has freed the encrypt context */ + if (sign_op) { + free(session_p->sign.context); + session_p->sign.context = NULL; + } else { + free(session_p->verify.context); + session_p->verify.context = NULL; + } + session_p->encrypt.flags = 0; + + (void) pthread_mutex_unlock(&session_p->session_mutex); + + if (pEncrypted) { + free(pEncrypted); + } + + return (rv); +} + +/* + * Called by soft_sign_update() + */ +CK_RV +soft_aes_mac_sign_verify_update(soft_session_t *session_p, CK_BYTE_PTR pPart, + CK_ULONG ulPartLen) +{ + CK_BYTE buf[AES_BLOCK_LEN]; + CK_ULONG ulEncryptedLen = AES_BLOCK_LEN; + CK_RV rv; + + rv = soft_encrypt_update(session_p, pPart, ulPartLen, + buf, &ulEncryptedLen); + + return (rv); +} diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softCrypt.h b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softCrypt.h index d4c58bc9d3..eb9f69e74b 100644 --- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softCrypt.h +++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softCrypt.h @@ -59,6 +59,7 @@ typedef struct soft_aes_ctx { uint8_t data[AES_BLOCK_LEN]; /* for use by update */ size_t remain_len; /* for use by update */ void *aes_cbc; /* to be used by CBC mode */ + size_t mac_len; } soft_aes_ctx_t; typedef struct soft_blowfish_ctx { @@ -84,15 +85,14 @@ CK_RV soft_des_encrypt_common(soft_session_t *, CK_BYTE_PTR, CK_ULONG, CK_RV soft_des_decrypt_common(soft_session_t *, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR, boolean_t); -CK_RV soft_des_sign_verify_common(soft_session_t *session_p, CK_BYTE_PTR pData, - CK_ULONG ulDataLen, CK_BYTE_PTR pSigned, CK_ULONG_PTR pulSignedLen, - boolean_t sign_op, boolean_t Final); +CK_RV soft_des_sign_verify_common(soft_session_t *, CK_BYTE_PTR, + CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR, + boolean_t, boolean_t); -CK_RV soft_des_sign_verify_init_common(soft_session_t *session_p, - CK_MECHANISM_PTR pMechanism, soft_object_t *key_p, boolean_t sign_op); +CK_RV soft_des_sign_verify_init_common(soft_session_t *, CK_MECHANISM_PTR, + soft_object_t *, boolean_t); -CK_RV soft_des_mac_sign_verify_update(soft_session_t *session_p, - CK_BYTE_PTR pPart, CK_ULONG ulPartLen); +CK_RV soft_des_mac_sign_verify_update(soft_session_t *, CK_BYTE_PTR, CK_ULONG); void soft_add_pkcs7_padding(CK_BYTE *, int, CK_ULONG); @@ -105,6 +105,7 @@ CK_RV soft_arcfour_crypt(crypto_active_op_t *, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR); void *aes_cbc_ctx_init(void *, size_t, uint8_t *); +void *aes_cmac_ctx_init(void *, size_t); void *aes_ctr_ctx_init(void *, size_t, uint8_t *); CK_RV soft_aes_crypt_init_common(soft_session_t *, CK_MECHANISM_PTR, @@ -116,6 +117,15 @@ CK_RV soft_aes_encrypt_common(soft_session_t *, CK_BYTE_PTR, CK_ULONG, CK_RV soft_aes_decrypt_common(soft_session_t *, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR, boolean_t); +CK_RV soft_aes_sign_verify_common(soft_session_t *, CK_BYTE_PTR, + CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR, + boolean_t, boolean_t); + +CK_RV soft_aes_sign_verify_init_common(soft_session_t *, CK_MECHANISM_PTR, + soft_object_t *, boolean_t); + +CK_RV soft_aes_mac_sign_verify_update(soft_session_t *, CK_BYTE_PTR, CK_ULONG); + void *blowfish_cbc_ctx_init(void *, size_t, uint8_t *); CK_RV soft_blowfish_crypt_init_common(soft_session_t *, CK_MECHANISM_PTR, diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softEncryptUtil.c b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softEncryptUtil.c index 39e863065e..aebacaa868 100644 --- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softEncryptUtil.c +++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softEncryptUtil.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2015 Nexenta Systems, Inc. All rights reserved. */ #include @@ -48,14 +49,14 @@ soft_add_pkcs7_padding(CK_BYTE *buf, int block_size, CK_ULONG data_len) /* * Perform encrypt init operation internally for the support of - * CKM_DES_MAC and CKM_DES_MAC_GENERAL + * CKM_AES and CKM_DES MAC operations. * * This function is called with the session being held, and without * its mutex taken. */ CK_RV soft_encrypt_init_internal(soft_session_t *session_p, CK_MECHANISM_PTR - pMechanism, soft_object_t *key_p) + pMechanism, soft_object_t *key_p) { CK_RV rv; @@ -197,6 +198,12 @@ cbc_common: case CKM_AES_CBC: case CKM_AES_CBC_PAD: + if ((pMechanism->pParameter == NULL) || + (pMechanism->ulParameterLen != AES_BLOCK_LEN)) { + return (CKR_MECHANISM_PARAM_INVALID); + } + /* FALLTHRU */ + case CKM_AES_CMAC: { soft_aes_ctx_t *soft_aes_ctx; @@ -204,10 +211,6 @@ cbc_common: return (CKR_KEY_TYPE_INCONSISTENT); } - if ((pMechanism->pParameter == NULL) || - (pMechanism->ulParameterLen != AES_BLOCK_LEN)) { - return (CKR_MECHANISM_PARAM_INVALID); - } rv = soft_aes_crypt_init_common(session_p, pMechanism, key_p, B_TRUE); @@ -219,14 +222,22 @@ cbc_common: soft_aes_ctx = (soft_aes_ctx_t *)session_p->encrypt.context; /* Copy Initialization Vector (IV) into the context. */ - (void) memcpy(soft_aes_ctx->ivec, pMechanism->pParameter, - AES_BLOCK_LEN); - - /* Allocate a context for AES cipher-block chaining. */ - soft_aes_ctx->aes_cbc = (void *)aes_cbc_ctx_init( - soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len, - soft_aes_ctx->ivec); - + if (pMechanism->mechanism == CKM_AES_CMAC) { + (void) bzero(soft_aes_ctx->ivec, AES_BLOCK_LEN); + /* Allocate a context for AES cipher-block chaining. */ + soft_aes_ctx->aes_cbc = (void *)aes_cmac_ctx_init( + soft_aes_ctx->key_sched, + soft_aes_ctx->keysched_len); + } else { + (void) memcpy(soft_aes_ctx->ivec, + pMechanism->pParameter, + AES_BLOCK_LEN); + /* Allocate a context for AES cipher-block chaining. */ + soft_aes_ctx->aes_cbc = (void *)aes_cbc_ctx_init( + soft_aes_ctx->key_sched, + soft_aes_ctx->keysched_len, + soft_aes_ctx->ivec); + } if (soft_aes_ctx->aes_cbc == NULL) { bzero(soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len); @@ -404,6 +415,7 @@ soft_encrypt_common(soft_session_t *session_p, CK_BYTE_PTR pData, } /* FALLTHROUGH */ + case CKM_AES_CMAC: case CKM_AES_CBC_PAD: return (soft_aes_encrypt_common(session_p, pData, @@ -488,8 +500,8 @@ soft_encrypt(soft_session_t *session_p, CK_BYTE_PTR pData, */ CK_RV soft_encrypt_update(soft_session_t *session_p, CK_BYTE_PTR pPart, - CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, - CK_ULONG_PTR pulEncryptedPartLen) + CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, + CK_ULONG_PTR pulEncryptedPartLen) { CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism; @@ -505,6 +517,7 @@ soft_encrypt_update(soft_session_t *session_p, CK_BYTE_PTR pPart, case CKM_AES_ECB: case CKM_AES_CBC: case CKM_AES_CBC_PAD: + case CKM_AES_CMAC: case CKM_AES_CTR: case CKM_BLOWFISH_CBC: case CKM_RC4: @@ -538,7 +551,7 @@ soft_encrypt_update(soft_session_t *session_p, CK_BYTE_PTR pPart, */ CK_RV soft_encrypt_final(soft_session_t *session_p, CK_BYTE_PTR pLastEncryptedPart, - CK_ULONG_PTR pulLastEncryptedPartLen) + CK_ULONG_PTR pulLastEncryptedPartLen) { CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism; @@ -717,6 +730,46 @@ soft_encrypt_final(soft_session_t *session_p, CK_BYTE_PTR pLastEncryptedPart, break; } + case CKM_AES_CMAC: + { + soft_aes_ctx_t *soft_aes_ctx; + soft_aes_ctx = (soft_aes_ctx_t *)session_p->encrypt.context; + + if (pLastEncryptedPart == NULL) { + /* + * Application asks for the length of the output + * buffer to hold the ciphertext. + */ + *pulLastEncryptedPartLen = AES_BLOCK_LEN; + goto clean1; + } else { + crypto_data_t out; + + out.cd_format = CRYPTO_DATA_RAW; + out.cd_offset = 0; + out.cd_length = AES_BLOCK_LEN; + out.cd_raw.iov_base = (char *)pLastEncryptedPart; + out.cd_raw.iov_len = AES_BLOCK_LEN; + + rc = cmac_mode_final(soft_aes_ctx->aes_cbc, &out, + aes_encrypt_block, aes_xor_block); + + if (rc == 0) { + *pulLastEncryptedPartLen = AES_BLOCK_LEN; + } else { + *pulLastEncryptedPartLen = 0; + rv = CKR_FUNCTION_FAILED; + } + + /* Cleanup memory space. */ + free(soft_aes_ctx->aes_cbc); + bzero(soft_aes_ctx->key_sched, + soft_aes_ctx->keysched_len); + free(soft_aes_ctx->key_sched); + } + + break; + } case CKM_AES_CBC: case CKM_AES_ECB: { @@ -840,7 +893,7 @@ clean1: */ void soft_crypt_cleanup(soft_session_t *session_p, boolean_t encrypt, - boolean_t lock_held) + boolean_t lock_held) { crypto_active_op_t *active_op; @@ -881,6 +934,7 @@ soft_crypt_cleanup(soft_session_t *session_p, boolean_t encrypt, case CKM_AES_CBC_PAD: case CKM_AES_CBC: + case CKM_AES_CMAC: case CKM_AES_ECB: { soft_aes_ctx_t *soft_aes_ctx = diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSignUtil.c b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSignUtil.c index 586dd76fdc..f8824df2dd 100644 --- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSignUtil.c +++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSignUtil.c @@ -21,10 +21,9 @@ /* * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2014 Nexenta Systems, Inc. All rights reserved. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include #include #include @@ -103,6 +102,12 @@ soft_sign_init(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism, return (soft_des_sign_verify_init_common(session_p, pMechanism, key_p, B_TRUE)); + case CKM_AES_CMAC_GENERAL: + case CKM_AES_CMAC: + + return (soft_aes_sign_verify_init_common(session_p, pMechanism, + key_p, B_TRUE)); + default: return (CKR_MECHANISM_INVALID); } @@ -187,6 +192,27 @@ soft_sign(soft_session_t *session_p, CK_BYTE_PTR pData, return (rv); } + case CKM_AES_CMAC_GENERAL: + case CKM_AES_CMAC: + { + CK_BYTE signature[AES_BLOCK_LEN]; + + if (pSignature != NULL) { + /* Pass local buffer to avoid overflow. */ + rv = soft_aes_sign_verify_common(session_p, pData, + ulDataLen, signature, pulSignatureLen, B_TRUE, + B_FALSE); + } else { + /* Pass NULL, let callee handle it. */ + rv = soft_aes_sign_verify_common(session_p, pData, + ulDataLen, NULL, pulSignatureLen, B_TRUE, B_FALSE); + } + + if ((rv == CKR_OK) && (pSignature != NULL)) + (void) memcpy(pSignature, signature, *pulSignatureLen); + + return (rv); + } case CKM_RSA_X_509: case CKM_RSA_PKCS: @@ -271,6 +297,12 @@ soft_sign_update(soft_session_t *session_p, CK_BYTE_PTR pPart, return (soft_des_mac_sign_verify_update(session_p, pPart, ulPartLen)); + case CKM_AES_CMAC_GENERAL: + case CKM_AES_CMAC: + + return (soft_aes_mac_sign_verify_update(session_p, pPart, + ulPartLen)); + case CKM_MD5_RSA_PKCS: case CKM_SHA1_RSA_PKCS: case CKM_SHA256_RSA_PKCS: @@ -367,6 +399,26 @@ soft_sign_final(soft_session_t *session_p, CK_BYTE_PTR pSignature, return (rv); } + case CKM_AES_CMAC_GENERAL: + case CKM_AES_CMAC: + { + CK_BYTE signature[AES_BLOCK_LEN]; /* use the maximum size */ + + if (pSignature != NULL) { + /* Pass local buffer to avoid overflow. */ + rv = soft_aes_sign_verify_common(session_p, NULL, 0, + signature, pulSignatureLen, B_TRUE, B_TRUE); + } else { + /* Pass NULL, let callee handle it. */ + rv = soft_aes_sign_verify_common(session_p, NULL, 0, + NULL, pulSignatureLen, B_TRUE, B_TRUE); + } + + if ((rv == CKR_OK) && (pSignature != NULL)) + (void) memcpy(pSignature, signature, *pulSignatureLen); + + return (rv); + } case CKM_MD5_RSA_PKCS: case CKM_SHA1_RSA_PKCS: case CKM_SHA256_RSA_PKCS: @@ -524,6 +576,17 @@ soft_sign_verify_cleanup(soft_session_t *session_p, boolean_t sign, bzero(active_op->context, sizeof (soft_des_ctx_t)); break; + case CKM_AES_CMAC_GENERAL: + case CKM_AES_CMAC: + if (session_p->encrypt.context != NULL) { + free(session_p->encrypt.context); + session_p->encrypt.context = NULL; + session_p->encrypt.flags = 0; + } + if (active_op->context != NULL) + bzero(active_op->context, sizeof (soft_aes_ctx_t)); + break; + } if (active_op->context != NULL) { diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSlotToken.c b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSlotToken.c index a18633094d..602b72486e 100644 --- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSlotToken.c +++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSlotToken.c @@ -55,6 +55,8 @@ static CK_MECHANISM_TYPE soft_mechanisms[] = { CKM_AES_CBC, CKM_AES_CBC_PAD, CKM_AES_CTR, + CKM_AES_CMAC_GENERAL, + CKM_AES_CMAC, CKM_AES_ECB, CKM_AES_KEY_GEN, CKM_BLOWFISH_CBC, @@ -160,6 +162,10 @@ static CK_MECHANISM_INFO soft_mechanism_info[] = { CKF_ENCRYPT|CKF_DECRYPT| CKF_WRAP|CKF_UNWRAP}, /* CKM_AES_CTR */ {AES_MINBYTES, AES_MAXBYTES, + CKF_SIGN|CKF_VERIFY}, /* CKM_AES_CMAC_GENERAL */ + {AES_MINBYTES, AES_MAXBYTES, + CKF_SIGN|CKF_VERIFY}, /* CKM_AES_CMAC */ + {AES_MINBYTES, AES_MAXBYTES, CKF_ENCRYPT|CKF_DECRYPT| CKF_WRAP|CKF_UNWRAP}, /* CKM_AES_ECB */ {AES_MINBYTES, AES_MAXBYTES, diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softVerifyUtil.c b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softVerifyUtil.c index dde02d2cf7..85c1e64398 100644 --- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softVerifyUtil.c +++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softVerifyUtil.c @@ -21,10 +21,9 @@ /* * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2014 Nexenta Systems, Inc. All rights reserved. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include #include #include @@ -104,6 +103,12 @@ soft_verify_init(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism, return (soft_des_sign_verify_init_common(session_p, pMechanism, key_p, B_FALSE)); + case CKM_AES_CMAC_GENERAL: + case CKM_AES_CMAC: + + return (soft_aes_sign_verify_init_common(session_p, pMechanism, + key_p, B_FALSE)); + default: return (CKR_MECHANISM_INVALID); } @@ -198,6 +203,32 @@ soft_verify(soft_session_t *session_p, CK_BYTE_PTR pData, return (rv); } + case CKM_AES_CMAC_GENERAL: + case CKM_AES_CMAC: + { + CK_ULONG len; + CK_BYTE signature[AES_BLOCK_LEN]; + soft_aes_ctx_t *aes_ctx; + + aes_ctx = (soft_aes_ctx_t *)session_p->verify.context; + len = aes_ctx->mac_len; + + /* Pass local buffer to avoid overflow. */ + rv = soft_aes_sign_verify_common(session_p, pData, + ulDataLen, signature, &len, B_FALSE, B_FALSE); + + if (rv == CKR_OK) { + if (len != ulSignatureLen) { + rv = CKR_SIGNATURE_LEN_RANGE; + } + + if (memcmp(signature, pSignature, len) != 0) { + rv = CKR_SIGNATURE_INVALID; + } + } + + return (rv); + } case CKM_RSA_X_509: case CKM_RSA_PKCS: @@ -282,6 +313,12 @@ soft_verify_update(soft_session_t *session_p, CK_BYTE_PTR pPart, return (soft_des_mac_sign_verify_update(session_p, pPart, ulPartLen)); + case CKM_AES_CMAC_GENERAL: + case CKM_AES_CMAC: + + return (soft_aes_mac_sign_verify_update(session_p, pPart, + ulPartLen)); + case CKM_MD5_RSA_PKCS: case CKM_SHA1_RSA_PKCS: case CKM_SHA256_RSA_PKCS: @@ -389,6 +426,32 @@ soft_verify_final(soft_session_t *session_p, CK_BYTE_PTR pSignature, return (rv); } + case CKM_AES_CMAC_GENERAL: + case CKM_AES_CMAC: + { + CK_ULONG len; + CK_BYTE signature[AES_BLOCK_LEN]; + soft_aes_ctx_t *aes_ctx; + + aes_ctx = (soft_aes_ctx_t *)session_p->verify.context; + len = aes_ctx->mac_len; + + /* Pass local buffer to avoid overflow. */ + rv = soft_aes_sign_verify_common(session_p, NULL, 0, + signature, &len, B_FALSE, B_TRUE); + + if (rv == CKR_OK) { + if (len != ulSignatureLen) { + rv = CKR_SIGNATURE_LEN_RANGE; + } + + if (memcmp(signature, pSignature, len) != 0) { + rv = CKR_SIGNATURE_INVALID; + } + } + + return (rv); + } case CKM_MD5_RSA_PKCS: case CKM_SHA1_RSA_PKCS: case CKM_SHA256_RSA_PKCS: diff --git a/usr/src/pkg/manifests/system-test-cryptotest.mf b/usr/src/pkg/manifests/system-test-cryptotest.mf new file mode 100644 index 0000000000..db54e93b90 --- /dev/null +++ b/usr/src/pkg/manifests/system-test-cryptotest.mf @@ -0,0 +1,52 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2012 by Delphix. All rights reserved. +# Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved. +# Copyright 2015 Nexenta Systems, Inc. All rights reserved. +# + +set name=pkg.fmri value=pkg:/system/test/cryptotest@$(PKGVERS) +set name=pkg.description value="Miscellaneous KCF/PKCS Unit Tests" +set name=pkg.summary value="KCF/PKCS Unit Test Suite" +set name=info.classification \ + value=org.opensolaris.category.2008:Development/System +set name=variant.arch value=$(ARCH) +dir path=opt/crypto-tests +dir path=opt/crypto-tests/bin +dir path=opt/crypto-tests/runfiles +dir path=opt/crypto-tests/tests +dir path=opt/crypto-tests/tests/kcf +dir path=opt/crypto-tests/tests/kcf/aes +dir path=opt/crypto-tests/tests/pkcs +dir path=opt/crypto-tests/tests/pkcs/aes +file path=opt/crypto-tests/README mode=0444 +file path=opt/crypto-tests/bin/cryptotest mode=0555 +file path=opt/crypto-tests/runfiles/default.run mode=0444 +file path=opt/crypto-tests/tests/kcf/aes/aes_cbc mode=0555 +file path=opt/crypto-tests/tests/kcf/aes/aes_ccm mode=0555 +file path=opt/crypto-tests/tests/kcf/aes/aes_cmac mode=0555 +file path=opt/crypto-tests/tests/kcf/aes/aes_ctr mode=0555 +file path=opt/crypto-tests/tests/kcf/aes/aes_ecb mode=0555 +file path=opt/crypto-tests/tests/kcf/aes/aes_gcm mode=0555 +file path=opt/crypto-tests/tests/kcf/aes/cleanup mode=0555 +file path=opt/crypto-tests/tests/kcf/aes/setup mode=0555 +file path=opt/crypto-tests/tests/pkcs/aes/aes_cbc mode=0555 +file path=opt/crypto-tests/tests/pkcs/aes/aes_ccm mode=0555 +file path=opt/crypto-tests/tests/pkcs/aes/aes_cmac mode=0555 +file path=opt/crypto-tests/tests/pkcs/aes/aes_ctr mode=0555 +file path=opt/crypto-tests/tests/pkcs/aes/aes_ecb mode=0555 +file path=opt/crypto-tests/tests/pkcs/aes/aes_gcm mode=0555 +license cr_Sun license=cr_Sun +license lic_CDDL license=lic_CDDL +depend fmri=driver/crypto/dprov type=require +depend fmri=system/test/testrunner type=require diff --git a/usr/src/test/Makefile b/usr/src/test/Makefile index 304163b79f..fdc5abc683 100644 --- a/usr/src/test/Makefile +++ b/usr/src/test/Makefile @@ -16,6 +16,6 @@ .PARALLEL: $(SUBDIRS) -SUBDIRS = libc-tests os-tests test-runner util-tests zfs-tests +SUBDIRS = libc-tests crypto-tests os-tests test-runner util-tests zfs-tests include Makefile.com diff --git a/usr/src/test/Makefile b/usr/src/test/crypto-tests/Makefile similarity index 69% copy from usr/src/test/Makefile copy to usr/src/test/crypto-tests/Makefile index 304163b79f..6669972e13 100644 --- a/usr/src/test/Makefile +++ b/usr/src/test/crypto-tests/Makefile @@ -10,12 +10,11 @@ # # -# Copyright (c) 2012 by Delphix. All rights reserved. -# Copyright 2014 Garrett D'Amore +# Copyright 2015 Nexenta Systems, Inc. All rights reserved. # .PARALLEL: $(SUBDIRS) -SUBDIRS = libc-tests os-tests test-runner util-tests zfs-tests +SUBDIRS = cmd doc runfiles tests -include Makefile.com +include $(SRC)/test/Makefile.com diff --git a/usr/src/test/Makefile b/usr/src/test/crypto-tests/cmd/Makefile similarity index 69% copy from usr/src/test/Makefile copy to usr/src/test/crypto-tests/cmd/Makefile index 304163b79f..02bea22f72 100644 --- a/usr/src/test/Makefile +++ b/usr/src/test/crypto-tests/cmd/Makefile @@ -10,12 +10,11 @@ # # -# Copyright (c) 2012 by Delphix. All rights reserved. -# Copyright 2014 Garrett D'Amore +# Copyright 2015 Nexenta Systems, Inc. All rights reserved. # .PARALLEL: $(SUBDIRS) -SUBDIRS = libc-tests os-tests test-runner util-tests zfs-tests +SUBDIRS = kcf scripts -include Makefile.com +include $(SRC)/test/Makefile.com diff --git a/usr/src/test/Makefile b/usr/src/test/crypto-tests/cmd/kcf/Makefile similarity index 53% copy from usr/src/test/Makefile copy to usr/src/test/crypto-tests/cmd/kcf/Makefile index 304163b79f..fd2d8f2746 100644 --- a/usr/src/test/Makefile +++ b/usr/src/test/crypto-tests/cmd/kcf/Makefile @@ -11,11 +11,28 @@ # # Copyright (c) 2012 by Delphix. All rights reserved. -# Copyright 2014 Garrett D'Amore +# Copyright 2015 Nexenta Systems, Inc. All rights reserved. # -.PARALLEL: $(SUBDIRS) +include $(SRC)/Makefile.master +include $(SRC)/test/Makefile.com -SUBDIRS = libc-tests os-tests test-runner util-tests zfs-tests +ROOTOPTPKG = $(ROOT)/opt/crypto-tests +ROOTBIN = $(ROOTOPTPKG)/tests/kcf/aes -include Makefile.com +PROGS = cleanup setup + +CMDS = $(PROGS:%=$(ROOTBIN)/%) +$(CMDS) := FILEMODE = 0555 + +all lint clean clobber: + +install: $(CMDS) + +$(CMDS): $(ROOTBIN) + +$(ROOTBIN): + $(INS.dir) + +$(ROOTBIN)/%: %.ksh + $(INS.rename) diff --git a/usr/src/test/Makefile b/usr/src/test/crypto-tests/cmd/kcf/cleanup.ksh similarity index 65% copy from usr/src/test/Makefile copy to usr/src/test/crypto-tests/cmd/kcf/cleanup.ksh index 304163b79f..26bed45978 100644 --- a/usr/src/test/Makefile +++ b/usr/src/test/crypto-tests/cmd/kcf/cleanup.ksh @@ -1,3 +1,5 @@ +#!/usr/bin/ksh + # # This file and its contents are supplied under the terms of the # Common Development and Distribution License ("CDDL"), version 1.0. @@ -10,12 +12,7 @@ # # -# Copyright (c) 2012 by Delphix. All rights reserved. -# Copyright 2014 Garrett D'Amore +# Copyright 2015 Nexenta Systems, Inc. All rights reserved. # -.PARALLEL: $(SUBDIRS) - -SUBDIRS = libc-tests os-tests test-runner util-tests zfs-tests - -include Makefile.com +rem_drv dprov \ No newline at end of file diff --git a/usr/src/test/Makefile b/usr/src/test/crypto-tests/cmd/kcf/setup.ksh similarity index 65% copy from usr/src/test/Makefile copy to usr/src/test/crypto-tests/cmd/kcf/setup.ksh index 304163b79f..ef8e66dae6 100644 --- a/usr/src/test/Makefile +++ b/usr/src/test/crypto-tests/cmd/kcf/setup.ksh @@ -1,3 +1,5 @@ +#!/usr/bin/ksh + # # This file and its contents are supplied under the terms of the # Common Development and Distribution License ("CDDL"), version 1.0. @@ -10,12 +12,7 @@ # # -# Copyright (c) 2012 by Delphix. All rights reserved. -# Copyright 2014 Garrett D'Amore +# Copyright 2015 Nexenta Systems, Inc. All rights reserved. # -.PARALLEL: $(SUBDIRS) - -SUBDIRS = libc-tests os-tests test-runner util-tests zfs-tests - -include Makefile.com +add_drv dprov \ No newline at end of file diff --git a/usr/src/test/Makefile b/usr/src/test/crypto-tests/cmd/scripts/Makefile similarity index 54% copy from usr/src/test/Makefile copy to usr/src/test/crypto-tests/cmd/scripts/Makefile index 304163b79f..587b5303e1 100644 --- a/usr/src/test/Makefile +++ b/usr/src/test/crypto-tests/cmd/scripts/Makefile @@ -11,11 +11,28 @@ # # Copyright (c) 2012 by Delphix. All rights reserved. -# Copyright 2014 Garrett D'Amore +# Copyright 2015 Nexenta Systems, Inc. All rights reserved. # -.PARALLEL: $(SUBDIRS) +include $(SRC)/Makefile.master +include $(SRC)/test/Makefile.com -SUBDIRS = libc-tests os-tests test-runner util-tests zfs-tests +ROOTOPTPKG = $(ROOT)/opt/crypto-tests +ROOTBIN = $(ROOTOPTPKG)/bin -include Makefile.com +PROGS = cryptotest + +CMDS = $(PROGS:%=$(ROOTBIN)/%) +$(CMDS) := FILEMODE = 0555 + +all lint clean clobber: + +install: $(CMDS) + +$(CMDS): $(ROOTBIN) + +$(ROOTBIN): + $(INS.dir) + +$(ROOTBIN)/%: %.ksh + $(INS.rename) diff --git a/usr/src/test/crypto-tests/cmd/scripts/cryptotest.ksh b/usr/src/test/crypto-tests/cmd/scripts/cryptotest.ksh new file mode 100644 index 0000000000..313cf1e0dc --- /dev/null +++ b/usr/src/test/crypto-tests/cmd/scripts/cryptotest.ksh @@ -0,0 +1,49 @@ +#!/usr/bin/ksh + +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2015 Nexenta Systems, Inc. All rights reserved. +# + +export CRYPTO_TESTS="/opt/crypto-tests" +runner="/opt/test-runner/bin/run" + +function fail +{ + echo $1 + exit ${2:-1} +} + +function find_runfile +{ + typeset distro=default + + [[ -n $distro ]] && echo $CRYPTO_TESTS/runfiles/$distro.run +} + +while getopts c: c; do + case $c in + 'c') + runfile=$OPTARG + [[ -f $runfile ]] || fail "Cannot read file: $runfile" + ;; + esac +done +shift $((OPTIND - 1)) + +[[ -z $runfile ]] && runfile=$(find_runfile) +[[ -z $runfile ]] && fail "Couldn't determine distro" + +$runner -c $runfile + +exit $? diff --git a/usr/src/test/Makefile b/usr/src/test/crypto-tests/doc/Makefile similarity index 57% copy from usr/src/test/Makefile copy to usr/src/test/crypto-tests/doc/Makefile index 304163b79f..cf4f0beb39 100644 --- a/usr/src/test/Makefile +++ b/usr/src/test/crypto-tests/doc/Makefile @@ -11,11 +11,26 @@ # # Copyright (c) 2012 by Delphix. All rights reserved. -# Copyright 2014 Garrett D'Amore +# Copyright 2015 Nexenta Systems, Inc. All rights reserved. # -.PARALLEL: $(SUBDIRS) +include $(SRC)/Makefile.master -SUBDIRS = libc-tests os-tests test-runner util-tests zfs-tests +READMES = README -include Makefile.com +ROOTOPTPKG = $(ROOT)/opt/crypto-tests + +FILES = $(READMES:%=$(ROOTOPTPKG)/%) +$(FILES) := FILEMODE = 0444 + +all: $(READMES) + +install: $(ROOTOPTPKG) $(FILES) + +clean lint clobber: + +$(ROOTOPTPKG): + $(INS.dir) + +$(ROOTOPTPKG)/%: % + $(INS.file) diff --git a/usr/src/test/crypto-tests/doc/README b/usr/src/test/crypto-tests/doc/README new file mode 100644 index 0000000000..0c848ac735 --- /dev/null +++ b/usr/src/test/crypto-tests/doc/README @@ -0,0 +1,60 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2012 by Delphix. All rights reserved. +# Copyright 2015 Nexenta Systems, Inc. All rights reserved. +# + +KCF/PKCS Unit Test Suite README + +1. Building and installing the KCF/PKCS Unit Test Suite +2. Running the KCF/PKCS Unit Test Suite +3. Test results + +-------------------------------------------------------------------------------- + +1. Building and installing the KCF/PKCS Unit Test Suite + +The KCF/PKCS Unit Test Suite runs under the testrunner framework (which can be +installed as pkg:/system/test/testrunner). To build both the KCF/PKCS Unit Test Suite +and the testrunner without running a full nightly: + + build_machine$ bldenv [-d] + build_machine$ cd $SRC/test + build_machine$ dmake install + build_machine$ cd $SRC/pkg + build_machine$ dmake install + +Then set the publisher on the test machine to point to your repository and +install the KCF/PKCS Unit Test Suite. + + test_machine# pkg install pkg:/system/test/cryptotest + +Note, the framework will be installed automatically, as the KCF/PKCS Unit Test Suite +depends on it. + +2. Running the KCF/PKCS Unit Test Suite + +The pre-requisites for running the KCF/PKCS Unit Test Suite are: + - A non-root user with the ability to sudo(1M) to root without a + password or the root user must run the test. + +Once the pre-requisites are satisfied, simply run the cryptotest script: + + test_machine$ /opt/crypto-tests/bin/cryptotest + +3. Test results + +While the KCF/PKCS Unit Test Suite is running, one informational line is printed at +the end of each test, and a results summary is printed at the end of the run. +The results summary includes the location of the complete logs, which is of the +form /var/tmp/test_results/. diff --git a/usr/src/test/Makefile b/usr/src/test/crypto-tests/runfiles/Makefile similarity index 50% copy from usr/src/test/Makefile copy to usr/src/test/crypto-tests/runfiles/Makefile index 304163b79f..2c6db60352 100644 --- a/usr/src/test/Makefile +++ b/usr/src/test/crypto-tests/runfiles/Makefile @@ -11,11 +11,30 @@ # # Copyright (c) 2012 by Delphix. All rights reserved. -# Copyright 2014 Garrett D'Amore +# Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved. +# Copyright 2015 Nexenta Systems, Inc. All rights reserved. # -.PARALLEL: $(SUBDIRS) +include $(SRC)/Makefile.master -SUBDIRS = libc-tests os-tests test-runner util-tests zfs-tests +SRCS = default.run -include Makefile.com +ROOTOPTPKG = $(ROOT)/opt/crypto-tests +RUNFILES = $(ROOTOPTPKG)/runfiles + +CMDS = $(SRCS:%=$(RUNFILES)/%) +$(CMDS) := FILEMODE = 0444 + +all: $(SRCS) + +install: $(CMDS) + +clean lint clobber: + +$(CMDS): $(RUNFILES) $(SRCS) + +$(RUNFILES): + $(INS.dir) + +$(RUNFILES)/%: % + $(INS.file) diff --git a/usr/src/test/Makefile b/usr/src/test/crypto-tests/runfiles/default.run similarity index 52% copy from usr/src/test/Makefile copy to usr/src/test/crypto-tests/runfiles/default.run index 304163b79f..ecd77fe085 100644 --- a/usr/src/test/Makefile +++ b/usr/src/test/crypto-tests/runfiles/default.run @@ -11,11 +11,22 @@ # # Copyright (c) 2012 by Delphix. All rights reserved. -# Copyright 2014 Garrett D'Amore +# Copyright 2015 Nexenta Systems, Inc. All rights reserved. # -.PARALLEL: $(SUBDIRS) +[DEFAULT] +pre = +verbose = False +quiet = False +timeout = 60 +post = +outputdir = /var/tmp/test_results -SUBDIRS = libc-tests os-tests test-runner util-tests zfs-tests +[/opt/crypto-tests/tests/pkcs/aes] +tests = ['aes_cbc', 'aes_ccm', 'aes_cmac', 'aes_ctr', 'aes_ecb', 'aes_gcm'] -include Makefile.com +[/opt/crypto-tests/tests/kcf/aes] +pre = setup +user = root +tests = ['aes_cbc', 'aes_ccm', 'aes_cmac', 'aes_ctr', 'aes_ecb', 'aes_gcm'] +post = cleanup \ No newline at end of file diff --git a/usr/src/test/Makefile b/usr/src/test/crypto-tests/tests/Makefile similarity index 65% copy from usr/src/test/Makefile copy to usr/src/test/crypto-tests/tests/Makefile index 304163b79f..abd151c0a5 100644 --- a/usr/src/test/Makefile +++ b/usr/src/test/crypto-tests/tests/Makefile @@ -10,12 +10,11 @@ # # -# Copyright (c) 2012 by Delphix. All rights reserved. -# Copyright 2014 Garrett D'Amore +# Copyright 2015 Nexenta Systems, Inc. All rights reserved. # -.PARALLEL: $(SUBDIRS) +SUBDIRS = modes common -SUBDIRS = libc-tests os-tests test-runner util-tests zfs-tests +modes: common -include Makefile.com +include $(SRC)/test/Makefile.com diff --git a/usr/src/test/Makefile b/usr/src/test/crypto-tests/tests/common/Makefile similarity index 55% copy from usr/src/test/Makefile copy to usr/src/test/crypto-tests/tests/common/Makefile index 304163b79f..3dae390d40 100644 --- a/usr/src/test/Makefile +++ b/usr/src/test/crypto-tests/tests/common/Makefile @@ -11,11 +11,23 @@ # # Copyright (c) 2012 by Delphix. All rights reserved. -# Copyright 2014 Garrett D'Amore +# Copyright 2015 Nexenta Systems, Inc. All rights reserved. # -.PARALLEL: $(SUBDIRS) +include $(SRC)/cmd/Makefile.cmd +include $(SRC)/test/Makefile.com -SUBDIRS = libc-tests os-tests test-runner util-tests zfs-tests +OBJS = testfuncs.o cryptotest_pkcs.o cryptotest_kcf.o +SRCS = $(OBJS:%.o=%.c) -include Makefile.com +CPPFLAGS += -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I$(SRC)/common/crypto/ + +all install: $(OBJS) + +%.o: %.c + $(COMPILE.c) -o $@ $< + +lint: + +clobber clean: + -$(RM) $(OBJS) diff --git a/usr/src/test/crypto-tests/tests/common/cryptotest.h b/usr/src/test/crypto-tests/tests/common/cryptotest.h new file mode 100644 index 0000000000..32b53f0730 --- /dev/null +++ b/usr/src/test/crypto-tests/tests/common/cryptotest.h @@ -0,0 +1,102 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2015 Nexenta Systems, Inc. All rights reserved. + */ + +#ifndef _CRYPTOTEST_H +#define _CRYPTOTEST_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#define CTEST_INIT_FAILED (-1) +#define CTEST_NAME_RESOLVE_FAILED (-2) +#define CTEST_MECH_NO_PROVIDER (-3) + +typedef struct cryptotest { + uint8_t *in; + uint8_t *out; + uint8_t *key; + void *param; + + size_t inlen; + size_t outlen; + size_t keylen; + size_t plen; + + char *mechname; + size_t updatelen; +} cryptotest_t; + +typedef int (*testfunc_t)(cryptotest_t *); + +typedef struct test_fg { + testfunc_t single; + testfunc_t update; +} test_fg_t; + +#define CRYPTO_INVALID_SESSION ((size_t)-1) +typedef struct crypto_op crypto_op_t; + +int run_test(cryptotest_t *args, uint8_t *cmp, size_t cmplen, test_fg_t *funcs); + +/* utils */ +crypto_op_t *cryptotest_init(cryptotest_t *args, crypto_func_group_t fg); +int cryptotest_close(crypto_op_t *op); +int get_mech_info(crypto_op_t *op); +int get_hsession_by_mech(crypto_op_t *op); + +/* CRYPTO_MAC */ +int mac_init(crypto_op_t *op); +int mac_single(crypto_op_t *op); +int mac_update(crypto_op_t *op, int offset); +int mac_final(crypto_op_t *op); + +/* CRYPTO_ENCRYPT */ +int encrypt_init(crypto_op_t *op); +int encrypt_single(crypto_op_t *op); +int encrypt_update(crypto_op_t *op, int offset, size_t *encrlen); +int encrypt_final(crypto_op_t *op, size_t encrlen); + +/* CRYPTO_DECRYPT */ +int decrypt_init(crypto_op_t *op); +int decrypt_single(crypto_op_t *op); +int decrypt_update(crypto_op_t *op, int offset, size_t *encrlen); +int decrypt_final(crypto_op_t *op, size_t encrlen); + +/* wrappers */ +int test_mac_single(cryptotest_t *args); +int test_mac(cryptotest_t *args); + +int test_encrypt_single(cryptotest_t *args); +int test_encrypt(cryptotest_t *args); + +int test_decrypt_single(cryptotest_t *args); +int test_decrypt(cryptotest_t *args); + +extern test_fg_t cryptotest_decr_fg; +extern test_fg_t cryptotest_encr_fg; +extern test_fg_t cryptotest_mac_fg; + +#define MAC_FG (&cryptotest_mac_fg) +#define ENCR_FG (&cryptotest_encr_fg) +#define DECR_FG (&cryptotest_decr_fg) + +#ifdef __cplusplus +} +#endif + +#endif /* _CRYPTOTEST_H */ diff --git a/usr/src/test/crypto-tests/tests/common/cryptotest_kcf.c b/usr/src/test/crypto-tests/tests/common/cryptotest_kcf.c new file mode 100644 index 0000000000..260821dcac --- /dev/null +++ b/usr/src/test/crypto-tests/tests/common/cryptotest_kcf.c @@ -0,0 +1,378 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2015 Nexenta Systems, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include + +#include "cryptotest.h" + +struct crypto_op { + char *in; + char *out; + char *key; + char *param; + + size_t inlen; + size_t outlen; + size_t keylen; + size_t paramlen; + size_t updatelen; + + char *mechname; + + /* internal */ + crypto_mech_type_t mech; + crypto_session_id_t hsession; + crypto_func_group_t fg; +}; + +static int fd; +static const char CRYPTO_DEVICE[] = "/dev/crypto"; + +int +kcf_do_ioctl(int opcode, uint_t *arg, char *opstr) +{ + int ret; + + while ((ret = ioctl(fd, opcode, arg)) < 0) { + if (errno != EINTR) + break; + } + + if (ret < 0 || *arg != CRYPTO_SUCCESS) + (void) fprintf(stderr, "%s: Error = %d %d 0x%02x\n", + (opstr == NULL) ? "ioctl" : opstr, + ret, errno, *arg); + + if (ret < 0) + return (errno); + + return (*arg); +} + +crypto_op_t * +cryptotest_init(cryptotest_t *arg, crypto_func_group_t fg) +{ + crypto_op_t *op = malloc(sizeof (*op)); + + if (op == NULL) + return (NULL); + + while ((fd = open(CRYPTO_DEVICE, O_RDWR)) < 0) { + if (errno != EINTR) + return (NULL); + } + + op->in = (char *)arg->in; + op->out = (char *)arg->out; + op->key = (char *)arg->key; + op->param = (char *)arg->param; + + op->inlen = arg->inlen; + op->outlen = arg->outlen; + op->keylen = arg->keylen * 8; /* kcf uses keylen in bits */ + op->paramlen = arg->plen; + op->updatelen = arg->updatelen; + + op->mechname = arg->mechname; + + op->hsession = CRYPTO_INVALID_SESSION; + op->fg = fg; + + if (op->out == NULL) + op->outlen = op->inlen; + return (op); +} + +int +cryptotest_close_session(crypto_session_id_t session) +{ + crypto_close_session_t cs; + + cs.cs_session = session; + return (kcf_do_ioctl(CRYPTO_CLOSE_SESSION, (uint_t *)&cs, "session")); +} + +int +cryptotest_close(crypto_op_t *op) +{ + if (op->hsession != CRYPTO_INVALID_SESSION) + (void) cryptotest_close_session(op->hsession); + free(op); + if (fd >= 0) + return (close(fd)); + return (0); +} + +int +get_mech_info(crypto_op_t *op) +{ + crypto_get_mechanism_number_t get_number; + + bzero(&get_number, sizeof (get_number)); + + get_number.pn_mechanism_string = op->mechname; + get_number.pn_mechanism_len = strlen(op->mechname) + 1; + + if (kcf_do_ioctl(CRYPTO_GET_MECHANISM_NUMBER, + (uint_t *)&get_number, "get_mech_info") != CRYPTO_SUCCESS) { + (void) fprintf(stderr, "failed to resolve mechanism name %s\n", + op->mechname); + (void) cryptotest_close(op); + return (CTEST_NAME_RESOLVE_FAILED); + } + op->mech = get_number.pn_internal_number; + return (CRYPTO_SUCCESS); +} + +int +get_hsession_by_mech(crypto_op_t *op) +{ + crypto_by_mech_t mech; + int rv; + + mech.mech_keylen = op->keylen; + mech.mech_type = op->mech; + mech.mech_fg = op->fg; + + rv = kcf_do_ioctl(CRYPTO_GET_PROVIDER_BY_MECH, (uint_t *)&mech, + "get_hsession_by_mech"); + + if (rv != 0 || mech.rv != CRYPTO_SUCCESS) { + (void) fprintf(stderr, + "could not find provider for mechanism %llu\n", + mech.mech_type); + (void) cryptotest_close(op); + return (CTEST_MECH_NO_PROVIDER); + } + + op->hsession = mech.session_id; + + return (CRYPTO_SUCCESS); +} + +/* + * CRYPTO_MAC_* functions + */ +int +mac_init(crypto_op_t *op) +{ + crypto_mac_init_t init; + + bzero((void *)&init, sizeof (init)); + + init.mi_session = op->hsession; + + init.mi_key.ck_data = op->key; + init.mi_key.ck_format = CRYPTO_KEY_RAW; /* must be this */ + init.mi_key.ck_length = op->keylen; + + init.mi_mech.cm_type = op->mech; + init.mi_mech.cm_param = NULL; + init.mi_mech.cm_param_len = 0; + + return (kcf_do_ioctl(CRYPTO_MAC_INIT, (uint_t *)&init, "init")); +} + +int +mac_single(crypto_op_t *op) +{ + crypto_mac_t mac; + + bzero(&mac, sizeof (mac)); + mac.cm_session = op->hsession; + mac.cm_datalen = op->inlen; + mac.cm_databuf = op->in; + mac.cm_maclen = op->outlen; + mac.cm_macbuf = op->out; + + return (kcf_do_ioctl(CRYPTO_MAC, (uint_t *)&mac, "single")); +} + +int +mac_update(crypto_op_t *op, int offset) +{ + crypto_mac_update_t update; + + bzero((void *)&update, sizeof (update)); + + update.mu_session = op->hsession; + update.mu_databuf = op->in + offset; + update.mu_datalen = op->updatelen; + + return (kcf_do_ioctl(CRYPTO_MAC_UPDATE, (uint_t *)&update, "update")); +} + +int +mac_final(crypto_op_t *op) +{ + crypto_mac_final_t final; + + bzero((void *)&final, sizeof (final)); + + final.mf_session = op->hsession; + final.mf_maclen = op->outlen; + final.mf_macbuf = op->out; + + return (kcf_do_ioctl(CRYPTO_MAC_FINAL, (uint_t *)&final, "final")); +} + + +/* + * CRYPTO_ENCRYPT_* functions + */ + +int +encrypt_init(crypto_op_t *op) +{ + crypto_encrypt_init_t init; + + bzero((void *)&init, sizeof (init)); + + init.ei_session = op->hsession; + + init.ei_key.ck_data = op->key; + init.ei_key.ck_format = CRYPTO_KEY_RAW; /* must be this */ + init.ei_key.ck_length = op->keylen; + + init.ei_mech.cm_type = op->mech; + init.ei_mech.cm_param = op->param; + init.ei_mech.cm_param_len = op->paramlen; + + return (kcf_do_ioctl(CRYPTO_ENCRYPT_INIT, (uint_t *)&init, "init")); +} + +int +encrypt_single(crypto_op_t *op) +{ + crypto_encrypt_t encrypt; + + bzero(&encrypt, sizeof (encrypt)); + encrypt.ce_session = op->hsession; + encrypt.ce_datalen = op->inlen; + encrypt.ce_databuf = op->in; + encrypt.ce_encrlen = op->outlen; + encrypt.ce_encrbuf = op->out; + + return (kcf_do_ioctl(CRYPTO_ENCRYPT, (uint_t *)&encrypt, "single")); +} + +int +encrypt_update(crypto_op_t *op, int offset, size_t *encrlen) +{ + crypto_encrypt_update_t update; + int ret; + bzero((void *)&update, sizeof (update)); + + update.eu_session = op->hsession; + update.eu_databuf = op->in + offset; + update.eu_datalen = op->updatelen; + update.eu_encrlen = op->outlen - *encrlen; + update.eu_encrbuf = op->out + *encrlen; + + ret = kcf_do_ioctl(CRYPTO_ENCRYPT_UPDATE, (uint_t *)&update, "update"); + *encrlen += update.eu_encrlen; + return (ret); +} + +int +encrypt_final(crypto_op_t *op, size_t encrlen) +{ + crypto_encrypt_final_t final; + + bzero((void *)&final, sizeof (final)); + + final.ef_session = op->hsession; + final.ef_encrlen = op->outlen - encrlen; + final.ef_encrbuf = op->out + encrlen; + + return (kcf_do_ioctl(CRYPTO_ENCRYPT_FINAL, (uint_t *)&final, "final")); +} + +/* + * CRYPTO_DECRYPT_* functions + */ + +int +decrypt_init(crypto_op_t *op) +{ + crypto_decrypt_init_t init; + + bzero((void *)&init, sizeof (init)); + + init.di_session = op->hsession; + + init.di_key.ck_data = op->key; + init.di_key.ck_format = CRYPTO_KEY_RAW; /* must be this */ + init.di_key.ck_length = op->keylen; + + init.di_mech.cm_type = op->mech; + init.di_mech.cm_param = op->param; + init.di_mech.cm_param_len = op->paramlen; + + return (kcf_do_ioctl(CRYPTO_DECRYPT_INIT, (uint_t *)&init, "init")); +} + +int +decrypt_single(crypto_op_t *op) +{ + crypto_decrypt_t decrypt; + + bzero(&decrypt, sizeof (decrypt)); + decrypt.cd_session = op->hsession; + decrypt.cd_datalen = op->outlen; + decrypt.cd_databuf = op->out; + decrypt.cd_encrlen = op->inlen; + decrypt.cd_encrbuf = op->in; + + return (kcf_do_ioctl(CRYPTO_DECRYPT, (uint_t *)&decrypt, "single")); +} + +int +decrypt_update(crypto_op_t *op, int offset, size_t *encrlen) +{ + crypto_decrypt_update_t update; + int ret; + + bzero((void *)&update, sizeof (update)); + + update.du_session = op->hsession; + update.du_databuf = op->out + *encrlen; + update.du_datalen = op->outlen - *encrlen; + update.du_encrlen = op->updatelen; + update.du_encrbuf = op->in + offset; + + ret = kcf_do_ioctl(CRYPTO_DECRYPT_UPDATE, (uint_t *)&update, "update"); + *encrlen += update.du_datalen; + return (ret); +} + +int +decrypt_final(crypto_op_t *op, size_t encrlen) +{ + crypto_decrypt_final_t final; + + bzero((void *)&final, sizeof (final)); + + final.df_session = op->hsession; + final.df_datalen = op->outlen - encrlen; + final.df_databuf = op->out + encrlen; + + return (kcf_do_ioctl(CRYPTO_DECRYPT_FINAL, (uint_t *)&final, "final")); +} diff --git a/usr/src/test/crypto-tests/tests/common/cryptotest_pkcs.c b/usr/src/test/crypto-tests/tests/common/cryptotest_pkcs.c new file mode 100644 index 0000000000..4a98a2aafc --- /dev/null +++ b/usr/src/test/crypto-tests/tests/common/cryptotest_pkcs.c @@ -0,0 +1,401 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2015 Nexenta Systems, Inc. All rights reserved. + */ + +#include +#include + +#include "cryptotest.h" + +struct crypto_op { + CK_BYTE_PTR in; + CK_BYTE_PTR out; + CK_BYTE_PTR key; + CK_BYTE_PTR param; + + size_t inlen; + size_t outlen; + size_t keylen; + size_t paramlen; + size_t updatelen; + + char *mechname; + + /* internal */ + CK_MECHANISM_TYPE mech; + CK_OBJECT_HANDLE keyt; + CK_SESSION_HANDLE hsession; + size_t fg; +}; + +static void +cryptotest_error(char *name, CK_RV rv) +{ + (void) fprintf(stderr, "%s: Error = 0x%.8lX '%s'\n", + name, rv, pkcs11_strerror(rv)); +} + +crypto_op_t * +cryptotest_init(cryptotest_t *arg, size_t fg) +{ + crypto_op_t *op = malloc(sizeof (*op)); + + op->in = (CK_BYTE_PTR)arg->in; + op->out = (CK_BYTE_PTR)arg->out; + op->key = (CK_BYTE_PTR)arg->key; + op->param = (CK_BYTE_PTR)arg->param; + + op->inlen = arg->inlen; + op->outlen = arg->outlen; + op->keylen = arg->keylen; + op->paramlen = arg->plen; + op->updatelen = arg->updatelen; + + op->mechname = arg->mechname; + + op->hsession = CRYPTO_INVALID_SESSION; + op->fg = fg; + + if (op->out == NULL) + op->outlen = op->inlen; + return (op); +} + +int +cryptotest_close_session(CK_SESSION_HANDLE hsession) +{ + CK_RV rv; + rv = C_CloseSession(hsession); + if (rv != CKR_OK) + cryptotest_error("cryptotest_close_session", rv); + + return (rv); +} + +int +cryptotest_close(crypto_op_t *op) +{ + (void) C_DestroyObject(op->hsession, op->keyt); + if (op->hsession != CRYPTO_INVALID_SESSION) + (void) cryptotest_close_session(op->hsession); + free(op); + return (C_Finalize(NULL)); +} + +int +get_mech_info(crypto_op_t *op) +{ + CK_RV rv; + rv = pkcs11_str2mech(op->mechname, &op->mech); + if (rv != CKR_OK) { + cryptotest_error("get_mech_info", rv); + (void) fprintf(stderr, "failed to resolve mechanism name %s\n", + op->mechname); + (void) cryptotest_close(op); + return (CTEST_NAME_RESOLVE_FAILED); + } + return (rv); +} + + +int +get_hsession_by_mech(crypto_op_t *op) +{ + CK_RV rv; + rv = SUNW_C_GetMechSession(op->mech, &op->hsession); + if (rv != CKR_OK) { + cryptotest_error("get_hsession_by_mech", rv); + (void) fprintf(stderr, + "could not find provider for mechanism %lu\n", + op->mech); + (void) cryptotest_close(op); + return (CTEST_MECH_NO_PROVIDER); + } + return (rv); +} + +/* + * SIGN_* functions + */ +int +sign_init(crypto_op_t *op) +{ + CK_MECHANISM mech; + CK_RV rv; + + mech.mechanism = op->mech; + mech.pParameter = NULL; + mech.ulParameterLen = 0; + + rv = SUNW_C_KeyToObject(op->hsession, op->mech, + op->key, op->keylen, &op->keyt); + + if (rv != CKR_OK) + cryptotest_error("SUNW_C_KeyToObject", rv); + + rv = C_SignInit(op->hsession, &mech, op->keyt); + + if (rv != CKR_OK) + cryptotest_error("C_SignInit", rv); + + return (rv); +} + +int +sign_single(crypto_op_t *op) +{ + CK_RV rv; + + rv = C_Sign(op->hsession, op->in, op->inlen, + op->out, (CK_ULONG_PTR)&op->outlen); + if (rv != CKR_OK) + cryptotest_error("C_Sign", rv); + return (rv); +} + +int +sign_update(crypto_op_t *op, int offset) +{ + CK_RV rv; + rv = C_SignUpdate(op->hsession, op->in + offset, op->updatelen); + if (rv != CKR_OK) + cryptotest_error("C_SignUpdate", rv); + + return (rv); +} + +int +sign_final(crypto_op_t *op) +{ + CK_RV rv; + rv = C_SignFinal(op->hsession, op->out, (CK_ULONG_PTR)&op->outlen); + if (rv != CKR_OK) + cryptotest_error("C_SignFinal", rv); + return (rv); +} + +/* + * MAC_* functions + */ +int +mac_init(crypto_op_t *op) +{ + return (sign_init(op)); +} + +int +mac_single(crypto_op_t *op) +{ + return (sign_single(op)); +} + +int +mac_update(crypto_op_t *op, int offset) +{ + return (sign_update(op, offset)); +} + +int +mac_final(crypto_op_t *op) +{ + return (sign_final(op)); +} + +/* + * VERIFY_* functions + */ +int +verify_init(crypto_op_t *op) +{ + CK_MECHANISM mech; + CK_RV rv; + + mech.mechanism = op->mech; + mech.pParameter = NULL; + mech.ulParameterLen = 0; + + rv = SUNW_C_KeyToObject(op->hsession, op->mech, + op->key, op->keylen, &op->keyt); + + if (rv != CKR_OK) + cryptotest_error("SUNW_C_KeyToObject", rv); + + rv = C_VerifyInit(op->hsession, &mech, op->keyt); + + if (rv != CKR_OK) + cryptotest_error("C_VerifyInit", rv); + + return (rv); +} + +int +verify_single(crypto_op_t *op) +{ + CK_RV rv; + + rv = C_Verify(op->hsession, op->in, op->inlen, op->out, op->outlen); + if (rv != CKR_OK && rv != CKR_SIGNATURE_INVALID && + rv != CKR_SIGNATURE_LEN_RANGE) + cryptotest_error("C_Verify", rv); + return (rv); +} + +int +verify_update(crypto_op_t *op, int offset) +{ + CK_RV rv; + rv = C_VerifyUpdate(op->hsession, op->in + offset, op->updatelen); + if (rv != CKR_OK) + cryptotest_error("C_VerifyUpdate", rv); + return (rv); +} + +int +verify_final(crypto_op_t *op) +{ + CK_RV rv; + rv = C_VerifyFinal(op->hsession, op->out, op->outlen); + if (rv != CKR_OK && rv != CKR_SIGNATURE_INVALID && + rv != CKR_SIGNATURE_LEN_RANGE) + cryptotest_error("C_VerifyFinal", rv); + return (rv); +} + +/* + * ENCRYPT_* functions + */ +int +encrypt_init(crypto_op_t *op) +{ + CK_MECHANISM mech; + CK_RV rv; + + mech.mechanism = op->mech; + mech.pParameter = op->param; + mech.ulParameterLen = op->paramlen; + + rv = SUNW_C_KeyToObject(op->hsession, op->mech, + op->key, op->keylen, &op->keyt); + + if (rv != CKR_OK) + cryptotest_error("SUNW_C_KeyToObject", rv); + + rv = C_EncryptInit(op->hsession, &mech, op->keyt); + + if (rv != CKR_OK) + cryptotest_error("C_EncryptInit", rv); + + return (rv); +} + +int +encrypt_single(crypto_op_t *op) +{ + CK_RV rv; + + rv = C_Encrypt(op->hsession, op->in, op->inlen, + op->out, (CK_ULONG_PTR)&op->outlen); + if (rv != CKR_OK) + cryptotest_error("C_Encrypt", rv); + return (rv); +} + +int +encrypt_update(crypto_op_t *op, int offset, size_t *encrlen) +{ + CK_RV rv; + CK_ULONG outlen = op->outlen - *encrlen; + rv = C_EncryptUpdate(op->hsession, op->in + offset, op->updatelen, + op->out + *encrlen, &outlen); + if (rv != CKR_OK) + cryptotest_error("C_EncryptUpdate", rv); + + *encrlen += outlen; + return (rv); +} + +int +encrypt_final(crypto_op_t *op, size_t encrlen) +{ + CK_RV rv; + CK_ULONG outlen = op->outlen - encrlen; + rv = C_EncryptFinal(op->hsession, op->out + encrlen, &outlen); + if (rv != CKR_OK) + cryptotest_error("C_EncryptFinal", rv); + return (rv); +} + +/* + * DECRYPT_* functions + */ +int +decrypt_init(crypto_op_t *op) +{ + CK_MECHANISM mech; + CK_RV rv; + + mech.mechanism = op->mech; + mech.pParameter = op->param; + mech.ulParameterLen = op->paramlen; + + rv = SUNW_C_KeyToObject(op->hsession, op->mech, + op->key, op->keylen, &op->keyt); + + if (rv != CKR_OK) + cryptotest_error("SUNW_C_KeyToObject", rv); + + rv = C_DecryptInit(op->hsession, &mech, op->keyt); + + if (rv != CKR_OK) + cryptotest_error("C_DecryptInit", rv); + + return (rv); +} + +int +decrypt_single(crypto_op_t *op) +{ + CK_RV rv; + + rv = C_Decrypt(op->hsession, op->in, op->inlen, + op->out, (CK_ULONG_PTR)&op->outlen); + if (rv != CKR_OK) + cryptotest_error("C_Decrypt", rv); + return (rv); +} + +int +decrypt_update(crypto_op_t *op, int offset, size_t *encrlen) +{ + CK_RV rv; + CK_ULONG outlen = op->outlen - *encrlen; + rv = C_DecryptUpdate(op->hsession, op->in + offset, op->updatelen, + op->out + *encrlen, &outlen); + if (rv != CKR_OK) + cryptotest_error("C_DecryptUpdate", rv); + + *encrlen += outlen; + return (rv); +} + +int +decrypt_final(crypto_op_t *op, size_t encrlen) +{ + CK_RV rv; + CK_ULONG outlen = op->outlen - encrlen; + rv = C_DecryptFinal(op->hsession, op->out + encrlen, &outlen); + if (rv != CKR_OK) + cryptotest_error("C_DecryptFinal", rv); + return (rv); +} diff --git a/usr/src/test/crypto-tests/tests/common/testfuncs.c b/usr/src/test/crypto-tests/tests/common/testfuncs.c new file mode 100644 index 0000000000..f4aacce111 --- /dev/null +++ b/usr/src/test/crypto-tests/tests/common/testfuncs.c @@ -0,0 +1,268 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2016 Nexenta Systems, Inc. All rights reserved. + */ + +#define __EXTENSIONS__ +#include +#include +#include +#include "cryptotest.h" + + + +test_fg_t cryptotest_decr_fg = {test_decrypt_single, test_decrypt}; +test_fg_t cryptotest_encr_fg = {test_encrypt_single, test_encrypt}; +test_fg_t cryptotest_mac_fg = {test_mac_single, test_mac}; + +/* + * Utils + */ + +void +printbuf(uint8_t *buf, char *name, size_t size) +{ + size_t i; + + flockfile(stderr); + (void) fprintf(stderr, "%s%s", name, (size > 0) ? " " : ""); + for (i = 0; i < size; i++) + (void) fprintf(stderr, "%02x", buf[i]); + (void) fputc('\n', stderr); + funlockfile(stderr); +} + +int +bufcmp(uint8_t *auth, uint8_t *cmp, size_t size) +{ + if (memcmp(cmp, auth, size) != 0) { + (void) fprintf(stderr, "mismatched result\n\n"); + printbuf(cmp, "calc", size); + printbuf(auth, "orig", size); + return (1); + } else { + (void) fprintf(stderr, "result matches\n\n"); + return (0); + } +} + +/* + * Wrapper functions + */ + +int +run_test(cryptotest_t *args, uint8_t *cmp, size_t cmplen, + test_fg_t *funcs) +{ + int ret, errs = 0; + static int i = 0; + + (void) fprintf(stderr, "%s: run %d\n", args->mechname, ++i); + bzero(args->out, args->outlen); + ret = funcs->update(args); + if (ret > 0) { + (void) fprintf(stderr, "failure %x\n", ret); + errs += 1; + } else if (ret < 0) { + (void) fprintf(stderr, "fatal error %d\n", ret); + exit(1); + } else + errs += bufcmp(cmp, args->out, cmplen); + + bzero(args->out, args->outlen); + ret = funcs->single(args); + if (ret > 0) { + (void) fprintf(stderr, "failure %x\n", ret); + errs += 1; + } else if (ret < 0) { + (void) fprintf(stderr, "fatal error %d\n", ret); + exit(2); + } else + errs += bufcmp(cmp, args->out, cmplen); + + return (errs); +} + +static int +test_mac_common(cryptotest_t *args, boolean_t AIO) +{ + int ret, i; + crypto_op_t *crypto_op; + + if (args->in == NULL || args->key == NULL) + return (CRYPTO_FAILED); + + if ((crypto_op = cryptotest_init(args, CRYPTO_FG_MAC)) == NULL) { + (void) fprintf(stderr, "Error occured during initialization\n"); + (void) cryptotest_close(NULL); + return (CTEST_INIT_FAILED); + } + + if ((ret = get_mech_info(crypto_op)) != CRYPTO_SUCCESS) + goto out; + + if ((ret = get_hsession_by_mech(crypto_op)) != CRYPTO_SUCCESS) + goto out; + + if ((ret = mac_init(crypto_op)) != CRYPTO_SUCCESS) + goto out; + + if (AIO) { + if ((ret = mac_single(crypto_op)) != CRYPTO_SUCCESS) + goto out; + } else { + for (i = 0; i < args->inlen; i += args->updatelen) { + + if ((ret = mac_update(crypto_op, i)) != CRYPTO_SUCCESS) + goto out; + } + + if ((ret = mac_final(crypto_op)) != CRYPTO_SUCCESS) + goto out; + + } + +out: + (void) cryptotest_close(crypto_op); + return (ret); +} + +int +test_mac_single(cryptotest_t *args) +{ + return (test_mac_common(args, B_TRUE)); +} + +int +test_mac(cryptotest_t *args) +{ + return (test_mac_common(args, B_FALSE)); +} + +static int +test_encrypt_common(cryptotest_t *args, boolean_t AIO) +{ + int ret, i; + size_t encrlen = 0; + crypto_op_t *crypto_op; + + if (args->key == NULL) + return (CRYPTO_FAILED); + + if ((crypto_op = cryptotest_init(args, CRYPTO_FG_ENCRYPT)) == NULL) { + (void) fprintf(stderr, "Error occured during initialization\n"); + (void) cryptotest_close(NULL); + return (CTEST_INIT_FAILED); + } + + if ((ret = get_mech_info(crypto_op)) != CRYPTO_SUCCESS) + goto out; + + if ((ret = get_hsession_by_mech(crypto_op)) != CRYPTO_SUCCESS) + goto out; + + if ((ret = encrypt_init(crypto_op)) != CRYPTO_SUCCESS) + goto out; + + if (AIO) { + if ((ret = encrypt_single(crypto_op)) != CRYPTO_SUCCESS) + goto out; + } else { + for (i = 0; i < args->inlen; i += args->updatelen) { + + if ((ret = encrypt_update(crypto_op, i, + &encrlen)) != CRYPTO_SUCCESS) + goto out; + } + + if ((ret = encrypt_final(crypto_op, encrlen)) != CRYPTO_SUCCESS) + goto out; + + } + +out: + (void) cryptotest_close(crypto_op); + return (ret); +} + +int +test_encrypt_single(cryptotest_t *args) +{ + return (test_encrypt_common(args, B_TRUE)); +} + + +int +test_encrypt(cryptotest_t *args) +{ + return (test_encrypt_common(args, B_FALSE)); +} + +static int +test_decrypt_common(cryptotest_t *args, boolean_t AIO) +{ + int ret, i; + size_t encrlen = 0; + crypto_op_t *crypto_op; + + if (args->key == NULL) + return (CRYPTO_FAILED); + + if ((crypto_op = cryptotest_init(args, CRYPTO_FG_DECRYPT)) == NULL) { + (void) fprintf(stderr, "Error occured during initialization\n"); + (void) cryptotest_close(NULL); + return (CTEST_INIT_FAILED); + } + + if ((ret = get_mech_info(crypto_op)) != CRYPTO_SUCCESS) + goto out; + + if ((ret = get_hsession_by_mech(crypto_op)) != CRYPTO_SUCCESS) + goto out; + + if ((ret = decrypt_init(crypto_op)) != CRYPTO_SUCCESS) + goto out; + + if (AIO) { + if ((ret = decrypt_single(crypto_op)) != CRYPTO_SUCCESS) + goto out; + } else { + for (i = 0; i < args->inlen; i += args->updatelen) { + + if ((ret = decrypt_update(crypto_op, i, + &encrlen)) != CRYPTO_SUCCESS) + goto out; + } + + if ((ret = decrypt_final(crypto_op, encrlen)) != CRYPTO_SUCCESS) + goto out; + + } + +out: + (void) cryptotest_close(crypto_op); + return (ret); +} + +int +test_decrypt_single(cryptotest_t *args) +{ + return (test_decrypt_common(args, B_TRUE)); +} + + +int +test_decrypt(cryptotest_t *args) +{ + return (test_decrypt_common(args, B_FALSE)); +} diff --git a/usr/src/test/Makefile b/usr/src/test/crypto-tests/tests/modes/Makefile similarity index 77% copy from usr/src/test/Makefile copy to usr/src/test/crypto-tests/tests/modes/Makefile index 304163b79f..c8dc4e360b 100644 --- a/usr/src/test/Makefile +++ b/usr/src/test/crypto-tests/tests/modes/Makefile @@ -11,11 +11,11 @@ # # Copyright (c) 2012 by Delphix. All rights reserved. -# Copyright 2014 Garrett D'Amore +# Copyright 2015 Nexenta Systems, Inc. All rights reserved. # .PARALLEL: $(SUBDIRS) -SUBDIRS = libc-tests os-tests test-runner util-tests zfs-tests +SUBDIRS = aes -include Makefile.com +include $(SRC)/test/Makefile.com diff --git a/usr/src/test/Makefile b/usr/src/test/crypto-tests/tests/modes/aes/Makefile similarity index 77% copy from usr/src/test/Makefile copy to usr/src/test/crypto-tests/tests/modes/aes/Makefile index 304163b79f..a58f77eb94 100644 --- a/usr/src/test/Makefile +++ b/usr/src/test/crypto-tests/tests/modes/aes/Makefile @@ -11,11 +11,11 @@ # # Copyright (c) 2012 by Delphix. All rights reserved. -# Copyright 2014 Garrett D'Amore +# Copyright 2015 Nexenta Systems, Inc. All rights reserved. # .PARALLEL: $(SUBDIRS) -SUBDIRS = libc-tests os-tests test-runner util-tests zfs-tests +SUBDIRS = cbc ccm cmac ctr ecb gcm -include Makefile.com +include $(SRC)/test/Makefile.com diff --git a/usr/src/test/crypto-tests/tests/modes/aes/Makefile.subdirs b/usr/src/test/crypto-tests/tests/modes/aes/Makefile.subdirs new file mode 100644 index 0000000000..d0dc303420 --- /dev/null +++ b/usr/src/test/crypto-tests/tests/modes/aes/Makefile.subdirs @@ -0,0 +1,82 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2012 by Delphix. All rights reserved. +# Copyright 2015 Nexenta Systems, Inc. All rights reserved. +# + +include $(SRC)/test/Makefile.com + +CRYPTO = pkcs kcf +PROGS = $(CRYPTO:%=$(PROG)_%) +ROOTOPTPKG = $(ROOT)/opt/crypto-tests +TESTROOT = $(ROOTOPTPKG)/tests/#$(SUFFIX)/aes +TESTDIR = $(CRYPTO:%=$(TESTROOT)/%/aes) + +COMMONDIR = ../../../common +OBJS_COMMON = testfuncs.o +OBJS_COMDIR = $(OBJS_COMMON:%=$(COMMONDIR)/%) +OBJS_LOCAL = $(PROG:%=%.o) +OBJS = $(OBJS_LOCAL) $(OBJS_COMDIR) +OBJS_PKCS = $(OBJS_LOCAL) $(OBJS_COMDIR) $(COMMONDIR)/cryptotest_pkcs.o +OBJS_KCF = $(OBJS_LOCAL) $(OBJS_COMDIR) $(COMMONDIR)/cryptotest_kcf.o +SRCS = $(OBJS:%.o=%.c) +PKCSLIBS = -lpkcs11 -lcryptoutil + +C99MODE = -xc99=%all + +CMDS = $(TESTDIR:%=%/$(PROG)) +$(CMDS) := FILEMODE = 0555 + +LINTFLAGS += -xerroff=E_NAME_USED_NOT_DEF2 +LINTFLAGS += -xerroff=E_NAME_DEF_NOT_USED2 + +CPPFLAGS += -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I$(COMMONDIR) -I$(SRC)/common/crypto/ + +all: $(PROGS) + +$(PROG)_kcf: $(OBJS_KCF) + $(LINK.c) $(OBJS_KCF) -o $@ $(LDLIBS) + $(POST_PROCESS) + +$(PROG)_pkcs: $(OBJS_PKCS) + $(LINK.c) $(OBJS_PKCS) -o $@ $(LDLIBS) $(PKCSLIBS) + $(POST_PROCESS) + + +$(COMMONDIR)/%.o: + +%.o: %.c + $(COMPILE.c) -o $@ $< + +install: all $(CMDS) + +lint: $(CRYPTO:%=lint_%) + +lint_pkcs: + $(LINT.c) $(OBJS_PKCS:%.o=%.c) $(LDLIBS) $(PKCSLIBS) + +lint_kcf: + $(LINT.c) $(OBJS_KCF:%.o=%.c) $(LDLIBS) +clobber: clean + -$(RM) $(PROGS) + +clean: + -$(RM) $(OBJS_LOCAL) + +$(CMDS): $(TESTDIR) $(PROGS) + +$(TESTDIR): + $(INS.dir) + +$(TESTROOT)/%/aes/$(PROG): $(PROG)_% + $(INS.rename) diff --git a/usr/src/test/Makefile b/usr/src/test/crypto-tests/tests/modes/aes/cbc/Makefile similarity index 74% copy from usr/src/test/Makefile copy to usr/src/test/crypto-tests/tests/modes/aes/cbc/Makefile index 304163b79f..e74dc104bd 100644 --- a/usr/src/test/Makefile +++ b/usr/src/test/crypto-tests/tests/modes/aes/cbc/Makefile @@ -11,11 +11,10 @@ # # Copyright (c) 2012 by Delphix. All rights reserved. -# Copyright 2014 Garrett D'Amore +# Copyright 2015 Nexenta Systems, Inc. All rights reserved. # -.PARALLEL: $(SUBDIRS) +PROG = aes_cbc -SUBDIRS = libc-tests os-tests test-runner util-tests zfs-tests - -include Makefile.com +include $(SRC)/cmd/Makefile.cmd +include ../Makefile.subdirs diff --git a/usr/src/test/crypto-tests/tests/modes/aes/cbc/aes_cbc.c b/usr/src/test/crypto-tests/tests/modes/aes/cbc/aes_cbc.c new file mode 100644 index 0000000000..446f3f27ab --- /dev/null +++ b/usr/src/test/crypto-tests/tests/modes/aes/cbc/aes_cbc.c @@ -0,0 +1,69 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2016 Nexenta Systems, Inc. All rights reserved. + */ + +#include +#include + +#include "cryptotest.h" +#include "aes_cbc.h" + +int +main(void) +{ + int errs = 0; + int i; + uint8_t N[1024]; + cryptotest_t args; + + args.out = N; + + args.outlen = sizeof (N); + args.plen = AES_BLOCK_LEN; + + args.mechname = SUN_CKM_AES_CBC; + args.updatelen = 1; + + + for (i = 0; i < sizeof (RES) / sizeof (RES[0]); i++) { + args.in = DATA[i]; + args.key = KEY[i]; + args.param = IV[i]; + + args.inlen = DATALEN[i]; + args.keylen = KEYLEN[i]; + + errs += run_test(&args, RES[i], RESLEN[i], ENCR_FG); + (void) fprintf(stderr, "----------\n"); + } + + (void) fprintf(stderr, "\t\t\t=== decrypt ===\n----------\n\n"); + + for (i = 0; i < sizeof (RES) / sizeof (RES[0]); i++) { + args.in = RES[i]; + args.key = KEY[i]; + args.param = IV[i]; + + args.inlen = RESLEN[i]; + args.keylen = KEYLEN[i]; + + errs += run_test(&args, DATA[i], DATALEN[i], DECR_FG); + (void) fprintf(stderr, "----------\n"); + } + + if (errs != 0) + (void) fprintf(stderr, "%d tests failed\n", errs); + + return (errs); +} diff --git a/usr/src/test/crypto-tests/tests/modes/aes/cbc/aes_cbc.h b/usr/src/test/crypto-tests/tests/modes/aes/cbc/aes_cbc.h new file mode 100644 index 0000000000..8a4dea540c --- /dev/null +++ b/usr/src/test/crypto-tests/tests/modes/aes/cbc/aes_cbc.h @@ -0,0 +1,173 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2015 Nexenta Systems, Inc. All rights reserved. + */ + +#ifndef _AES_CBC_H +#define _AES_CBC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Test vectors + * RFC3602 section 4 + */ + +static uint8_t CBC1_KEY[16] = { + 0x06, 0xa9, 0x21, 0x40, 0x36, 0xb8, 0xa1, 0x5b, + 0x51, 0x2e, 0x03, 0xd5, 0x34, 0x12, 0x00, 0x06, +}; +static uint8_t CBC1_IV[16] = { + 0x3d, 0xaf, 0xba, 0x42, 0x9d, 0x9e, 0xb4, 0x30, + 0xb4, 0x22, 0xda, 0x80, 0x2c, 0x9f, 0xac, 0x41, +}; +static uint8_t CBC1_DATA[] = { + 'S', 'i', 'n', 'g', 'l', 'e', ' ', 'b', + 'l', 'o', 'c', 'k', ' ', 'm', 's', 'g', +}; +static uint8_t CBC1_RES[] = { + 0xe3, 0x53, 0x77, 0x9c, 0x10, 0x79, 0xae, 0xb8, + 0x27, 0x08, 0x94, 0x2d, 0xbe, 0x77, 0x18, 0x1a, +}; + +static uint8_t CBC2_KEY[] = { + 0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0, + 0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a, +}; +static uint8_t CBC2_IV[] = { + 0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28, + 0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58, +}; +static uint8_t CBC2_DATA[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f +}; +static uint8_t CBC2_RES[] = { + 0xd2, 0x96, 0xcd, 0x94, 0xc2, 0xcc, 0xcf, 0x8a, + 0x3a, 0x86, 0x30, 0x28, 0xb5, 0xe1, 0xdc, 0x0a, + + 0x75, 0x86, 0x60, 0x2d, 0x25, 0x3c, 0xff, 0xf9, + 0x1b, 0x82, 0x66, 0xbe, 0xa6, 0xd6, 0x1a, 0xb1, +}; + +static uint8_t CBC3_KEY[] = { + 0x6c, 0x3e, 0xa0, 0x47, 0x76, 0x30, 0xce, 0x21, + 0xa2, 0xce, 0x33, 0x4a, 0xa7, 0x46, 0xc2, 0xcd, +}; +static uint8_t CBC3_IV[] = { + 0xc7, 0x82, 0xdc, 0x4c, 0x09, 0x8c, 0x66, 0xcb, + 0xd9, 0xcd, 0x27, 0xd8, 0x25, 0x68, 0x2c, 0x81, +}; +static uint8_t CBC3_DATA[] = { + 'T', 'h', 'i', 's', ' ', 'i', 's', ' ', + 'a', ' ', '4', '8', '-', 'b', 'y', 't', + + 'e', ' ', 'm', 'e', 's', 's', 'a', 'g', + 'e', ' ', '(', 'e', 'x', 'a', 'c', 't', + + 'l', 'y', ' ', '3', ' ', 'A', 'E', 'S', + ' ', 'b', 'l', 'o', 'c', 'k', 's', ')', +}; + +static uint8_t CBC3_RES[] = { + 0xd0, 0xa0, 0x2b, 0x38, 0x36, 0x45, 0x17, 0x53, + 0xd4, 0x93, 0x66, 0x5d, 0x33, 0xf0, 0xe8, 0x86, + + 0x2d, 0xea, 0x54, 0xcd, 0xb2, 0x93, 0xab, 0xc7, + 0x50, 0x69, 0x39, 0x27, 0x67, 0x72, 0xf8, 0xd5, + + 0x02, 0x1c, 0x19, 0x21, 0x6b, 0xad, 0x52, 0x5c, + 0x85, 0x79, 0x69, 0x5d, 0x83, 0xba, 0x26, 0x84, +}; + +static uint8_t CBC4_KEY[] = { + 0x56, 0xe4, 0x7a, 0x38, 0xc5, 0x59, 0x89, 0x74, + 0xbc, 0x46, 0x90, 0x3d, 0xba, 0x29, 0x03, 0x49, +}; +static uint8_t CBC4_IV[] = { + 0x8c, 0xe8, 0x2e, 0xef, 0xbe, 0xa0, 0xda, 0x3c, + 0x44, 0x69, 0x9e, 0xd7, 0xdb, 0x51, 0xb7, 0xd9, +}; +static uint8_t CBC4_DATA[] = { + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, +}; +static uint8_t CBC4_RES[] = { + 0xc3, 0x0e, 0x32, 0xff, 0xed, 0xc0, 0x77, 0x4e, + 0x6a, 0xff, 0x6a, 0xf0, 0x86, 0x9f, 0x71, 0xaa, + + 0x0f, 0x3a, 0xf0, 0x7a, 0x9a, 0x31, 0xa9, 0xc6, + 0x84, 0xdb, 0x20, 0x7e, 0xb0, 0xef, 0x8e, 0x4e, + + 0x35, 0x90, 0x7a, 0xa6, 0x32, 0xc3, 0xff, 0xdf, + 0x86, 0x8b, 0xb7, 0xb2, 0x9d, 0x3d, 0x46, 0xad, + + 0x83, 0xce, 0x9f, 0x9a, 0x10, 0x2e, 0xe9, 0x9d, + 0x49, 0xa5, 0x3e, 0x87, 0xf4, 0xc3, 0xda, 0x55, +}; + +uint8_t *DATA[] = { + CBC1_DATA, CBC2_DATA, CBC3_DATA, CBC4_DATA +}; + +size_t DATALEN[] = { + sizeof (CBC1_DATA), sizeof (CBC2_DATA), + sizeof (CBC3_DATA), sizeof (CBC4_DATA), +}; + +uint8_t *KEY[] = { + CBC1_KEY, CBC2_KEY, CBC3_KEY, CBC4_KEY +}; + +size_t KEYLEN[] = { + sizeof (CBC1_KEY), sizeof (CBC2_KEY), + sizeof (CBC3_KEY), sizeof (CBC4_KEY), +}; + +uint8_t *IV[] = { + CBC1_IV, CBC2_IV, CBC3_IV, CBC4_IV +}; + +size_t IVLEN[] = { + sizeof (CBC1_IV), sizeof (CBC2_IV), + sizeof (CBC3_IV), sizeof (CBC4_IV), +}; + +uint8_t *RES[] = { + CBC1_RES, CBC2_RES, CBC3_RES, CBC4_RES +}; + +size_t RESLEN[] = { + sizeof (CBC1_RES), sizeof (CBC2_RES), + sizeof (CBC3_RES), sizeof (CBC4_RES), +}; + +#ifdef __cplusplus +} +#endif + +#endif /* _AES_CBC_H */ diff --git a/usr/src/test/Makefile b/usr/src/test/crypto-tests/tests/modes/aes/ccm/Makefile similarity index 74% copy from usr/src/test/Makefile copy to usr/src/test/crypto-tests/tests/modes/aes/ccm/Makefile index 304163b79f..28ec598193 100644 --- a/usr/src/test/Makefile +++ b/usr/src/test/crypto-tests/tests/modes/aes/ccm/Makefile @@ -11,11 +11,10 @@ # # Copyright (c) 2012 by Delphix. All rights reserved. -# Copyright 2014 Garrett D'Amore +# Copyright 2015 Nexenta Systems, Inc. All rights reserved. # -.PARALLEL: $(SUBDIRS) +PROG = aes_ccm -SUBDIRS = libc-tests os-tests test-runner util-tests zfs-tests - -include Makefile.com +include $(SRC)/cmd/Makefile.cmd +include ../Makefile.subdirs diff --git a/usr/src/test/crypto-tests/tests/modes/aes/ccm/aes_ccm.c b/usr/src/test/crypto-tests/tests/modes/aes/ccm/aes_ccm.c new file mode 100644 index 0000000000..a01129547e --- /dev/null +++ b/usr/src/test/crypto-tests/tests/modes/aes/ccm/aes_ccm.c @@ -0,0 +1,120 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2015 Nexenta Systems, Inc. All rights reserved. + */ + +#include +#include + +#include "cryptotest.h" +#include "aes_ccm.h" + +int +main(void) +{ + int errs = 0; + int i; + uint8_t N[1024]; + CK_AES_CCM_PARAMS param; + cryptotest_t args; + + bzero(¶m, sizeof (param)); + + args.out = N; + args.param = ¶m; + + args.outlen = sizeof (N); + args.plen = sizeof (param); + + args.mechname = SUN_CKM_AES_CCM; + args.updatelen = 1; + + param.authData = CCM_DATA1; + args.key = CCM_KEY1; + args.keylen = sizeof (CCM_KEY1); + for (i = 0; i < 12; i++) { + param.ulMACSize = MACLEN[i]; + param.ulNonceSize = NONCELEN[i]; + param.ulAuthDataSize = AUTHLEN[i]; + param.ulDataSize = DATALEN[i] - AUTHLEN[i]; + param.nonce = NONCE[i]; + + args.in = CCM_DATA1 + AUTHLEN[i]; + args.inlen = DATALEN[i] - AUTHLEN[i]; + + errs += run_test(&args, RES[i] + AUTHLEN[i], + RESLEN[i] - AUTHLEN[i], ENCR_FG); + (void) fprintf(stderr, "----------\n"); + } + + args.key = CCM_KEY2; + args.keylen = sizeof (CCM_KEY2); + for (i = 12; i < 24; i++) { + param.ulMACSize = MACLEN[i]; + param.ulNonceSize = NONCELEN[i]; + param.ulAuthDataSize = AUTHLEN[i]; + param.ulDataSize = DATALEN[i] - AUTHLEN[i]; + param.nonce = NONCE[i]; + param.authData = DATA_2[i-12]; + + args.in = DATA_2[i-12] + AUTHLEN[i]; + args.inlen = DATALEN[i] - AUTHLEN[i]; + + errs += run_test(&args, RES[i] + AUTHLEN[i], + RESLEN[i] - AUTHLEN[i], ENCR_FG); + (void) fprintf(stderr, "----------\n"); + } + + (void) fprintf(stderr, "\t\t\t=== decrypt ===\n----------\n\n"); + + param.authData = CCM_DATA1; + args.key = CCM_KEY1; + args.keylen = sizeof (CCM_KEY1); + for (i = 0; i < 12; i++) { + param.ulMACSize = MACLEN[i]; + param.ulNonceSize = NONCELEN[i]; + param.ulAuthDataSize = AUTHLEN[i]; + param.ulDataSize = RESLEN[i] - AUTHLEN[i]; + param.nonce = NONCE[i]; + + args.in = RES[i] + AUTHLEN[i]; + args.inlen = RESLEN[i] - AUTHLEN[i]; + + errs += run_test(&args, CCM_DATA1 + AUTHLEN[i], + DATALEN[i] - AUTHLEN[i], DECR_FG); + (void) fprintf(stderr, "----------\n"); + } + + args.key = CCM_KEY2; + args.keylen = sizeof (CCM_KEY2); + for (i = 12; i < 24; i++) { + param.ulMACSize = MACLEN[i]; + param.ulNonceSize = NONCELEN[i]; + param.ulAuthDataSize = AUTHLEN[i]; + param.ulDataSize = RESLEN[i] - AUTHLEN[i]; + param.nonce = NONCE[i]; + param.authData = DATA_2[i-12]; + + args.in = RES[i] + AUTHLEN[i]; + args.inlen = RESLEN[i] - AUTHLEN[i]; + + errs += run_test(&args, DATA_2[i-12] + AUTHLEN[i], + DATALEN[i] - AUTHLEN[i], ENCR_FG); + (void) fprintf(stderr, "----------\n"); + } + + if (errs != 0) + (void) fprintf(stderr, "%d tests failed\n", errs); + + return (errs); +} diff --git a/usr/src/test/crypto-tests/tests/modes/aes/ccm/aes_ccm.h b/usr/src/test/crypto-tests/tests/modes/aes/ccm/aes_ccm.h new file mode 100644 index 0000000000..c23ecffe4b --- /dev/null +++ b/usr/src/test/crypto-tests/tests/modes/aes/ccm/aes_ccm.h @@ -0,0 +1,481 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2015 Nexenta Systems, Inc. All rights reserved. + */ + +#ifndef _AES_CCM_H +#define _AES_CCM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Test vectors + * RFC3610 section 4 + */ + +/* + * 1st half + */ +static uint8_t CCM_KEY1[16] = { + 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, + 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, +}; + +/* nonces */ +static uint8_t CCM1_N[] = { + 0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xA0, + 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, +}; +static uint8_t CCM2_N[] = { + 0x00, 0x00, 0x00, 0x04, 0x03, 0x02, 0x01, 0xA0, + 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, +}; +static uint8_t CCM3_N[] = { + 0x00, 0x00, 0x00, 0x05, 0x04, 0x03, 0x02, 0xA0, + 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, +}; +static uint8_t CCM4_N[] = { + 0x00, 0x00, 0x00, 0x06, 0x05, 0x04, 0x03, 0xA0, + 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, +}; +static uint8_t CCM5_N[] = { + 0x00, 0x00, 0x00, 0x07, 0x06, 0x05, 0x04, 0xA0, + 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, +}; +static uint8_t CCM6_N[] = { + 0x00, 0x00, 0x00, 0x08, 0x07, 0x06, 0x05, 0xA0, + 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, +}; +static uint8_t CCM7_N[] = { + 0x00, 0x00, 0x00, 0x09, 0x08, 0x07, 0x06, 0xA0, + 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, +}; +static uint8_t CCM8_N[] = { + 0x00, 0x00, 0x00, 0x0A, 0x09, 0x08, 0x07, 0xA0, + 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, +}; +static uint8_t CCM9_N[] = { + 0x00, 0x00, 0x00, 0x0B, 0x0A, 0x09, 0x08, 0xA0, + 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, +}; +static uint8_t CCM10_N[] = { + 0x00, 0x00, 0x00, 0x0C, 0x0B, 0x0A, 0x09, 0xA0, + 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, +}; +static uint8_t CCM11_N[] = { + 0x00, 0x00, 0x00, 0x0D, 0x0C, 0x0B, 0x0A, 0xA0, + 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, +}; +static uint8_t CCM12_N[] = { + 0x00, 0x00, 0x00, 0x0E, 0x0D, 0x0C, 0x0B, 0xA0, + 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, +}; + +/* vector data is a subset of this */ +static uint8_t CCM_DATA1[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, +}; + +/* results */ +static uint8_t CCM1_RES[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x58, 0x8C, 0x97, 0x9A, 0x61, 0xC6, 0x63, 0xD2, + 0xF0, 0x66, 0xD0, 0xC2, 0xC0, 0xF9, 0x89, 0x80, + 0x6D, 0x5F, 0x6B, 0x61, 0xDA, 0xC3, 0x84, 0x17, + 0xE8, 0xD1, 0x2C, 0xFD, 0xF9, 0x26, 0xE0, +}; +static uint8_t CCM2_RES[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x72, 0xC9, 0x1A, 0x36, 0xE1, 0x35, 0xF8, 0xCF, + 0x29, 0x1C, 0xA8, 0x94, 0x08, 0x5C, 0x87, 0xE3, + 0xCC, 0x15, 0xC4, 0x39, 0xC9, 0xE4, 0x3A, 0x3B, + 0xA0, 0x91, 0xD5, 0x6E, 0x10, 0x40, 0x09, 0x16, +}; +static uint8_t CCM3_RES[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x51, 0xB1, 0xE5, 0xF4, 0x4A, 0x19, 0x7D, 0x1D, + 0xA4, 0x6B, 0x0F, 0x8E, 0x2D, 0x28, 0x2A, 0xE8, + 0x71, 0xE8, 0x38, 0xBB, 0x64, 0xDA, 0x85, 0x96, + 0x57, 0x4A, 0xDA, 0xA7, 0x6F, 0xBD, 0x9F, 0xB0, + 0xC5, +}; +static uint8_t CCM4_RES[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0xA2, 0x8C, 0x68, 0x65, + 0x93, 0x9A, 0x9A, 0x79, 0xFA, 0xAA, 0x5C, 0x4C, + 0x2A, 0x9D, 0x4A, 0x91, 0xCD, 0xAC, 0x8C, 0x96, + 0xC8, 0x61, 0xB9, 0xC9, 0xE6, 0x1E, 0xF1, +}; +static uint8_t CCM5_RES[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0xDC, 0xF1, 0xFB, 0x7B, + 0x5D, 0x9E, 0x23, 0xFB, 0x9D, 0x4E, 0x13, 0x12, + 0x53, 0x65, 0x8A, 0xD8, 0x6E, 0xBD, 0xCA, 0x3E, + 0x51, 0xE8, 0x3F, 0x07, 0x7D, 0x9C, 0x2D, 0x93, +}; +static uint8_t CCM6_RES[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x6F, 0xC1, 0xB0, 0x11, + 0xF0, 0x06, 0x56, 0x8B, 0x51, 0x71, 0xA4, 0x2D, + 0x95, 0x3D, 0x46, 0x9B, 0x25, 0x70, 0xA4, 0xBD, + 0x87, 0x40, 0x5A, 0x04, 0x43, 0xAC, 0x91, 0xCB, + 0x94, +}; +static uint8_t CCM7_RES[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x01, 0x35, 0xD1, 0xB2, 0xC9, 0x5F, 0x41, 0xD5, + 0xD1, 0xD4, 0xFE, 0xC1, 0x85, 0xD1, 0x66, 0xB8, + 0x09, 0x4E, 0x99, 0x9D, 0xFE, 0xD9, 0x6C, 0x04, + 0x8C, 0x56, 0x60, 0x2C, 0x97, 0xAC, 0xBB, 0x74, + 0x90, +}; +static uint8_t CCM8_RES[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x7B, 0x75, 0x39, 0x9A, 0xC0, 0x83, 0x1D, 0xD2, + 0xF0, 0xBB, 0xD7, 0x58, 0x79, 0xA2, 0xFD, 0x8F, + 0x6C, 0xAE, 0x6B, 0x6C, 0xD9, 0xB7, 0xDB, 0x24, + 0xC1, 0x7B, 0x44, 0x33, 0xF4, 0x34, 0x96, 0x3F, + 0x34, 0xB4, +}; +static uint8_t CCM9_RES[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x82, 0x53, 0x1A, 0x60, 0xCC, 0x24, 0x94, 0x5A, + 0x4B, 0x82, 0x79, 0x18, 0x1A, 0xB5, 0xC8, 0x4D, + 0xF2, 0x1C, 0xE7, 0xF9, 0xB7, 0x3F, 0x42, 0xE1, + 0x97, 0xEA, 0x9C, 0x07, 0xE5, 0x6B, 0x5E, 0xB1, + 0x7E, 0x5F, 0x4E, +}; +static uint8_t CCM10_RES[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x07, 0x34, 0x25, 0x94, + 0x15, 0x77, 0x85, 0x15, 0x2B, 0x07, 0x40, 0x98, + 0x33, 0x0A, 0xBB, 0x14, 0x1B, 0x94, 0x7B, 0x56, + 0x6A, 0xA9, 0x40, 0x6B, 0x4D, 0x99, 0x99, 0x88, + 0xDD, +}; +static uint8_t CCM11_RES[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x67, 0x6B, 0xB2, 0x03, + 0x80, 0xB0, 0xE3, 0x01, 0xE8, 0xAB, 0x79, 0x59, + 0x0A, 0x39, 0x6D, 0xA7, 0x8B, 0x83, 0x49, 0x34, + 0xF5, 0x3A, 0xA2, 0xE9, 0x10, 0x7A, 0x8B, 0x6C, + 0x02, 0x2C, +}; +static uint8_t CCM12_RES[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0xC0, 0xFF, 0xA0, 0xD6, + 0xF0, 0x5B, 0xDB, 0x67, 0xF2, 0x4D, 0x43, 0xA4, + 0x33, 0x8D, 0x2A, 0xA4, 0xBE, 0xD7, 0xB2, 0x0E, + 0x43, 0xCD, 0x1A, 0xA3, 0x16, 0x62, 0xE7, 0xAD, + 0x65, 0xD6, 0xDB, +}; + + +/* + * 2nd half + */ +static uint8_t CCM_KEY2[16] = { + 0xD7, 0x82, 0x8D, 0x13, 0xB2, 0xB0, 0xBD, 0xC3, + 0x25, 0xA7, 0x62, 0x36, 0xDF, 0x93, 0xCC, 0x6B, +}; + +/* nonces */ +static uint8_t CCM13_N[] = { + 0x00, 0x41, 0x2B, 0x4E, 0xA9, 0xCD, 0xBE, 0x3C, + 0x96, 0x96, 0x76, 0x6C, 0xFA, +}; +static uint8_t CCM14_N[] = { + 0x00, 0x33, 0x56, 0x8E, 0xF7, 0xB2, 0x63, 0x3C, + 0x96, 0x96, 0x76, 0x6C, 0xFA, +}; +static uint8_t CCM15_N[] = { + 0x00, 0x10, 0x3F, 0xE4, 0x13, 0x36, 0x71, 0x3C, + 0x96, 0x96, 0x76, 0x6C, 0xFA, +}; +static uint8_t CCM16_N[] = { + 0x00, 0x76, 0x4C, 0x63, 0xB8, 0x05, 0x8E, 0x3C, + 0x96, 0x96, 0x76, 0x6C, 0xFA, +}; +static uint8_t CCM17_N[] = { + 0x00, 0xF8, 0xB6, 0x78, 0x09, 0x4E, 0x3B, 0x3C, + 0x96, 0x96, 0x76, 0x6C, 0xFA, +}; +static uint8_t CCM18_N[] = { + 0x00, 0xD5, 0x60, 0x91, 0x2D, 0x3F, 0x70, 0x3C, + 0x96, 0x96, 0x76, 0x6C, 0xFA, +}; +static uint8_t CCM19_N[] = { + 0x00, 0x42, 0xFF, 0xF8, 0xF1, 0x95, 0x1C, 0x3C, + 0x96, 0x96, 0x76, 0x6C, 0xFA, +}; +static uint8_t CCM20_N[] = { + 0x00, 0x92, 0x0F, 0x40, 0xE5, 0x6C, 0xDC, 0x3C, + 0x96, 0x96, 0x76, 0x6C, 0xFA, +}; +static uint8_t CCM21_N[] = { + 0x00, 0x27, 0xCA, 0x0C, 0x71, 0x20, 0xBC, 0x3C, + 0x96, 0x96, 0x76, 0x6C, 0xFA, +}; +static uint8_t CCM22_N[] = { + 0x00, 0x5B, 0x8C, 0xCB, 0xCD, 0x9A, 0xF8, 0x3C, + 0x96, 0x96, 0x76, 0x6C, 0xFA, +}; +static uint8_t CCM23_N[] = { + 0x00, 0x3E, 0xBE, 0x94, 0x04, 0x4B, 0x9A, 0x3C, + 0x96, 0x96, 0x76, 0x6C, 0xFA, +}; +static uint8_t CCM24_N[] = { + 0x00, 0x8D, 0x49, 0x3B, 0x30, 0xAE, 0x8B, 0x3C, + 0x96, 0x96, 0x76, 0x6C, 0xFA, +}; + +/* data */ +static uint8_t CCM13_DATA[] = { + 0x0B, 0xE1, 0xA8, 0x8B, 0xAC, 0xE0, 0x18, 0xB1, + 0x08, 0xE8, 0xCF, 0x97, 0xD8, 0x20, 0xEA, 0x25, + 0x84, 0x60, 0xE9, 0x6A, 0xD9, 0xCF, 0x52, 0x89, + 0x05, 0x4D, 0x89, 0x5C, 0xEA, 0xC4, 0x7C, +}; +static uint8_t CCM14_DATA[] = { + 0x63, 0x01, 0x8F, 0x76, 0xDC, 0x8A, 0x1B, 0xCB, + 0x90, 0x20, 0xEA, 0x6F, 0x91, 0xBD, 0xD8, 0x5A, + 0xFA, 0x00, 0x39, 0xBA, 0x4B, 0xAF, 0xF9, 0xBF, + 0xB7, 0x9C, 0x70, 0x28, 0x94, 0x9C, 0xD0, 0xEC, +}; +static uint8_t CCM15_DATA[] = { + 0xAA, 0x6C, 0xFA, 0x36, 0xCA, 0xE8, 0x6B, 0x40, + 0xB9, 0x16, 0xE0, 0xEA, 0xCC, 0x1C, 0x00, 0xD7, + 0xDC, 0xEC, 0x68, 0xEC, 0x0B, 0x3B, 0xBB, 0x1A, + 0x02, 0xDE, 0x8A, 0x2D, 0x1A, 0xA3, 0x46, 0x13, + 0x2E, +}; +static uint8_t CCM16_DATA[] = { + 0xD0, 0xD0, 0x73, 0x5C, 0x53, 0x1E, 0x1B, 0xEC, + 0xF0, 0x49, 0xC2, 0x44, 0x12, 0xDA, 0xAC, 0x56, + 0x30, 0xEF, 0xA5, 0x39, 0x6F, 0x77, 0x0C, 0xE1, + 0xA6, 0x6B, 0x21, 0xF7, 0xB2, 0x10, 0x1C, +}; +static uint8_t CCM17_DATA[] = { + 0x77, 0xB6, 0x0F, 0x01, 0x1C, 0x03, 0xE1, 0x52, + 0x58, 0x99, 0xBC, 0xAE, 0xE8, 0x8B, 0x6A, 0x46, + 0xC7, 0x8D, 0x63, 0xE5, 0x2E, 0xB8, 0xC5, 0x46, + 0xEF, 0xB5, 0xDE, 0x6F, 0x75, 0xE9, 0xCC, 0x0D, +}; +static uint8_t CCM18_DATA[] = { + 0xCD, 0x90, 0x44, 0xD2, 0xB7, 0x1F, 0xDB, 0x81, + 0x20, 0xEA, 0x60, 0xC0, 0x64, 0x35, 0xAC, 0xBA, + 0xFB, 0x11, 0xA8, 0x2E, 0x2F, 0x07, 0x1D, 0x7C, + 0xA4, 0xA5, 0xEB, 0xD9, 0x3A, 0x80, 0x3B, 0xA8, + 0x7F, +}; +static uint8_t CCM19_DATA[] = { + 0xD8, 0x5B, 0xC7, 0xE6, 0x9F, 0x94, 0x4F, 0xB8, + 0x8A, 0x19, 0xB9, 0x50, 0xBC, 0xF7, 0x1A, 0x01, + 0x8E, 0x5E, 0x67, 0x01, 0xC9, 0x17, 0x87, 0x65, + 0x98, 0x09, 0xD6, 0x7D, 0xBE, 0xDD, 0x18, +}; +static uint8_t CCM20_DATA[] = { + 0x74, 0xA0, 0xEB, 0xC9, 0x06, 0x9F, 0x5B, 0x37, + 0x17, 0x61, 0x43, 0x3C, 0x37, 0xC5, 0xA3, 0x5F, + 0xC1, 0xF3, 0x9F, 0x40, 0x63, 0x02, 0xEB, 0x90, + 0x7C, 0x61, 0x63, 0xBE, 0x38, 0xC9, 0x84, 0x37, +}; +static uint8_t CCM21_DATA[] = { + 0x44, 0xA3, 0xAA, 0x3A, 0xAE, 0x64, 0x75, 0xCA, + 0xA4, 0x34, 0xA8, 0xE5, 0x85, 0x00, 0xC6, 0xE4, + 0x15, 0x30, 0x53, 0x88, 0x62, 0xD6, 0x86, 0xEA, + 0x9E, 0x81, 0x30, 0x1B, 0x5A, 0xE4, 0x22, 0x6B, + 0xFA, +}; +static uint8_t CCM22_DATA[] = { + 0xEC, 0x46, 0xBB, 0x63, 0xB0, 0x25, 0x20, 0xC3, + 0x3C, 0x49, 0xFD, 0x70, 0xB9, 0x6B, 0x49, 0xE2, + 0x1D, 0x62, 0x17, 0x41, 0x63, 0x28, 0x75, 0xDB, + 0x7F, 0x6C, 0x92, 0x43, 0xD2, 0xD7, 0xC2, +}; +static uint8_t CCM23_DATA[] = { + 0x47, 0xA6, 0x5A, 0xC7, 0x8B, 0x3D, 0x59, 0x42, + 0x27, 0xE8, 0x5E, 0x71, 0xE2, 0xFC, 0xFB, 0xB8, + 0x80, 0x44, 0x2C, 0x73, 0x1B, 0xF9, 0x51, 0x67, + 0xC8, 0xFF, 0xD7, 0x89, 0x5E, 0x33, 0x70, 0x76, +}; +static uint8_t CCM24_DATA[] = { + 0x6E, 0x37, 0xA6, 0xEF, 0x54, 0x6D, 0x95, 0x5D, + 0x34, 0xAB, 0x60, 0x59, 0xAB, 0xF2, 0x1C, 0x0B, + 0x02, 0xFE, 0xB8, 0x8F, 0x85, 0x6D, 0xF4, 0xA3, + 0x73, 0x81, 0xBC, 0xE3, 0xCC, 0x12, 0x85, 0x17, + 0xD4, +}; + +/* results */ + +static uint8_t CCM13_RES[] = { + 0x0B, 0xE1, 0xA8, 0x8B, 0xAC, 0xE0, 0x18, 0xB1, + 0x4C, 0xB9, 0x7F, 0x86, 0xA2, 0xA4, 0x68, 0x9A, + 0x87, 0x79, 0x47, 0xAB, 0x80, 0x91, 0xEF, 0x53, + 0x86, 0xA6, 0xFF, 0xBD, 0xD0, 0x80, 0xF8, 0xE7, + 0x8C, 0xF7, 0xCB, 0x0C, 0xDD, 0xD7, 0xB3, +}; +static uint8_t CCM14_RES[] = { + 0x63, 0x01, 0x8F, 0x76, 0xDC, 0x8A, 0x1B, 0xCB, + 0x4C, 0xCB, 0x1E, 0x7C, 0xA9, 0x81, 0xBE, 0xFA, + 0xA0, 0x72, 0x6C, 0x55, 0xD3, 0x78, 0x06, 0x12, + 0x98, 0xC8, 0x5C, 0x92, 0x81, 0x4A, 0xBC, 0x33, + 0xC5, 0x2E, 0xE8, 0x1D, 0x7D, 0x77, 0xC0, 0x8A, +}; +static uint8_t CCM15_RES[] = { + 0xAA, 0x6C, 0xFA, 0x36, 0xCA, 0xE8, 0x6B, 0x40, + 0xB1, 0xD2, 0x3A, 0x22, 0x20, 0xDD, 0xC0, 0xAC, + 0x90, 0x0D, 0x9A, 0xA0, 0x3C, 0x61, 0xFC, 0xF4, + 0xA5, 0x59, 0xA4, 0x41, 0x77, 0x67, 0x08, 0x97, + 0x08, 0xA7, 0x76, 0x79, 0x6E, 0xDB, 0x72, 0x35, + 0x06, +}; +static uint8_t CCM16_RES[] = { + 0xD0, 0xD0, 0x73, 0x5C, 0x53, 0x1E, 0x1B, 0xEC, + 0xF0, 0x49, 0xC2, 0x44, 0x14, 0xD2, 0x53, 0xC3, + 0x96, 0x7B, 0x70, 0x60, 0x9B, 0x7C, 0xBB, 0x7C, + 0x49, 0x91, 0x60, 0x28, 0x32, 0x45, 0x26, 0x9A, + 0x6F, 0x49, 0x97, 0x5B, 0xCA, 0xDE, 0xAF, +}; +static uint8_t CCM17_RES[] = { + 0x77, 0xB6, 0x0F, 0x01, 0x1C, 0x03, 0xE1, 0x52, + 0x58, 0x99, 0xBC, 0xAE, 0x55, 0x45, 0xFF, 0x1A, + 0x08, 0x5E, 0xE2, 0xEF, 0xBF, 0x52, 0xB2, 0xE0, + 0x4B, 0xEE, 0x1E, 0x23, 0x36, 0xC7, 0x3E, 0x3F, + 0x76, 0x2C, 0x0C, 0x77, 0x44, 0xFE, 0x7E, 0x3C, +}; +static uint8_t CCM18_RES[] = { + 0xCD, 0x90, 0x44, 0xD2, 0xB7, 0x1F, 0xDB, 0x81, + 0x20, 0xEA, 0x60, 0xC0, 0x00, 0x97, 0x69, 0xEC, + 0xAB, 0xDF, 0x48, 0x62, 0x55, 0x94, 0xC5, 0x92, + 0x51, 0xE6, 0x03, 0x57, 0x22, 0x67, 0x5E, 0x04, + 0xC8, 0x47, 0x09, 0x9E, 0x5A, 0xE0, 0x70, 0x45, + 0x51, +}; +static uint8_t CCM19_RES[] = { + 0xD8, 0x5B, 0xC7, 0xE6, 0x9F, 0x94, 0x4F, 0xB8, + 0xBC, 0x21, 0x8D, 0xAA, 0x94, 0x74, 0x27, 0xB6, + 0xDB, 0x38, 0x6A, 0x99, 0xAC, 0x1A, 0xEF, 0x23, + 0xAD, 0xE0, 0xB5, 0x29, 0x39, 0xCB, 0x6A, 0x63, + 0x7C, 0xF9, 0xBE, 0xC2, 0x40, 0x88, 0x97, 0xC6, + 0xBA, +}; +static uint8_t CCM20_RES[] = { + 0x74, 0xA0, 0xEB, 0xC9, 0x06, 0x9F, 0x5B, 0x37, + 0x58, 0x10, 0xE6, 0xFD, 0x25, 0x87, 0x40, 0x22, + 0xE8, 0x03, 0x61, 0xA4, 0x78, 0xE3, 0xE9, 0xCF, + 0x48, 0x4A, 0xB0, 0x4F, 0x44, 0x7E, 0xFF, 0xF6, + 0xF0, 0xA4, 0x77, 0xCC, 0x2F, 0xC9, 0xBF, 0x54, + 0x89, 0x44, +}; +static uint8_t CCM21_RES[] = { + 0x44, 0xA3, 0xAA, 0x3A, 0xAE, 0x64, 0x75, 0xCA, + 0xF2, 0xBE, 0xED, 0x7B, 0xC5, 0x09, 0x8E, 0x83, + 0xFE, 0xB5, 0xB3, 0x16, 0x08, 0xF8, 0xE2, 0x9C, + 0x38, 0x81, 0x9A, 0x89, 0xC8, 0xE7, 0x76, 0xF1, + 0x54, 0x4D, 0x41, 0x51, 0xA4, 0xED, 0x3A, 0x8B, + 0x87, 0xB9, 0xCE, +}; +static uint8_t CCM22_RES[] = { + 0xEC, 0x46, 0xBB, 0x63, 0xB0, 0x25, 0x20, 0xC3, + 0x3C, 0x49, 0xFD, 0x70, 0x31, 0xD7, 0x50, 0xA0, + 0x9D, 0xA3, 0xED, 0x7F, 0xDD, 0xD4, 0x9A, 0x20, + 0x32, 0xAA, 0xBF, 0x17, 0xEC, 0x8E, 0xBF, 0x7D, + 0x22, 0xC8, 0x08, 0x8C, 0x66, 0x6B, 0xE5, 0xC1, + 0x97, +}; +static uint8_t CCM23_RES[] = { + 0x47, 0xA6, 0x5A, 0xC7, 0x8B, 0x3D, 0x59, 0x42, + 0x27, 0xE8, 0x5E, 0x71, 0xE8, 0x82, 0xF1, 0xDB, + 0xD3, 0x8C, 0xE3, 0xED, 0xA7, 0xC2, 0x3F, 0x04, + 0xDD, 0x65, 0x07, 0x1E, 0xB4, 0x13, 0x42, 0xAC, + 0xDF, 0x7E, 0x00, 0xDC, 0xCE, 0xC7, 0xAE, 0x52, + 0x98, 0x7D, +}; +static uint8_t CCM24_RES[] = { + 0x6E, 0x37, 0xA6, 0xEF, 0x54, 0x6D, 0x95, 0x5D, + 0x34, 0xAB, 0x60, 0x59, 0xF3, 0x29, 0x05, 0xB8, + 0x8A, 0x64, 0x1B, 0x04, 0xB9, 0xC9, 0xFF, 0xB5, + 0x8C, 0xC3, 0x90, 0x90, 0x0F, 0x3D, 0xA1, 0x2A, + 0xB1, 0x6D, 0xCE, 0x9E, 0x82, 0xEF, 0xA1, 0x6D, + 0xA6, 0x20, 0x59, +}; + +uint8_t *DATA_2[] = { + CCM13_DATA, CCM14_DATA, CCM15_DATA, CCM16_DATA, CCM17_DATA, CCM18_DATA, + CCM19_DATA, CCM20_DATA, CCM21_DATA, CCM22_DATA, CCM23_DATA, CCM24_DATA, +}; + +size_t DATALEN[] = { + 31, 32, 33, 31, 32, 33, 31, 32, 33, 31, 32, 33, + sizeof (CCM13_DATA), sizeof (CCM14_DATA), sizeof (CCM15_DATA), + sizeof (CCM16_DATA), sizeof (CCM17_DATA), sizeof (CCM18_DATA), + sizeof (CCM19_DATA), sizeof (CCM20_DATA), sizeof (CCM21_DATA), + sizeof (CCM22_DATA), sizeof (CCM23_DATA), sizeof (CCM24_DATA), +}; + +uint8_t *RES[] = { + CCM1_RES, CCM2_RES, CCM3_RES, CCM4_RES, CCM5_RES, CCM6_RES, + CCM7_RES, CCM8_RES, CCM9_RES, CCM10_RES, CCM11_RES, CCM12_RES, + CCM13_RES, CCM14_RES, CCM15_RES, CCM16_RES, CCM17_RES, CCM18_RES, + CCM19_RES, CCM20_RES, CCM21_RES, CCM22_RES, CCM23_RES, CCM24_RES, +}; + +size_t RESLEN[] = { + sizeof (CCM1_RES), sizeof (CCM2_RES), sizeof (CCM3_RES), + sizeof (CCM4_RES), sizeof (CCM5_RES), sizeof (CCM6_RES), + sizeof (CCM7_RES), sizeof (CCM8_RES), sizeof (CCM9_RES), + sizeof (CCM10_RES), sizeof (CCM11_RES), sizeof (CCM12_RES), + sizeof (CCM13_RES), sizeof (CCM14_RES), sizeof (CCM15_RES), + sizeof (CCM16_RES), sizeof (CCM17_RES), sizeof (CCM18_RES), + sizeof (CCM19_RES), sizeof (CCM20_RES), sizeof (CCM21_RES), + sizeof (CCM22_RES), sizeof (CCM23_RES), sizeof (CCM24_RES), +}; + +uint8_t *NONCE[] = { + CCM1_N, CCM2_N, CCM3_N, CCM4_N, CCM5_N, CCM6_N, CCM7_N, CCM8_N, + CCM9_N, CCM10_N, CCM11_N, CCM12_N, CCM13_N, CCM14_N, CCM15_N, CCM16_N, + CCM17_N, CCM18_N, CCM19_N, CCM20_N, CCM21_N, CCM22_N, CCM23_N, CCM24_N, +}; + +size_t NONCELEN[] = { + sizeof (CCM1_N), sizeof (CCM2_N), sizeof (CCM3_N), sizeof (CCM4_N), + sizeof (CCM5_N), sizeof (CCM6_N), sizeof (CCM7_N), sizeof (CCM8_N), + sizeof (CCM9_N), sizeof (CCM10_N), sizeof (CCM11_N), sizeof (CCM12_N), + sizeof (CCM13_N), sizeof (CCM14_N), sizeof (CCM15_N), sizeof (CCM16_N), + sizeof (CCM17_N), sizeof (CCM18_N), sizeof (CCM19_N), sizeof (CCM20_N), + sizeof (CCM21_N), sizeof (CCM22_N), sizeof (CCM23_N), sizeof (CCM24_N), +}; + +size_t AUTHLEN[] = { + 8, 8, 8, 12, 12, 12, 8, 8, 8, 12, 12, 12, + 8, 8, 8, 12, 12, 12, 8, 8, 8, 12, 12, 12, +}; + +size_t MACLEN[] = { + 8, 8, 8, 8, 8, 8, 10, 10, 10, 10, 10, 10, + 8, 8, 8, 8, 8, 8, 10, 10, 10, 10, 10, 10, +}; + +#ifdef __cplusplus +} +#endif + +#endif /* _AES_CCM_H */ diff --git a/usr/src/test/Makefile b/usr/src/test/crypto-tests/tests/modes/aes/cmac/Makefile similarity index 74% copy from usr/src/test/Makefile copy to usr/src/test/crypto-tests/tests/modes/aes/cmac/Makefile index 304163b79f..c4e63db251 100644 --- a/usr/src/test/Makefile +++ b/usr/src/test/crypto-tests/tests/modes/aes/cmac/Makefile @@ -11,11 +11,10 @@ # # Copyright (c) 2012 by Delphix. All rights reserved. -# Copyright 2014 Garrett D'Amore +# Copyright 2015 Nexenta Systems, Inc. All rights reserved. # -.PARALLEL: $(SUBDIRS) +PROG = aes_cmac -SUBDIRS = libc-tests os-tests test-runner util-tests zfs-tests - -include Makefile.com +include $(SRC)/cmd/Makefile.cmd +include ../Makefile.subdirs diff --git a/usr/src/test/crypto-tests/tests/modes/aes/cmac/aes_cmac.c b/usr/src/test/crypto-tests/tests/modes/aes/cmac/aes_cmac.c new file mode 100644 index 0000000000..a6e5936a80 --- /dev/null +++ b/usr/src/test/crypto-tests/tests/modes/aes/cmac/aes_cmac.c @@ -0,0 +1,51 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2015 Nexenta Systems, Inc. All rights reserved. + */ + +#include +#include + +#include "cryptotest.h" +#include "aes_cmac.h" + +int +main(void) +{ + int errs = 0; + int i; + uint8_t N[AES_BLOCK_LEN]; + cryptotest_t args; + + args.in = M; + args.out = N; + args.key = keytest; + args.param = NULL; + + args.outlen = sizeof (N); + args.keylen = sizeof (keytest); + args.plen = 0; + + args.mechname = SUN_CKM_AES_CMAC; + args.updatelen = 1; + + for (i = 0; i < sizeof (RES) / sizeof (RES[0]); i++) { + args.inlen = DATALEN[i]; + errs += run_test(&args, RES[i], AES_BLOCK_LEN, MAC_FG); + (void) fprintf(stderr, "----------\n"); + } + if (errs != 0) + (void) fprintf(stderr, "%d tests failed\n", errs); + + return (errs); +} diff --git a/usr/src/test/crypto-tests/tests/modes/aes/cmac/aes_cmac.h b/usr/src/test/crypto-tests/tests/modes/aes/cmac/aes_cmac.h new file mode 100644 index 0000000000..7f6c9b0fad --- /dev/null +++ b/usr/src/test/crypto-tests/tests/modes/aes/cmac/aes_cmac.h @@ -0,0 +1,72 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2015 Nexenta Systems, Inc. All rights reserved. + */ + +#ifndef _AES_CMAC_H +#define _AES_CMAC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Test Vectors + * RFC4493 + */ +static uint8_t CMAC_0[AES_BLOCK_LEN] = { + 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28, + 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46 +}; +static uint8_t CMAC_16[AES_BLOCK_LEN] = { + 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44, + 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c +}; +static uint8_t CMAC_40[AES_BLOCK_LEN] = { + 0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30, + 0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27 +}; +static uint8_t CMAC_64[AES_BLOCK_LEN] = { + 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92, + 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe +}; + +uint8_t M[64] = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, + 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, + 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 +}; + +uint8_t keytest[16] = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c +}; + +uint8_t *RES[] = { + CMAC_0, CMAC_16, CMAC_40, CMAC_64 +}; + +size_t DATALEN[] = { + 0, 16, 40, 64 +}; + +#ifdef __cplusplus +} +#endif + +#endif /* _AES_CMAC_H */ diff --git a/usr/src/test/Makefile b/usr/src/test/crypto-tests/tests/modes/aes/ctr/Makefile similarity index 74% copy from usr/src/test/Makefile copy to usr/src/test/crypto-tests/tests/modes/aes/ctr/Makefile index 304163b79f..a1a1d35425 100644 --- a/usr/src/test/Makefile +++ b/usr/src/test/crypto-tests/tests/modes/aes/ctr/Makefile @@ -11,11 +11,10 @@ # # Copyright (c) 2012 by Delphix. All rights reserved. -# Copyright 2014 Garrett D'Amore +# Copyright 2015 Nexenta Systems, Inc. All rights reserved. # -.PARALLEL: $(SUBDIRS) +PROG = aes_ctr -SUBDIRS = libc-tests os-tests test-runner util-tests zfs-tests - -include Makefile.com +include $(SRC)/cmd/Makefile.cmd +include ../Makefile.subdirs diff --git a/usr/src/test/crypto-tests/tests/modes/aes/ctr/aes_ctr.c b/usr/src/test/crypto-tests/tests/modes/aes/ctr/aes_ctr.c new file mode 100644 index 0000000000..c747485b8b --- /dev/null +++ b/usr/src/test/crypto-tests/tests/modes/aes/ctr/aes_ctr.c @@ -0,0 +1,85 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2016 Nexenta Systems, Inc. All rights reserved. + */ + +#include +#include +/* used for CK_*_PARAMS */ +#include + +#include "cryptotest.h" +#include "aes_ctr.h" + +int +main(void) +{ + int errs = 0; + int i; + uint8_t N[1024]; + CK_AES_CTR_PARAMS param; + cryptotest_t args; + size_t cblen = sizeof (CTR_CB0); + + bzero(¶m, sizeof (param)); + param.ulCounterBits = 128 - cblen*8; + param.cb[15] = 0x01; + + args.out = N; + args.param = ¶m; + + args.outlen = sizeof (N); + args.plen = sizeof (param); + + /* + * CTR is a stream cipher, and it runs ctr_mode_final every time + * it has a remainder, so the result is different + * if len == 0 mod block_size vs len != 0 mod block_size + */ + + args.mechname = SUN_CKM_AES_CTR; + args.updatelen = 16; + + for (i = 0; i < sizeof (DATA) / sizeof (DATA[0]); i++) { + bcopy(CB[i], param.cb, cblen); + + args.in = DATA[i]; + args.key = KEY[i]; + + args.inlen = DATALEN[i]; + args.keylen = KEYLEN[i]; + + errs += run_test(&args, RES[i], RESLEN[i], ENCR_FG); + (void) fprintf(stderr, "----------\n"); + } + + (void) fprintf(stderr, "\t\t\t=== decrypt ===\n----------\n\n"); + + for (i = 0; i < sizeof (DATA) / sizeof (DATA[0]); i++) { + bcopy(CB[i], param.cb, cblen); + + args.in = RES[i]; + args.key = KEY[i]; + + args.inlen = RESLEN[i]; + args.keylen = KEYLEN[i]; + + errs += run_test(&args, DATA[i], DATALEN[i], ENCR_FG); + (void) fprintf(stderr, "----------\n"); + } + + if (errs != 0) + (void) fprintf(stderr, "%d tests failed\n", errs); + + return (errs); +} diff --git a/usr/src/test/crypto-tests/tests/modes/aes/ctr/aes_ctr.h b/usr/src/test/crypto-tests/tests/modes/aes/ctr/aes_ctr.h new file mode 100644 index 0000000000..369ebc56fb --- /dev/null +++ b/usr/src/test/crypto-tests/tests/modes/aes/ctr/aes_ctr.h @@ -0,0 +1,289 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2015 Nexenta Systems, Inc. All rights reserved. + */ + +#ifndef _AES_CTR_H +#define _AES_CTR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Test vectors + * RFC3686 section 6 + */ + +uint8_t CTR_KEY0[] = { + 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC, + 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E, +}; + +uint8_t CTR_CB0[] = { + 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, +}; + +uint8_t CTR_DATA0[] = { + 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62, + 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67, +}; + +uint8_t CTR_RES0[] = { + 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79, + 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8, +}; + +uint8_t CTR_KEY1[] = { + 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7, + 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63, +}; + +uint8_t CTR_CB1[] = { + 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59, + 0xDA, 0x48, 0xD9, 0x0B, +}; + +uint8_t CTR_DATA1[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, +}; + +uint8_t CTR_RES1[] = { + 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9, + 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88, + 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8, + 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28, +}; + +uint8_t CTR_KEY2[] = { + 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8, + 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC, +}; + +uint8_t CTR_CB2[] = { + 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F, + 0x4A, 0x17, 0x86, 0xF0, +}; + +uint8_t CTR_DATA2[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x22, 0x23, +}; + +uint8_t CTR_RES2[] = { + 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9, + 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7, + 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36, + 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53, + 0x25, 0xB2, 0x07, 0x2F, +}; + +uint8_t CTR_KEY3[] = { + 0x16, 0xAF, 0x5B, 0x14, 0x5F, 0xC9, 0xF5, 0x79, + 0xC1, 0x75, 0xF9, 0x3E, 0x3B, 0xFB, 0x0E, 0xED, + 0x86, 0x3D, 0x06, 0xCC, 0xFD, 0xB7, 0x85, 0x15, +}; + +uint8_t CTR_CB3[] = { + 0x00, 0x00, 0x00, 0x48, 0x36, 0x73, 0x3C, 0x14, + 0x7D, 0x6D, 0x93, 0xCB, +}; + +uint8_t CTR_DATA3[] = { + 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62, + 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67, +}; + +uint8_t CTR_RES3[] = { + 0x4B, 0x55, 0x38, 0x4F, 0xE2, 0x59, 0xC9, 0xC8, + 0x4E, 0x79, 0x35, 0xA0, 0x03, 0xCB, 0xE9, 0x28, +}; + +uint8_t CTR_KEY4[] = { + 0x7C, 0x5C, 0xB2, 0x40, 0x1B, 0x3D, 0xC3, 0x3C, + 0x19, 0xE7, 0x34, 0x08, 0x19, 0xE0, 0xF6, 0x9C, + 0x67, 0x8C, 0x3D, 0xB8, 0xE6, 0xF6, 0xA9, 0x1A, +}; + +uint8_t CTR_CB4[] = { + 0x00, 0x96, 0xB0, 0x3B, 0x02, 0x0C, 0x6E, 0xAD, + 0xC2, 0xCB, 0x50, 0x0D, +}; + +uint8_t CTR_DATA4[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, +}; + +uint8_t CTR_RES4[] = { + 0x45, 0x32, 0x43, 0xFC, 0x60, 0x9B, 0x23, 0x32, + 0x7E, 0xDF, 0xAA, 0xFA, 0x71, 0x31, 0xCD, 0x9F, + 0x84, 0x90, 0x70, 0x1C, 0x5A, 0xD4, 0xA7, 0x9C, + 0xFC, 0x1F, 0xE0, 0xFF, 0x42, 0xF4, 0xFB, 0x00, +}; + +uint8_t CTR_KEY5[] = { + 0x02, 0xBF, 0x39, 0x1E, 0xE8, 0xEC, 0xB1, 0x59, + 0xB9, 0x59, 0x61, 0x7B, 0x09, 0x65, 0x27, 0x9B, + 0xF5, 0x9B, 0x60, 0xA7, 0x86, 0xD3, 0xE0, 0xFE, +}; + +uint8_t CTR_CB5[] = { + 0x00, 0x07, 0xBD, 0xFD, 0x5C, 0xBD, 0x60, 0x27, + 0x8D, 0xCC, 0x09, 0x12, +}; + +uint8_t CTR_DATA5[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x22, 0x23, +}; + +uint8_t CTR_RES5[] = { + 0x96, 0x89, 0x3F, 0xC5, 0x5E, 0x5C, 0x72, 0x2F, + 0x54, 0x0B, 0x7D, 0xD1, 0xDD, 0xF7, 0xE7, 0x58, + 0xD2, 0x88, 0xBC, 0x95, 0xC6, 0x91, 0x65, 0x88, + 0x45, 0x36, 0xC8, 0x11, 0x66, 0x2F, 0x21, 0x88, + 0xAB, 0xEE, 0x09, 0x35, +}; + +uint8_t CTR_KEY6[] = { + 0x77, 0x6B, 0xEF, 0xF2, 0x85, 0x1D, 0xB0, 0x6F, + 0x4C, 0x8A, 0x05, 0x42, 0xC8, 0x69, 0x6F, 0x6C, + 0x6A, 0x81, 0xAF, 0x1E, 0xEC, 0x96, 0xB4, 0xD3, + 0x7F, 0xC1, 0xD6, 0x89, 0xE6, 0xC1, 0xC1, 0x04, +}; + +uint8_t CTR_CB6[] = { + 0x00, 0x00, 0x00, 0x60, 0xDB, 0x56, 0x72, 0xC9, + 0x7A, 0xA8, 0xF0, 0xB2, +}; + +uint8_t CTR_DATA6[] = { + 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62, + 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67, +}; + +uint8_t CTR_RES6[] = { + 0x14, 0x5A, 0xD0, 0x1D, 0xBF, 0x82, 0x4E, 0xC7, + 0x56, 0x08, 0x63, 0xDC, 0x71, 0xE3, 0xE0, 0xC0, +}; + +uint8_t CTR_KEY7[] = { + 0xF6, 0xD6, 0x6D, 0x6B, 0xD5, 0x2D, 0x59, 0xBB, + 0x07, 0x96, 0x36, 0x58, 0x79, 0xEF, 0xF8, 0x86, + 0xC6, 0x6D, 0xD5, 0x1A, 0x5B, 0x6A, 0x99, 0x74, + 0x4B, 0x50, 0x59, 0x0C, 0x87, 0xA2, 0x38, 0x84, +}; + +uint8_t CTR_CB7[] = { + 0x00, 0xFA, 0xAC, 0x24, 0xC1, 0x58, 0x5E, 0xF1, + 0x5A, 0x43, 0xD8, 0x75, +}; + +uint8_t CTR_DATA7[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, +}; + +uint8_t CTR_RES7[] = { + 0xF0, 0x5E, 0x23, 0x1B, 0x38, 0x94, 0x61, 0x2C, + 0x49, 0xEE, 0x00, 0x0B, 0x80, 0x4E, 0xB2, 0xA9, + 0xB8, 0x30, 0x6B, 0x50, 0x8F, 0x83, 0x9D, 0x6A, + 0x55, 0x30, 0x83, 0x1D, 0x93, 0x44, 0xAF, 0x1C, +}; + +uint8_t CTR_KEY8[] = { + 0xFF, 0x7A, 0x61, 0x7C, 0xE6, 0x91, 0x48, 0xE4, + 0xF1, 0x72, 0x6E, 0x2F, 0x43, 0x58, 0x1D, 0xE2, + 0xAA, 0x62, 0xD9, 0xF8, 0x05, 0x53, 0x2E, 0xDF, + 0xF1, 0xEE, 0xD6, 0x87, 0xFB, 0x54, 0x15, 0x3D, +}; + +uint8_t CTR_CB8[] = { + 0x00, 0x1C, 0xC5, 0xB7, 0x51, 0xA5, 0x1D, 0x70, + 0xA1, 0xC1, 0x11, 0x48, +}; + +uint8_t CTR_DATA8[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x22, 0x23, +}; + +uint8_t CTR_RES8[] = { + 0xEB, 0x6C, 0x52, 0x82, 0x1D, 0x0B, 0xBB, 0xF7, + 0xCE, 0x75, 0x94, 0x46, 0x2A, 0xCA, 0x4F, 0xAA, + 0xB4, 0x07, 0xDF, 0x86, 0x65, 0x69, 0xFD, 0x07, + 0xF4, 0x8C, 0xC0, 0xB5, 0x83, 0xD6, 0x07, 0x1F, + 0x1E, 0xC0, 0xE6, 0xB8, +}; + +uint8_t *DATA[] = { + CTR_DATA0, CTR_DATA1, CTR_DATA2, CTR_DATA3, CTR_DATA4, + CTR_DATA5, CTR_DATA6, CTR_DATA7, CTR_DATA8, +}; + +size_t DATALEN[] = { + sizeof (CTR_DATA0), sizeof (CTR_DATA1), sizeof (CTR_DATA2), + sizeof (CTR_DATA3), sizeof (CTR_DATA4), sizeof (CTR_DATA5), + sizeof (CTR_DATA6), sizeof (CTR_DATA7), sizeof (CTR_DATA8), +}; + +uint8_t *RES[] = { + CTR_RES0, CTR_RES1, CTR_RES2, CTR_RES3, CTR_RES4, + CTR_RES5, CTR_RES6, CTR_RES7, CTR_RES8, +}; + +size_t RESLEN[] = { + sizeof (CTR_RES0), sizeof (CTR_RES1), sizeof (CTR_RES2), + sizeof (CTR_RES3), sizeof (CTR_RES4), sizeof (CTR_RES5), + sizeof (CTR_RES6), sizeof (CTR_RES7), sizeof (CTR_RES8), +}; + +uint8_t *KEY[] = { + CTR_KEY0, CTR_KEY1, CTR_KEY2, CTR_KEY3, CTR_KEY4, + CTR_KEY5, CTR_KEY6, CTR_KEY7, CTR_KEY8, +}; + +size_t KEYLEN[] = { + sizeof (CTR_KEY0), sizeof (CTR_KEY1), sizeof (CTR_KEY2), + sizeof (CTR_KEY3), sizeof (CTR_KEY4), sizeof (CTR_KEY5), + sizeof (CTR_KEY6), sizeof (CTR_KEY7), sizeof (CTR_KEY8), +}; + +uint8_t *CB[] = { + CTR_CB0, CTR_CB1, CTR_CB2, CTR_CB3, CTR_CB4, + CTR_CB5, CTR_CB6, CTR_CB7, CTR_CB8, +}; + +#ifdef __cplusplus +} +#endif + +#endif /* _AES_CTR_H */ diff --git a/usr/src/test/Makefile b/usr/src/test/crypto-tests/tests/modes/aes/ecb/Makefile similarity index 74% copy from usr/src/test/Makefile copy to usr/src/test/crypto-tests/tests/modes/aes/ecb/Makefile index 304163b79f..00adfa3b43 100644 --- a/usr/src/test/Makefile +++ b/usr/src/test/crypto-tests/tests/modes/aes/ecb/Makefile @@ -11,11 +11,10 @@ # # Copyright (c) 2012 by Delphix. All rights reserved. -# Copyright 2014 Garrett D'Amore +# Copyright 2015 Nexenta Systems, Inc. All rights reserved. # -.PARALLEL: $(SUBDIRS) +PROG = aes_ecb -SUBDIRS = libc-tests os-tests test-runner util-tests zfs-tests - -include Makefile.com +include $(SRC)/cmd/Makefile.cmd +include ../Makefile.subdirs diff --git a/usr/src/test/crypto-tests/tests/modes/aes/ecb/aes_ecb.c b/usr/src/test/crypto-tests/tests/modes/aes/ecb/aes_ecb.c new file mode 100644 index 0000000000..1768349f9b --- /dev/null +++ b/usr/src/test/crypto-tests/tests/modes/aes/ecb/aes_ecb.c @@ -0,0 +1,60 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2016 Nexenta Systems, Inc. All rights reserved. + */ + +#include +#include "cryptotest.h" +#include "aes_ecb.h" + +int +main(void) +{ + int errs = 0; + int i; + uint8_t N[1024]; + cryptotest_t args; + + args.in = ECB_DATA; + args.out = N; + args.param = NULL; + + args.inlen = sizeof (ECB_DATA); + args.outlen = sizeof (N); + args.plen = 0; + + args.mechname = SUN_CKM_AES_ECB; + args.updatelen = 1; + + for (i = 0; i < sizeof (RES) / sizeof (RES[0]); i++) { + args.key = KEY[i]; + args.keylen = KEYLEN[i]; + errs += run_test(&args, RES[i], RESLEN[i], ENCR_FG); + (void) fprintf(stderr, "----------\n"); + } + + (void) fprintf(stderr, "\t\t\t=== decrypt ===\n----------\n\n"); + + for (i = 0; i < sizeof (RES) / sizeof (RES[0]); i++) { + args.key = KEY[i]; + args.in = RES[i]; + args.keylen = KEYLEN[i]; + args.inlen = RESLEN[i]; + errs += run_test(&args, ECB_DATA, sizeof (ECB_DATA), DECR_FG); + (void) fprintf(stderr, "----------\n"); + } + if (errs != 0) + (void) fprintf(stderr, "%d tests failed\n", errs); + + return (errs); +} diff --git a/usr/src/test/crypto-tests/tests/modes/aes/ecb/aes_ecb.h b/usr/src/test/crypto-tests/tests/modes/aes/ecb/aes_ecb.h new file mode 100644 index 0000000000..4c8181c936 --- /dev/null +++ b/usr/src/test/crypto-tests/tests/modes/aes/ecb/aes_ecb.h @@ -0,0 +1,110 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2015 Nexenta Systems, Inc. All rights reserved. + */ + +#ifndef _AES_ECB_H +#define _AES_ECB_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Test vectors + * NIST SP-800-38A Appendix F + */ + +uint8_t ECB_KEY0[] = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, +}; + +uint8_t ECB_DATA[] = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, + 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, + 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10, +}; + +uint8_t ECB_RES0[] = { + 0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, + 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97, + 0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d, + 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf, + 0x43, 0xb1, 0xcd, 0x7f, 0x59, 0x8e, 0xce, 0x23, + 0x88, 0x1b, 0x00, 0xe3, 0xed, 0x03, 0x06, 0x88, + 0x7b, 0x0c, 0x78, 0x5e, 0x27, 0xe8, 0xad, 0x3f, + 0x82, 0x23, 0x20, 0x71, 0x04, 0x72, 0x5d, 0xd4, +}; + +uint8_t ECB_KEY1[] = { + 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, + 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, + 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b, +}; + +uint8_t ECB_RES1[] = { + 0xbd, 0x33, 0x4f, 0x1d, 0x6e, 0x45, 0xf2, 0x5f, + 0xf7, 0x12, 0xa2, 0x14, 0x57, 0x1f, 0xa5, 0xcc, + 0x97, 0x41, 0x04, 0x84, 0x6d, 0x0a, 0xd3, 0xad, + 0x77, 0x34, 0xec, 0xb3, 0xec, 0xee, 0x4e, 0xef, + 0xef, 0x7a, 0xfd, 0x22, 0x70, 0xe2, 0xe6, 0x0a, + 0xdc, 0xe0, 0xba, 0x2f, 0xac, 0xe6, 0x44, 0x4e, + 0x9a, 0x4b, 0x41, 0xba, 0x73, 0x8d, 0x6c, 0x72, + 0xfb, 0x16, 0x69, 0x16, 0x03, 0xc1, 0x8e, 0x0e, +}; + +uint8_t ECB_KEY2[] = { + 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, + 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, + 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, + 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4, +}; + +uint8_t ECB_RES2[] = { + 0xf3, 0xee, 0xd1, 0xbd, 0xb5, 0xd2, 0xa0, 0x3c, + 0x06, 0x4b, 0x5a, 0x7e, 0x3d, 0xb1, 0x81, 0xf8, + 0x59, 0x1c, 0xcb, 0x10, 0xd4, 0x10, 0xed, 0x26, + 0xdc, 0x5b, 0xa7, 0x4a, 0x31, 0x36, 0x28, 0x70, + 0xb6, 0xed, 0x21, 0xb9, 0x9c, 0xa6, 0xf4, 0xf9, + 0xf1, 0x53, 0xe7, 0xb1, 0xbe, 0xaf, 0xed, 0x1d, + 0x23, 0x30, 0x4b, 0x7a, 0x39, 0xf9, 0xf3, 0xff, + 0x06, 0x7d, 0x8d, 0x8f, 0x9e, 0x24, 0xec, 0xc7, +}; + +uint8_t *RES[] = { + ECB_RES0, ECB_RES1, ECB_RES2, +}; + +size_t RESLEN[] = { + sizeof (ECB_RES0), sizeof (ECB_RES1), sizeof (ECB_RES2), +}; + +uint8_t *KEY[] = { + ECB_KEY0, ECB_KEY1, ECB_KEY2, +}; + +size_t KEYLEN[] = { + sizeof (ECB_KEY0), sizeof (ECB_KEY1), sizeof (ECB_KEY2), +}; + +#ifdef __cplusplus +} +#endif + +#endif /* _AES_ECB_H */ diff --git a/usr/src/test/Makefile b/usr/src/test/crypto-tests/tests/modes/aes/gcm/Makefile similarity index 74% copy from usr/src/test/Makefile copy to usr/src/test/crypto-tests/tests/modes/aes/gcm/Makefile index 304163b79f..c480cf13f9 100644 --- a/usr/src/test/Makefile +++ b/usr/src/test/crypto-tests/tests/modes/aes/gcm/Makefile @@ -11,11 +11,10 @@ # # Copyright (c) 2012 by Delphix. All rights reserved. -# Copyright 2014 Garrett D'Amore +# Copyright 2015 Nexenta Systems, Inc. All rights reserved. # -.PARALLEL: $(SUBDIRS) +PROG = aes_gcm -SUBDIRS = libc-tests os-tests test-runner util-tests zfs-tests - -include Makefile.com +include $(SRC)/cmd/Makefile.cmd +include ../Makefile.subdirs diff --git a/usr/src/test/crypto-tests/tests/modes/aes/gcm/aes_gcm.c b/usr/src/test/crypto-tests/tests/modes/aes/gcm/aes_gcm.c new file mode 100644 index 0000000000..764cbba385 --- /dev/null +++ b/usr/src/test/crypto-tests/tests/modes/aes/gcm/aes_gcm.c @@ -0,0 +1,87 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2016 Nexenta Systems, Inc. All rights reserved. + */ + +#include +#include +#include "cryptotest.h" +#include "aes_gcm.h" + +const size_t GCM_SPEC_TAG_LEN = 16; +int +main(void) +{ + int errs = 0; + int i; + uint8_t N[1024]; + size_t taglen = GCM_SPEC_TAG_LEN; + + CK_AES_GCM_PARAMS param; + cryptotest_t args; + + bzero(¶m, sizeof (param)); + param.ulTagBits = taglen*8; + + args.out = N; + args.param = ¶m; + + args.outlen = sizeof (N); + args.plen = sizeof (param); + + args.mechname = SUN_CKM_AES_GCM; + args.updatelen = 1; + + for (i = 0; i < sizeof (DATA) / sizeof (DATA[0]); i++) { + args.in = DATA[i]; + args.key = KEY[i]; + + args.inlen = DATALEN[i]; + args.keylen = KEYLEN[i]; + + param.pIv = IV[i]; + param.ulIvLen = IVLEN[i]; + param.ulIvBits = IVLEN[i]*8; + param.pAAD = AUTH[i]; + param.ulAADLen = AUTHLEN[i]; + + + errs += run_test(&args, RES[i], RESLEN[i], ENCR_FG); + (void) fprintf(stderr, "----------\n"); + } + + (void) fprintf(stderr, "\t\t\t=== decrypt ===\n----------\n\n"); + + for (i = 0; i < sizeof (DATA) / sizeof (DATA[0]); i++) { + args.in = RES[i]; + args.key = KEY[i]; + + args.inlen = RESLEN[i]; + args.keylen = KEYLEN[i]; + + param.pIv = IV[i]; + param.ulIvLen = IVLEN[i]; + param.ulIvBits = IVLEN[i]*8; + param.pAAD = AUTH[i]; + param.ulAADLen = AUTHLEN[i]; + + + errs += run_test(&args, DATA[i], DATALEN[i], DECR_FG); + (void) fprintf(stderr, "----------\n"); + } + + if (errs != 0) + (void) fprintf(stderr, "%d tests failed\n", errs); + + return (errs); +} diff --git a/usr/src/test/crypto-tests/tests/modes/aes/gcm/aes_gcm.h b/usr/src/test/crypto-tests/tests/modes/aes/gcm/aes_gcm.h new file mode 100644 index 0000000000..4537c64e21 --- /dev/null +++ b/usr/src/test/crypto-tests/tests/modes/aes/gcm/aes_gcm.h @@ -0,0 +1,737 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2015 Nexenta Systems, Inc. All rights reserved. + */ + +#ifndef _AES_GCM_H +#define _AES_GCM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Test vectors + * NIST, "The Galois/Counter Mode of Operation (GCM)", Appendix B + * http://csrc.nist.gov/groups/ST/toolkit/ + * BCM/documents/proposedmodes/gcm/gcm-spec.pdf + */ + +uint8_t GCM_KEY0[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +#define GCM_DATA0 NULL + +#define GCM_AUTH0 NULL + +uint8_t GCM_IV0[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, +}; + +uint8_t GCM_RES0[] = { + 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61, + 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a, +}; + +uint8_t GCM_KEY1[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +uint8_t GCM_DATA1[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +#define GCM_AUTH1 NULL + +uint8_t GCM_IV1[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, +}; + +uint8_t GCM_RES1[] = { + 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92, + 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78, + 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd, + 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf, +}; + +uint8_t GCM_KEY2[] = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, +}; + +uint8_t GCM_DATA2[] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, +}; + +#define GCM_AUTH2 NULL + +uint8_t GCM_IV2[] = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88, +}; + +uint8_t GCM_RES2[] = { + 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, + 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, + 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, + 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, + 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, + 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, + 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, + 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85, + 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, + 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4, +}; + +uint8_t GCM_KEY3[] = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, +}; + +uint8_t GCM_DATA3[] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, +}; + +uint8_t GCM_AUTH3[] = { + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2, +}; + +uint8_t GCM_IV3[] = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88, +}; + +uint8_t GCM_RES3[] = { + 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, + 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, + 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, + 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, + 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, + 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, + 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, + 0x3d, 0x58, 0xe0, 0x91, 0x5b, 0xc9, 0x4f, 0xbc, + 0x32, 0x21, 0xa5, 0xdb, 0x94, 0xfa, 0xe9, 0x5a, + 0xe7, 0x12, 0x1a, 0x47, +}; + +uint8_t GCM_KEY4[] = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, +}; + +uint8_t GCM_DATA4[] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, +}; + +uint8_t GCM_AUTH4[] = { + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2, +}; + +uint8_t GCM_IV4[] = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, +}; + +uint8_t GCM_RES4[] = { + 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a, + 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55, + 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8, + 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23, + 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2, + 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42, + 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07, + 0xc2, 0x3f, 0x45, 0x98, 0x36, 0x12, 0xd2, 0xe7, + 0x9e, 0x3b, 0x07, 0x85, 0x56, 0x1b, 0xe1, 0x4a, + 0xac, 0xa2, 0xfc, 0xcb, +}; + +uint8_t GCM_KEY5[] = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, +}; + +uint8_t GCM_DATA5[] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, +}; + +uint8_t GCM_AUTH5[] = { + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2, +}; + +uint8_t GCM_IV5[] = { + 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, + 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, + 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, + 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28, + 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, + 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, + 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57, + 0xa6, 0x37, 0xb3, 0x9b, +}; + +uint8_t GCM_RES5[] = { + 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6, + 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94, + 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8, + 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7, + 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90, + 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f, + 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03, + 0x4c, 0x34, 0xae, 0xe5, 0x61, 0x9c, 0xc5, 0xae, + 0xff, 0xfe, 0x0b, 0xfa, 0x46, 0x2a, 0xf4, 0x3c, + 0x16, 0x99, 0xd0, 0x50, +}; + +uint8_t GCM_KEY6[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +#define GCM_DATA6 NULL + +#define GCM_AUTH6 NULL + +uint8_t GCM_IV6[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, +}; + +uint8_t GCM_RES6[] = { + 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b, + 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35, +}; + +uint8_t GCM_KEY7[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +uint8_t GCM_DATA7[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +#define GCM_AUTH7 NULL + +uint8_t GCM_IV7[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, +}; + +uint8_t GCM_RES7[] = { + 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41, + 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00, + 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab, + 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb, +}; + +uint8_t GCM_KEY8[] = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, +}; + +uint8_t GCM_DATA8[] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, +}; + +#define GCM_AUTH8 NULL + +uint8_t GCM_IV8[] = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88, +}; + +uint8_t GCM_RES8[] = { + 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, + 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, + 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, + 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, + 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, + 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, + 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, + 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56, + 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf, + 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14, +}; + +uint8_t GCM_KEY9[] = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, +}; + +uint8_t GCM_DATA9[] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, +}; + +uint8_t GCM_AUTH9[] = { + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2, +}; + +uint8_t GCM_IV9[] = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88, +}; + +uint8_t GCM_RES9[] = { + 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, + 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, + 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, + 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, + 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, + 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, + 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, + 0xcc, 0xda, 0x27, 0x10, 0x25, 0x19, 0x49, 0x8e, + 0x80, 0xf1, 0x47, 0x8f, 0x37, 0xba, 0x55, 0xbd, + 0x6d, 0x27, 0x61, 0x8c, +}; + +uint8_t GCM_KEY10[] = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, +}; + +uint8_t GCM_DATA10[] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, +}; + +uint8_t GCM_AUTH10[] = { + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2, +}; + +uint8_t GCM_IV10[] = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, +}; + +uint8_t GCM_RES10[] = { + 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54, + 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8, + 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f, + 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57, + 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75, + 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9, + 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f, + 0xa0, 0xf0, 0x62, 0xf7, 0x65, 0xdc, 0xc5, 0x7f, + 0xcf, 0x62, 0x3a, 0x24, 0x09, 0x4f, 0xcc, 0xa4, + 0x0d, 0x35, 0x33, 0xf8, +}; + +uint8_t GCM_KEY11[] = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, +}; + +uint8_t GCM_DATA11[] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, +}; + +uint8_t GCM_AUTH11[] = { + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2, +}; + +uint8_t GCM_IV11[] = { + 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, + 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, + 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, + 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28, + 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, + 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, + 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57, + 0xa6, 0x37, 0xb3, 0x9b, +}; + +uint8_t GCM_RES11[] = { + 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c, + 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff, + 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef, + 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45, + 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9, + 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3, + 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7, + 0xe9, 0xb7, 0x37, 0x3b, 0xdc, 0xf5, 0x66, 0xff, + 0x29, 0x1c, 0x25, 0xbb, 0xb8, 0x56, 0x8f, 0xc3, + 0xd3, 0x76, 0xa6, 0xd9, +}; + +uint8_t GCM_KEY12[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +#define GCM_DATA12 NULL + +#define GCM_AUTH12 NULL + +uint8_t GCM_IV12[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, +}; + +uint8_t GCM_RES12[] = { + 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9, + 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b, +}; + +uint8_t GCM_KEY13[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +uint8_t GCM_DATA13[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +#define GCM_AUTH13 NULL + +uint8_t GCM_IV13[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, +}; + +uint8_t GCM_RES13[] = { + 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e, + 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18, + 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0, + 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19, +}; + +uint8_t GCM_KEY14[] = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, +}; + +uint8_t GCM_DATA14[] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, +}; + +#define GCM_AUTH14 NULL + +uint8_t GCM_IV14[] = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88, +}; + +uint8_t GCM_RES14[] = { + 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, + 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, + 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, + 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, + 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, + 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, + 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, + 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad, + 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd, + 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c, +}; + +uint8_t GCM_KEY15[] = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, +}; + +uint8_t GCM_DATA15[] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, +}; + +uint8_t GCM_AUTH15[] = { + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2, +}; + +uint8_t GCM_IV15[] = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88, +}; + +uint8_t GCM_RES15[] = { + 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, + 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, + 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, + 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, + 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, + 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, + 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, + 0xbc, 0xc9, 0xf6, 0x62, 0x76, 0xfc, 0x6e, 0xce, + 0x0f, 0x4e, 0x17, 0x68, 0xcd, 0xdf, 0x88, 0x53, + 0xbb, 0x2d, 0x55, 0x1b, +}; + +uint8_t GCM_KEY16[] = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, +}; + +uint8_t GCM_DATA16[] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, +}; + +uint8_t GCM_AUTH16[] = { + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2, +}; + +uint8_t GCM_IV16[] = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, +}; + +uint8_t GCM_RES16[] = { + 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32, + 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb, + 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa, + 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0, + 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0, + 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78, + 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99, + 0xf4, 0x7c, 0x9b, 0x1f, 0x3a, 0x33, 0x7d, 0xbf, + 0x46, 0xa7, 0x92, 0xc4, 0x5e, 0x45, 0x49, 0x13, + 0xfe, 0x2e, 0xa8, 0xf2, +}; + +uint8_t GCM_KEY17[] = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, +}; + +uint8_t GCM_DATA17[] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, +}; + +uint8_t GCM_AUTH17[] = { + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2, +}; + +uint8_t GCM_IV17[] = { + 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, + 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, + 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, + 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28, + 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, + 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, + 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57, + 0xa6, 0x37, 0xb3, 0x9b, +}; + +uint8_t GCM_RES17[] = { + 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1, + 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20, + 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19, + 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4, + 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45, + 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde, + 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e, + 0x44, 0xae, 0x7e, 0x3f, 0xa4, 0x4a, 0x82, 0x66, + 0xee, 0x1c, 0x8e, 0xb0, 0xc8, 0xb5, 0xd4, 0xcf, + 0x5a, 0xe9, 0xf1, 0x9a, +}; + + +uint8_t *DATA[] = { + GCM_DATA0, GCM_DATA1, GCM_DATA2, GCM_DATA3, GCM_DATA4, GCM_DATA5, + GCM_DATA6, GCM_DATA7, GCM_DATA8, GCM_DATA9, GCM_DATA10, GCM_DATA11, + GCM_DATA12, GCM_DATA13, GCM_DATA14, GCM_DATA15, GCM_DATA16, GCM_DATA17, +}; + +size_t DATALEN[] = { + 0, sizeof (GCM_DATA1), sizeof (GCM_DATA2), sizeof (GCM_DATA3), + sizeof (GCM_DATA4), sizeof (GCM_DATA5), 0, sizeof (GCM_DATA7), + sizeof (GCM_DATA8), sizeof (GCM_DATA9), sizeof (GCM_DATA10), + sizeof (GCM_DATA11), 0, sizeof (GCM_DATA13), sizeof (GCM_DATA14), + sizeof (GCM_DATA15), sizeof (GCM_DATA16), + sizeof (GCM_DATA17), +}; + +uint8_t *RES[] = { + GCM_RES0, GCM_RES1, GCM_RES2, GCM_RES3, GCM_RES4, GCM_RES5, + GCM_RES6, GCM_RES7, GCM_RES8, GCM_RES9, GCM_RES10, GCM_RES11, + GCM_RES12, GCM_RES13, GCM_RES14, GCM_RES15, GCM_RES16, GCM_RES17, +}; + +size_t RESLEN[] = { + sizeof (GCM_RES0), sizeof (GCM_RES1), sizeof (GCM_RES2), + sizeof (GCM_RES3), sizeof (GCM_RES4), sizeof (GCM_RES5), + sizeof (GCM_RES6), sizeof (GCM_RES7), sizeof (GCM_RES8), + sizeof (GCM_RES9), sizeof (GCM_RES10), sizeof (GCM_RES11), + sizeof (GCM_RES12), sizeof (GCM_RES13), sizeof (GCM_RES14), + sizeof (GCM_RES15), sizeof (GCM_RES16), sizeof (GCM_RES17), +}; + +uint8_t *IV[] = { + GCM_IV0, GCM_IV1, GCM_IV2, GCM_IV3, GCM_IV4, GCM_IV5, + GCM_IV6, GCM_IV7, GCM_IV8, GCM_IV9, GCM_IV10, GCM_IV11, + GCM_IV12, GCM_IV13, GCM_IV14, GCM_IV15, GCM_IV16, GCM_IV17, +}; + +size_t IVLEN[] = { + sizeof (GCM_IV0), sizeof (GCM_IV1), sizeof (GCM_IV2), + sizeof (GCM_IV3), sizeof (GCM_IV4), sizeof (GCM_IV5), + sizeof (GCM_IV6), sizeof (GCM_IV7), sizeof (GCM_IV8), + sizeof (GCM_IV9), sizeof (GCM_IV10), sizeof (GCM_IV11), + sizeof (GCM_IV12), sizeof (GCM_IV13), sizeof (GCM_IV14), + sizeof (GCM_IV15), sizeof (GCM_IV16), sizeof (GCM_IV17), +}; + +uint8_t *AUTH[] = { + GCM_AUTH0, GCM_AUTH1, GCM_AUTH2, GCM_AUTH3, GCM_AUTH4, GCM_AUTH5, + GCM_AUTH6, GCM_AUTH7, GCM_AUTH8, GCM_AUTH9, GCM_AUTH10, GCM_AUTH11, + GCM_AUTH12, GCM_AUTH13, GCM_AUTH14, GCM_AUTH15, GCM_AUTH16, GCM_AUTH17, +}; + +size_t AUTHLEN[] = { + 0, 0, 0, sizeof (GCM_AUTH3), sizeof (GCM_AUTH4), sizeof (GCM_AUTH5), + 0, 0, 0, sizeof (GCM_AUTH9), sizeof (GCM_AUTH10), sizeof (GCM_AUTH11), + 0, 0, 0, sizeof (GCM_AUTH15), sizeof (GCM_AUTH16), sizeof (GCM_AUTH17), +}; + +uint8_t *KEY[] = { + GCM_KEY0, GCM_KEY1, GCM_KEY2, GCM_KEY3, GCM_KEY4, GCM_KEY5, + GCM_KEY6, GCM_KEY7, GCM_KEY8, GCM_KEY9, GCM_KEY10, GCM_KEY11, + GCM_KEY12, GCM_KEY13, GCM_KEY14, GCM_KEY15, GCM_KEY16, GCM_KEY17, +}; + +size_t KEYLEN[] = { + sizeof (GCM_KEY0), sizeof (GCM_KEY1), sizeof (GCM_KEY2), + sizeof (GCM_KEY3), sizeof (GCM_KEY4), sizeof (GCM_KEY5), + sizeof (GCM_KEY6), sizeof (GCM_KEY7), sizeof (GCM_KEY8), + sizeof (GCM_KEY9), sizeof (GCM_KEY10), sizeof (GCM_KEY11), + sizeof (GCM_KEY12), sizeof (GCM_KEY13), sizeof (GCM_KEY14), + sizeof (GCM_KEY15), sizeof (GCM_KEY16), sizeof (GCM_KEY17), +}; + +#ifdef __cplusplus +} +#endif + +#endif /* _AES_GCM_H */ diff --git a/usr/src/uts/common/crypto/core/kcf_cryptoadm.c b/usr/src/uts/common/crypto/core/kcf_cryptoadm.c index 518b0bc722..54e7c533ad 100644 --- a/usr/src/uts/common/crypto/core/kcf_cryptoadm.c +++ b/usr/src/uts/common/crypto/core/kcf_cryptoadm.c @@ -73,9 +73,11 @@ static void kcf_soft_config_dump(char *message); * (excluding final NUL-character string element). */ static int -count_mechanisms(crypto_mech_name_t mechs[]) { +count_mechanisms(crypto_mech_name_t mechs[]) +{ int count; - for (count = 0; mechs[count][0] != '\0'; ++count); + for (count = 0; mechs[count][0] != '\0'; ++count) + ; return (count); } @@ -100,7 +102,7 @@ kcf_soft_config_init(void) * # /etc/crypto/kcf.conf * des:supportedlist=CKM_DES_CBC,CKM_DES_ECB,CKM_DES3_CBC,CKM_DES3_ECB * aes:supportedlist=CKM_AES_ECB,CKM_AES_CBC,CKM_AES_CTR,CKM_AES_CCM,\ - * CKM_AES_GCM,CKM_AES_GMAC + * CKM_AES_GCM,CKM_AES_GMAC,CKM_AES_CMAC * arcfour:supportedlist=CKM_RC4 * blowfish:supportedlist=CKM_BLOWFISH_ECB,CKM_BLOWFISH_CBC * ecc:supportedlist=CKM_EC_KEY_PAIR_GEN,CKM_ECDH1_DERIVE,CKM_ECDSA,\ @@ -134,7 +136,7 @@ kcf_soft_config_init(void) "CKM_DES_CBC", "CKM_DES_ECB", "CKM_DES3_CBC", "CKM_DES3_ECB", ""}; static crypto_mech_name_t aes_mechs[] = { "CKM_AES_ECB", "CKM_AES_CBC", "CKM_AES_CTR", "CKM_AES_CCM", - "CKM_AES_GCM", "CKM_AES_GMAC", ""}; + "CKM_AES_GCM", "CKM_AES_GMAC", "CKM_AES_CMAC", ""}; static crypto_mech_name_t arcfour_mechs[] = { "CKM_RC4", ""}; static crypto_mech_name_t blowfish_mechs[] = { @@ -250,7 +252,7 @@ kcf_soft_config_dump(char *message) */ static void filter_providers(uint_t count, kcf_provider_desc_t **provider_array, - char *skip_providers, int *mech_counts, int *new_count) + char *skip_providers, int *mech_counts, int *new_count) { int i, j; kcf_provider_desc_t *prov1, *prov2; diff --git a/usr/src/uts/common/crypto/core/kcf_mech_tabs.c b/usr/src/uts/common/crypto/core/kcf_mech_tabs.c index 099f73a291..6d81267d50 100644 --- a/usr/src/uts/common/crypto/core/kcf_mech_tabs.c +++ b/usr/src/uts/common/crypto/core/kcf_mech_tabs.c @@ -224,7 +224,7 @@ kcf_init_mech_tabs() kcf_cipher_mechs_tab[8].me_threshold = kcf_rc4_threshold; - /* 5 HMACs */ + /* 6 HMACs */ (void) strncpy(kcf_mac_mechs_tab[0].me_name, SUN_CKM_MD5_HMAC, CRYPTO_MAX_MECH_NAME); kcf_mac_mechs_tab[0].me_threshold = kcf_md5_threshold; @@ -245,6 +245,10 @@ kcf_init_mech_tabs() CRYPTO_MAX_MECH_NAME); kcf_mac_mechs_tab[4].me_threshold = kcf_sha1_threshold; + (void) strncpy(kcf_mac_mechs_tab[5].me_name, SUN_CKM_AES_CMAC, + CRYPTO_MAX_MECH_NAME); + kcf_mac_mechs_tab[5].me_threshold = kcf_sha1_threshold; + /* 1 random number generation pseudo mechanism */ (void) strncpy(kcf_misc_mechs_tab[0].me_name, SUN_RANDOM, CRYPTO_MAX_MECH_NAME); diff --git a/usr/src/uts/common/crypto/core/kcf_prov_lib.c b/usr/src/uts/common/crypto/core/kcf_prov_lib.c index 59f7ea1e70..65322bfb3c 100644 --- a/usr/src/uts/common/crypto/core/kcf_prov_lib.c +++ b/usr/src/uts/common/crypto/core/kcf_prov_lib.c @@ -35,204 +35,6 @@ #include /* - * Utility routine to apply the command, 'cmd', to the - * data in the uio structure. - */ -int -crypto_uio_data(crypto_data_t *data, uchar_t *buf, int len, cmd_type_t cmd, - void *digest_ctx, void (*update)()) -{ - uio_t *uiop = data->cd_uio; - off_t offset = data->cd_offset; - size_t length = len; - uint_t vec_idx; - size_t cur_len; - uchar_t *datap; - - ASSERT(data->cd_format == CRYPTO_DATA_UIO); - if (uiop->uio_segflg != UIO_SYSSPACE) { - return (CRYPTO_ARGUMENTS_BAD); - } - - /* - * Jump to the first iovec containing data to be - * processed. - */ - for (vec_idx = 0; vec_idx < uiop->uio_iovcnt && - offset >= uiop->uio_iov[vec_idx].iov_len; - offset -= uiop->uio_iov[vec_idx++].iov_len) - ; - - if (vec_idx == uiop->uio_iovcnt) { - /* - * The caller specified an offset that is larger than - * the total size of the buffers it provided. - */ - return (CRYPTO_DATA_LEN_RANGE); - } - - while (vec_idx < uiop->uio_iovcnt && length > 0) { - cur_len = MIN(uiop->uio_iov[vec_idx].iov_len - - offset, length); - - datap = (uchar_t *)(uiop->uio_iov[vec_idx].iov_base + - offset); - switch (cmd) { - case COPY_FROM_DATA: - bcopy(datap, buf, cur_len); - buf += cur_len; - break; - case COPY_TO_DATA: - bcopy(buf, datap, cur_len); - buf += cur_len; - break; - case COMPARE_TO_DATA: - if (bcmp(datap, buf, cur_len)) - return (CRYPTO_SIGNATURE_INVALID); - buf += cur_len; - break; - case MD5_DIGEST_DATA: - case SHA1_DIGEST_DATA: - case SHA2_DIGEST_DATA: - case GHASH_DATA: - update(digest_ctx, datap, cur_len); - break; - } - - length -= cur_len; - vec_idx++; - offset = 0; - } - - if (vec_idx == uiop->uio_iovcnt && length > 0) { - /* - * The end of the specified iovec's was reached but - * the length requested could not be processed. - */ - switch (cmd) { - case COPY_TO_DATA: - data->cd_length = len; - return (CRYPTO_BUFFER_TOO_SMALL); - default: - return (CRYPTO_DATA_LEN_RANGE); - } - } - - return (CRYPTO_SUCCESS); -} - -/* - * Utility routine to apply the command, 'cmd', to the - * data in the mblk structure. - */ -int -crypto_mblk_data(crypto_data_t *data, uchar_t *buf, int len, cmd_type_t cmd, - void *digest_ctx, void (*update)()) -{ - off_t offset = data->cd_offset; - size_t length = len; - mblk_t *mp; - size_t cur_len; - uchar_t *datap; - - ASSERT(data->cd_format == CRYPTO_DATA_MBLK); - /* - * Jump to the first mblk_t containing data to be processed. - */ - for (mp = data->cd_mp; mp != NULL && offset >= MBLKL(mp); - offset -= MBLKL(mp), mp = mp->b_cont) - ; - if (mp == NULL) { - /* - * The caller specified an offset that is larger - * than the total size of the buffers it provided. - */ - return (CRYPTO_DATA_LEN_RANGE); - } - - /* - * Now do the processing on the mblk chain. - */ - while (mp != NULL && length > 0) { - cur_len = MIN(MBLKL(mp) - offset, length); - - datap = (uchar_t *)(mp->b_rptr + offset); - switch (cmd) { - case COPY_FROM_DATA: - bcopy(datap, buf, cur_len); - buf += cur_len; - break; - case COPY_TO_DATA: - bcopy(buf, datap, cur_len); - buf += cur_len; - break; - case COMPARE_TO_DATA: - if (bcmp(datap, buf, cur_len)) - return (CRYPTO_SIGNATURE_INVALID); - buf += cur_len; - break; - case MD5_DIGEST_DATA: - case SHA1_DIGEST_DATA: - case SHA2_DIGEST_DATA: - case GHASH_DATA: - update(digest_ctx, datap, cur_len); - break; - } - - length -= cur_len; - offset = 0; - mp = mp->b_cont; - } - - if (mp == NULL && length > 0) { - /* - * The end of the mblk was reached but the length - * requested could not be processed. - */ - switch (cmd) { - case COPY_TO_DATA: - data->cd_length = len; - return (CRYPTO_BUFFER_TOO_SMALL); - default: - return (CRYPTO_DATA_LEN_RANGE); - } - } - - return (CRYPTO_SUCCESS); -} - -/* - * Utility routine to copy a buffer to a crypto_data structure. - */ -int -crypto_put_output_data(uchar_t *buf, crypto_data_t *output, int len) -{ - switch (output->cd_format) { - case CRYPTO_DATA_RAW: - if (output->cd_raw.iov_len < len) { - output->cd_length = len; - return (CRYPTO_BUFFER_TOO_SMALL); - } - bcopy(buf, (uchar_t *)(output->cd_raw.iov_base + - output->cd_offset), len); - break; - - case CRYPTO_DATA_UIO: - return (crypto_uio_data(output, buf, len, - COPY_TO_DATA, NULL, NULL)); - - case CRYPTO_DATA_MBLK: - return (crypto_mblk_data(output, buf, len, - COPY_TO_DATA, NULL, NULL)); - - default: - return (CRYPTO_ARGUMENTS_BAD); - } - - return (CRYPTO_SUCCESS); -} - -/* * Utility routine to get data from a crypto_data structure. * * '*dptr' contains a pointer to a buffer on return. 'buf' diff --git a/usr/src/uts/common/crypto/io/aes.c b/usr/src/uts/common/crypto/io/aes.c index 6a30f0b7bc..a008927cbb 100644 --- a/usr/src/uts/common/crypto/io/aes.c +++ b/usr/src/uts/common/crypto/io/aes.c @@ -20,6 +20,7 @@ */ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2017 Nexenta Systems, Inc. All rights reserved. */ /* @@ -70,6 +71,11 @@ static crypto_mech_info_t aes_mech_info_tab[] = { CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC, AES_MIN_KEY_BYTES, AES_MAX_KEY_BYTES, CRYPTO_KEYSIZE_UNIT_IN_BYTES}, + /* AES_CMAC */ + {SUN_CKM_AES_CMAC, AES_CMAC_MECH_INFO_TYPE, + CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | + CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC | + AES_MIN_KEY_BYTES, AES_MAX_KEY_BYTES, CRYPTO_KEYSIZE_UNIT_IN_BYTES}, /* AES_CTR */ {SUN_CKM_AES_CTR, AES_CTR_MECH_INFO_TYPE, CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | @@ -148,6 +154,14 @@ static crypto_cipher_ops_t aes_cipher_ops = { aes_decrypt_atomic }; +static int aes_mac_init(crypto_ctx_t *, crypto_mechanism_t *, + crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); +static int aes_mac(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, + crypto_req_handle_t); +static int aes_mac_update(crypto_ctx_t *, crypto_data_t *, + crypto_req_handle_t); +static int aes_mac_final(crypto_ctx_t *, crypto_data_t *, + crypto_req_handle_t); static int aes_mac_atomic(crypto_provider_handle_t, crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); @@ -156,10 +170,10 @@ static int aes_mac_verify_atomic(crypto_provider_handle_t, crypto_session_id_t, crypto_spi_ctx_template_t, crypto_req_handle_t); static crypto_mac_ops_t aes_mac_ops = { - NULL, - NULL, - NULL, - NULL, + aes_mac_init, + aes_mac, + aes_mac_update, + aes_mac_final, aes_mac_atomic, aes_mac_verify_atomic }; @@ -264,6 +278,10 @@ aes_check_mech_param(crypto_mechanism_t *mechanism, aes_ctx_t **ctx, int kmflag) param_len = AES_BLOCK_LEN; alloc_fun = cbc_alloc_ctx; break; + case AES_CMAC_MECH_INFO_TYPE: + param_required = B_FALSE; + alloc_fun = cmac_alloc_ctx; + break; case AES_CTR_MECH_INFO_TYPE: param_len = sizeof (CK_AES_CTR_PARAMS); alloc_fun = ctr_alloc_ctx; @@ -336,14 +354,16 @@ aes_provider_status(crypto_provider_handle_t provider, uint_t *status) static int aes_encrypt_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_spi_ctx_template_t template, - crypto_req_handle_t req) { + crypto_req_handle_t req) +{ return (aes_common_init(ctx, mechanism, key, template, req, B_TRUE)); } static int aes_decrypt_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_spi_ctx_template_t template, - crypto_req_handle_t req) { + crypto_req_handle_t req) +{ return (aes_common_init(ctx, mechanism, key, template, req, B_FALSE)); } @@ -417,8 +437,9 @@ aes_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext, * For block ciphers, plaintext must be a multiple of AES block size. * This test is only valid for ciphers whose blocksize is a power of 2. */ - if (((aes_ctx->ac_flags & (CTR_MODE|CCM_MODE|GCM_MODE|GMAC_MODE)) - == 0) && (plaintext->cd_length & (AES_BLOCK_LEN - 1)) != 0) + if (((aes_ctx->ac_flags & (CMAC_MODE|CTR_MODE|CCM_MODE| + GCM_MODE|GMAC_MODE)) == 0) && + (plaintext->cd_length & (AES_BLOCK_LEN - 1)) != 0) return (CRYPTO_DATA_LEN_RANGE); AES_ARG_INPLACE(plaintext, ciphertext); @@ -427,13 +448,16 @@ aes_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext, * We need to just return the length needed to store the output. * We should not destroy the context for the following case. */ - switch (aes_ctx->ac_flags & (CCM_MODE|GCM_MODE|GMAC_MODE)) { + switch (aes_ctx->ac_flags & (CMAC_MODE|CCM_MODE|GCM_MODE|GMAC_MODE)) { case CCM_MODE: length_needed = plaintext->cd_length + aes_ctx->ac_mac_len; break; case GCM_MODE: length_needed = plaintext->cd_length + aes_ctx->ac_tag_len; break; + case CMAC_MODE: + length_needed = AES_BLOCK_LEN; + break; case GMAC_MODE: if (plaintext->cd_length != 0) return (CRYPTO_ARGUMENTS_BAD); @@ -507,6 +531,12 @@ aes_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext, ciphertext->cd_offset - saved_offset; } ciphertext->cd_offset = saved_offset; + } else if (aes_ctx->ac_flags & CMAC_MODE) { + /* cmac_update doesn't store data */ + ciphertext->cd_length = saved_length; + ret = cmac_mode_final((cbc_ctx_t *)aes_ctx, ciphertext, + aes_encrypt_block, aes_xor_block); + aes_ctx->ac_remainder_len = 0; } ASSERT(aes_ctx->ac_remainder_len == 0); @@ -650,8 +680,12 @@ aes_encrypt_update(crypto_ctx_t *ctx, crypto_data_t *plaintext, out_len += plaintext->cd_length; out_len &= ~(AES_BLOCK_LEN - 1); - /* return length needed to store the output */ - if (ciphertext->cd_length < out_len) { + /* + * return length needed to store the output. + * CMAC stores its output in a local buffer until *_final. + */ + if ((aes_ctx->ac_flags & CMAC_MODE) == 0 && + ciphertext->cd_length < out_len) { ciphertext->cd_length = out_len; return (CRYPTO_BUFFER_TOO_SMALL); } @@ -833,6 +867,12 @@ aes_encrypt_final(crypto_ctx_t *ctx, crypto_data_t *data, } data->cd_length = data->cd_offset - saved_offset; data->cd_offset = saved_offset; + } else if (aes_ctx->ac_flags & CMAC_MODE) { + ret = cmac_mode_final((cbc_ctx_t *)aes_ctx, data, + aes_encrypt_block, aes_xor_block); + if (ret != CRYPTO_SUCCESS) + return (ret); + data->cd_length = AES_BLOCK_LEN; } else { /* * There must be no unprocessed plaintext. @@ -970,7 +1010,7 @@ aes_encrypt_atomic(crypto_provider_handle_t provider, AES_ARG_INPLACE(plaintext, ciphertext); /* - * CTR, CCM, GCM, and GMAC modes do not require that plaintext + * CTR, CCM, CMAC, GCM, and GMAC modes do not require that plaintext * be a multiple of AES block size. */ switch (mechanism->cm_type) { @@ -978,6 +1018,7 @@ aes_encrypt_atomic(crypto_provider_handle_t provider, case AES_CCM_MECH_INFO_TYPE: case AES_GCM_MECH_INFO_TYPE: case AES_GMAC_MECH_INFO_TYPE: + case AES_CMAC_MECH_INFO_TYPE: break; default: if ((plaintext->cd_length & (AES_BLOCK_LEN - 1)) != 0) @@ -1005,6 +1046,9 @@ aes_encrypt_atomic(crypto_provider_handle_t provider, case AES_GCM_MECH_INFO_TYPE: length_needed = plaintext->cd_length + aes_ctx.ac_tag_len; break; + case AES_CMAC_MECH_INFO_TYPE: + length_needed = AES_BLOCK_LEN; + break; default: length_needed = plaintext->cd_length; } @@ -1062,6 +1106,12 @@ aes_encrypt_atomic(crypto_provider_handle_t provider, if (ret != CRYPTO_SUCCESS) goto out; } + } else if (mechanism->cm_type == AES_CMAC_MECH_INFO_TYPE) { + ret = cmac_mode_final((cbc_ctx_t *)&aes_ctx, + ciphertext, aes_encrypt_block, + aes_xor_block); + if (ret != CRYPTO_SUCCESS) + goto out; } else { ASSERT(aes_ctx.ac_remainder_len == 0); } @@ -1262,6 +1312,7 @@ aes_create_ctx_template(crypto_provider_handle_t provider, if (mechanism->cm_type != AES_ECB_MECH_INFO_TYPE && mechanism->cm_type != AES_CBC_MECH_INFO_TYPE && + mechanism->cm_type != AES_CMAC_MECH_INFO_TYPE && mechanism->cm_type != AES_CTR_MECH_INFO_TYPE && mechanism->cm_type != AES_CCM_MECH_INFO_TYPE && mechanism->cm_type != AES_GCM_MECH_INFO_TYPE && @@ -1343,6 +1394,9 @@ aes_common_init_ctx(aes_ctx_t *aes_ctx, crypto_spi_ctx_template_t *template, rv = cbc_init_ctx((cbc_ctx_t *)aes_ctx, mechanism->cm_param, mechanism->cm_param_len, AES_BLOCK_LEN, aes_copy_block64); break; + case AES_CMAC_MECH_INFO_TYPE: + rv = cmac_init_ctx((cbc_ctx_t *)aes_ctx, AES_BLOCK_LEN); + break; case AES_CTR_MECH_INFO_TYPE: { CK_AES_CTR_PARAMS *pp; @@ -1428,6 +1482,44 @@ process_gmac_mech(crypto_mechanism_t *mech, crypto_data_t *data, } static int +aes_mac_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, + crypto_key_t *key, crypto_spi_ctx_template_t template, + crypto_req_handle_t req) +{ + return (aes_encrypt_init(ctx, mechanism, + key, template, req)); +} + +static int +aes_mac(crypto_ctx_t *ctx, crypto_data_t *plaintext, crypto_data_t *ciphertext, + crypto_req_handle_t req) +{ + return (aes_encrypt(ctx, plaintext, ciphertext, req)); +} + +static int +aes_mac_update(crypto_ctx_t *ctx, crypto_data_t *data, + crypto_req_handle_t req) +{ + crypto_data_t out; + uint8_t block[AES_BLOCK_LEN]; + out.cd_format = CRYPTO_DATA_RAW; + out.cd_offset = 0; + out.cd_length = sizeof (block); + out.cd_miscdata = NULL; + out.cd_raw.iov_base = (void *)block; + out.cd_raw.iov_len = sizeof (block); + + return (aes_encrypt_update(ctx, data, &out, req)); +} + +static int +aes_mac_final(crypto_ctx_t *ctx, crypto_data_t *mac, crypto_req_handle_t req) +{ + return (aes_encrypt_final(ctx, mac, req)); +} + +static int aes_mac_atomic(crypto_provider_handle_t provider, crypto_session_id_t session_id, crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac, @@ -1437,16 +1529,21 @@ aes_mac_atomic(crypto_provider_handle_t provider, crypto_mechanism_t gcm_mech; int rv; - if ((rv = process_gmac_mech(mechanism, data, &gcm_params)) - != CRYPTO_SUCCESS) - return (rv); + if (mechanism->cm_type == AES_GMAC_MECH_INFO_TYPE) { + if ((rv = process_gmac_mech(mechanism, data, &gcm_params)) + != CRYPTO_SUCCESS) + return (rv); - gcm_mech.cm_type = AES_GCM_MECH_INFO_TYPE; - gcm_mech.cm_param_len = sizeof (CK_AES_GCM_PARAMS); - gcm_mech.cm_param = (char *)&gcm_params; + gcm_mech.cm_type = AES_GCM_MECH_INFO_TYPE; + gcm_mech.cm_param_len = sizeof (CK_AES_GCM_PARAMS); + gcm_mech.cm_param = (char *)&gcm_params; - return (aes_encrypt_atomic(provider, session_id, &gcm_mech, - key, &null_crypto_data, mac, template, req)); + return (aes_encrypt_atomic(provider, session_id, &gcm_mech, + key, &null_crypto_data, mac, template, req)); + } + /* CMAC */ + return (aes_encrypt_atomic(provider, session_id, mechanism, + key, data, mac, template, req)); } static int @@ -1457,16 +1554,42 @@ aes_mac_verify_atomic(crypto_provider_handle_t provider, { CK_AES_GCM_PARAMS gcm_params; crypto_mechanism_t gcm_mech; + crypto_data_t data_mac; + char buf[AES_BLOCK_LEN]; int rv; - if ((rv = process_gmac_mech(mechanism, data, &gcm_params)) - != CRYPTO_SUCCESS) + if (mechanism->cm_type == AES_GMAC_MECH_INFO_TYPE) { + if ((rv = process_gmac_mech(mechanism, data, &gcm_params)) + != CRYPTO_SUCCESS) + return (rv); + + gcm_mech.cm_type = AES_GCM_MECH_INFO_TYPE; + gcm_mech.cm_param_len = sizeof (CK_AES_GCM_PARAMS); + gcm_mech.cm_param = (char *)&gcm_params; + + return (aes_decrypt_atomic(provider, session_id, &gcm_mech, + key, mac, &null_crypto_data, template, req)); + } + + /* CMAC */ + + data_mac.cd_format = CRYPTO_DATA_RAW; + data_mac.cd_offset = 0; + data_mac.cd_length = AES_BLOCK_LEN; + data_mac.cd_miscdata = NULL; + data_mac.cd_raw.iov_base = (void *) buf; + data_mac.cd_raw.iov_len = AES_BLOCK_LEN; + + rv = aes_encrypt_atomic(provider, session_id, &gcm_mech, + key, data, &data_mac, template, req); + + if (rv != CRYPTO_SUCCESS) return (rv); - gcm_mech.cm_type = AES_GCM_MECH_INFO_TYPE; - gcm_mech.cm_param_len = sizeof (CK_AES_GCM_PARAMS); - gcm_mech.cm_param = (char *)&gcm_params; + /* should use get_input_data for mac? */ + if (bcmp(buf, mac->cd_raw.iov_base + mac->cd_offset, + AES_BLOCK_LEN) != 0) + return (CRYPTO_INVALID_MAC); - return (aes_decrypt_atomic(provider, session_id, &gcm_mech, - key, mac, &null_crypto_data, template, req)); + return (CRYPTO_SUCCESS); } diff --git a/usr/src/uts/common/crypto/io/crypto.c b/usr/src/uts/common/crypto/io/crypto.c index 31947ae130..812c624d66 100644 --- a/usr/src/uts/common/crypto/io/crypto.c +++ b/usr/src/uts/common/crypto/io/crypto.c @@ -20,6 +20,7 @@ */ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2015 Nexenta Systems, Inc. All rights reserved. */ @@ -112,6 +113,12 @@ static int crypto_free_find_ctx(crypto_session_data_t *); static int crypto_get_provider_list(crypto_minor_t *, uint_t *, crypto_provider_entry_t **, boolean_t); +static int crypto_create_provider_session(crypto_minor_t *, + kcf_provider_desc_t *, crypto_session_id_t, crypto_provider_session_t **, + kcf_provider_desc_t *); +static int crypto_create_session_ptr(crypto_minor_t *, kcf_provider_desc_t *, + crypto_provider_session_t *, crypto_session_id_t *); + /* number of minor numbers to allocate at a time */ #define CRYPTO_MINOR_CHUNK 16 @@ -221,6 +228,10 @@ static kcf_lock_withpad_t *crypto_locks; crypto_cancel_ctx((sp)->sd_verify_recover_ctx); \ (sp)->sd_verify_recover_ctx = NULL; \ } \ + if ((sp)->sd_mac_ctx != NULL) { \ + crypto_cancel_ctx((sp)->sd_mac_ctx); \ + (sp)->sd_mac_ctx = NULL; \ + } \ } #define CRYPTO_DECREMENT_RCTL(val) if ((val) != 0) { \ @@ -1700,7 +1711,7 @@ crypto_get_provider_session(crypto_minor_t *cm, { kcf_provider_desc_t *pd, *real_provider; kcf_req_params_t params; - crypto_provider_session_t *ps, *new_ps; + crypto_provider_session_t *ps; crypto_session_id_t provider_session_id = 0; int rv; @@ -1746,9 +1757,6 @@ again: } } - /* allocate crypto_provider_session structure */ - new_ps = kmem_zalloc(sizeof (crypto_provider_session_t), KM_SLEEP); - /* * Check if someone opened a session to the provider * while we dropped the lock. @@ -1757,7 +1765,6 @@ again: for (ps = cm->cm_provider_session; ps != NULL; ps = ps->ps_next) { if (ps->ps_provider == pd) { mutex_exit(&cm->cm_lock); - kmem_free(new_ps, sizeof (crypto_provider_session_t)); if (real_provider != NULL) { KCF_WRAP_SESSION_OPS_PARAMS(¶ms, KCF_OP_SESSION_CLOSE, NULL, @@ -1773,18 +1780,32 @@ again: } } + return (crypto_create_provider_session(cm, pd, provider_session_id, + output_ps, real_provider)); +} + +static int +crypto_create_provider_session(crypto_minor_t *cm, kcf_provider_desc_t *pd, + crypto_session_id_t sid, crypto_provider_session_t **out_ps, + kcf_provider_desc_t *real) +{ + crypto_provider_session_t *ps; + + /* allocate crypto_provider_session structure */ + ps = kmem_zalloc(sizeof (crypto_provider_session_t), KM_SLEEP); + /* increment refcnt and attach to crypto_minor structure */ - new_ps->ps_session = provider_session_id; - new_ps->ps_refcnt = 1; + ps->ps_session = sid; + ps->ps_refcnt = 1; KCF_PROV_REFHOLD(pd); - new_ps->ps_provider = pd; - if (real_provider != NULL) { - new_ps->ps_real_provider = real_provider; + ps->ps_provider = pd; + if (real != NULL) { + ps->ps_real_provider = real; } - new_ps->ps_next = cm->cm_provider_session; - cm->cm_provider_session = new_ps; + ps->ps_next = cm->cm_provider_session; + cm->cm_provider_session = ps; - *output_ps = new_ps; + *out_ps = ps; return (CRYPTO_SUCCESS); } @@ -1880,7 +1901,7 @@ grow_session_table(crypto_minor_t *cm) } /* - * Find unused entry in session table and return it's index. + * Find unused entry in session table and return its index. * Initialize session table entry. */ /* ARGSUSED */ @@ -1888,11 +1909,7 @@ static int crypto_open_session(dev_t dev, uint_t flags, crypto_session_id_t *session_index, crypto_provider_id_t provider_id) { - crypto_session_data_t **session_table; - crypto_session_data_t *sp; crypto_minor_t *cm; - uint_t session_table_count; - uint_t i; int rv; crypto_provider_session_t *ps; kcf_provider_desc_t *provider; @@ -1928,6 +1945,25 @@ crypto_open_session(dev_t dev, uint_t flags, crypto_session_id_t *session_index, } provider = cm->cm_provider_array[provider_id]; + rv = crypto_create_session_ptr(cm, provider, ps, session_index); + mutex_exit(&cm->cm_lock); + crypto_release_minor(cm); + return (rv); + +} + +static int +crypto_create_session_ptr(crypto_minor_t *cm, kcf_provider_desc_t *provider, + crypto_provider_session_t *ps, crypto_session_id_t *session_index) +{ + crypto_session_data_t **session_table; + crypto_session_data_t *sp; + uint_t session_table_count; + uint_t i; + int rv; + + ASSERT(MUTEX_HELD(&cm->cm_lock)); + again: session_table_count = cm->cm_session_table_count; session_table = cm->cm_session_table; @@ -1941,8 +1977,6 @@ again: if (i == session_table_count || session_table_count == 0) { if ((rv = grow_session_table(cm)) != CRYPTO_SUCCESS) { crypto_release_provider_session(cm, ps); - mutex_exit(&cm->cm_lock); - crypto_release_minor(cm); return (rv); } goto again; @@ -1956,6 +1990,7 @@ again: sp->sd_decr_ctx = NULL; sp->sd_sign_ctx = NULL; sp->sd_verify_ctx = NULL; + sp->sd_mac_ctx = NULL; sp->sd_sign_recover_ctx = NULL; sp->sd_verify_recover_ctx = NULL; mutex_init(&sp->sd_lock, NULL, MUTEX_DRIVER, NULL); @@ -1973,9 +2008,8 @@ again: } cm->cm_session_table[i] = sp; - mutex_exit(&cm->cm_lock); - crypto_release_minor(cm); - *session_index = i; + if (session_index != NULL) + *session_index = i; return (CRYPTO_SUCCESS); } @@ -3123,7 +3157,7 @@ common_final(dev_t dev, caddr_t arg, int mode, ASSERT(final == crypto_encrypt_final || final == crypto_decrypt_final || final == crypto_sign_final || - final == crypto_digest_final); + final == crypto_digest_final || final == crypto_mac_final); if (final == crypto_encrypt_final) { ctxpp = &sp->sd_encr_ctx; @@ -3131,6 +3165,8 @@ common_final(dev_t dev, caddr_t arg, int mode, ctxpp = &sp->sd_decr_ctx; } else if (final == crypto_sign_final) { ctxpp = &sp->sd_sign_ctx; + } else if (final == crypto_mac_final) { + ctxpp = &sp->sd_mac_ctx; } else { ctxpp = &sp->sd_digest_ctx; } @@ -3420,6 +3456,35 @@ digest(dev_t dev, caddr_t arg, int mode, int *rval) return (common_digest(dev, arg, mode, crypto_digest_single)); } +static int +mac_init(dev_t dev, caddr_t arg, int mode, int *rval) +{ + _NOTE(ARGUNUSED(rval)) + return (sign_verify_init(dev, arg, mode, crypto_mac_init_prov)); +} + +static int +mac_update(dev_t dev, caddr_t arg, int mode, int *rval) +{ + _NOTE(ARGUNUSED(rval)) + return (sign_verify_update(dev, arg, mode, crypto_mac_update)); +} + +static int +mac_final(dev_t dev, caddr_t arg, int mode, int *rval) +{ + _NOTE(ARGUNUSED(rval)) + return (common_final(dev, arg, mode, crypto_mac_final)); +} + +/* ARGSUSED */ +static int +mac(dev_t dev, caddr_t arg, int mode, int *rval) +{ + _NOTE(ARGUNUSED(rval)) + return (common_digest(dev, arg, mode, crypto_mac_single)); +} + /* * ASSUMPTION: crypto_digest, crypto_sign, crypto_sign_recover, * and crypto_verify_recover are identical except for field names. @@ -3456,6 +3521,8 @@ common_digest(dev_t dev, caddr_t arg, int mode, data.cd_raw.iov_base = NULL; digest.cd_raw.iov_base = NULL; + data.cd_miscdata = NULL; + digest.cd_miscdata = NULL; datalen = STRUCT_FGET(crypto_digest, cd_datalen); digestlen = STRUCT_FGET(crypto_digest, cd_digestlen); @@ -3503,7 +3570,8 @@ common_digest(dev_t dev, caddr_t arg, int mode, ASSERT(single == crypto_digest_single || single == crypto_sign_single || single == crypto_verify_recover_single || - single == crypto_sign_recover_single); + single == crypto_sign_recover_single || + single == crypto_mac_single); if (single == crypto_digest_single) { ctxpp = &sp->sd_digest_ctx; @@ -3511,6 +3579,8 @@ common_digest(dev_t dev, caddr_t arg, int mode, ctxpp = &sp->sd_sign_ctx; } else if (single == crypto_verify_recover_single) { ctxpp = &sp->sd_verify_recover_ctx; + } else if (single == crypto_mac_single) { + ctxpp = &sp->sd_mac_ctx; } else { ctxpp = &sp->sd_sign_recover_ctx; } @@ -3897,7 +3967,8 @@ sign_verify_init(dev_t dev, caddr_t arg, int mode, ASSERT(init == crypto_sign_init_prov || init == crypto_verify_init_prov || init == crypto_sign_recover_init_prov || - init == crypto_verify_recover_init_prov); + init == crypto_verify_recover_init_prov || + init == crypto_mac_init_prov); if (init == crypto_sign_init_prov) { fg = CRYPTO_FG_SIGN; @@ -3908,6 +3979,9 @@ sign_verify_init(dev_t dev, caddr_t arg, int mode, } else if (init == crypto_sign_recover_init_prov) { fg = CRYPTO_FG_SIGN_RECOVER; ctxpp = &sp->sd_sign_recover_ctx; + } else if (init == crypto_mac_init_prov) { + fg = CRYPTO_FG_MAC; + ctxpp = &sp->sd_mac_ctx; } else { fg = CRYPTO_FG_VERIFY_RECOVER; ctxpp = &sp->sd_verify_recover_ctx; @@ -4134,6 +4208,7 @@ sign_verify_update(dev_t dev, caddr_t arg, int mode, } data.cd_raw.iov_base = NULL; + data.cd_miscdata = NULL; datalen = STRUCT_FGET(sign_update, su_datalen); if (datalen > crypto_max_buffer_len) { @@ -4163,8 +4238,16 @@ sign_verify_update(dev_t dev, caddr_t arg, int mode, goto release_minor; } - ctxpp = (update == crypto_sign_update) ? - &sp->sd_sign_ctx : &sp->sd_verify_ctx; + ASSERT(update == crypto_sign_update || + update == crypto_verify_update || + update == crypto_mac_update); + + if (update == crypto_sign_update) + ctxpp = &sp->sd_sign_ctx; + else if (update == crypto_verify_update) + ctxpp = &sp->sd_verify_ctx; + else + ctxpp = &sp->sd_mac_ctx; rv = (update)(*ctxpp, &data, NULL); if (rv != CRYPTO_SUCCESS) @@ -6550,6 +6633,62 @@ out: return (error); } +static int +get_provider_by_mech(dev_t dev, caddr_t arg, int mode, int *rval) +{ + _NOTE(ARGUNUSED(mode, rval)) + kcf_mech_entry_t *me; + kcf_provider_desc_t *pd; + crypto_key_t key; + crypto_by_mech_t mech; + crypto_provider_session_t *ps; + crypto_minor_t *cm; + int rv, error; + + if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { + cmn_err(CE_WARN, "get_provider_by_mech: failed holding minor"); + return (ENXIO); + } + + bzero(&key, sizeof (key)); + key.ck_format = CRYPTO_KEY_RAW; + + if (copyin(arg, &mech, sizeof (mech)) != 0) { + crypto_release_minor(cm); + return (EFAULT); + } + + key.ck_length = mech.mech_keylen; + /* pd is returned held */ + if ((pd = kcf_get_mech_provider(mech.mech_type, &key, &me, &error, + NULL, mech.mech_fg, 0)) == NULL) { + rv = error; + goto release_minor; + } + + /* don't want to allow direct access to software providers */ + if (pd->pd_prov_type == CRYPTO_SW_PROVIDER) { + rv = CRYPTO_MECHANISM_INVALID; + KCF_PROV_REFRELE(pd); + cmn_err(CE_WARN, "software mech_type given"); + goto release_minor; + } + + mutex_enter(&cm->cm_lock); + if ((rv = crypto_create_provider_session(cm, pd, pd->pd_sid, &ps, NULL)) + == CRYPTO_SUCCESS) + rv = crypto_create_session_ptr(cm, pd, ps, &mech.session_id); + + mutex_exit(&cm->cm_lock); +release_minor: + crypto_release_minor(cm); + mech.rv = rv; + if (copyout(&mech, arg, sizeof (mech)) != 0) + return (EFAULT); + + return (rv); +} + /* ARGSUSED */ static int crypto_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *c, @@ -6573,6 +6712,9 @@ crypto_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *c, case CRYPTO_GET_PROVIDER_LIST: return (get_provider_list(dev, ARG, mode, rval)); + case CRYPTO_GET_PROVIDER_BY_MECH: + return (get_provider_by_mech(dev, ARG, mode, rval)); + case CRYPTO_GET_PROVIDER_INFO: return (get_provider_info(dev, ARG, mode, rval)); @@ -6663,6 +6805,18 @@ crypto_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *c, case CRYPTO_VERIFY_RECOVER: return (verify_recover(dev, ARG, mode, rval)); + case CRYPTO_MAC_INIT: + return (mac_init(dev, ARG, mode, rval)); + + case CRYPTO_MAC: + return (mac(dev, ARG, mode, rval)); + + case CRYPTO_MAC_UPDATE: + return (mac_update(dev, ARG, mode, rval)); + + case CRYPTO_MAC_FINAL: + return (mac_final(dev, ARG, mode, rval)); + case CRYPTO_SET_PIN: return (set_pin(dev, ARG, mode, rval)); diff --git a/usr/src/uts/common/crypto/io/dprov.c b/usr/src/uts/common/crypto/io/dprov.c index 6259c8396d..de0a9b20e9 100644 --- a/usr/src/uts/common/crypto/io/dprov.c +++ b/usr/src/uts/common/crypto/io/dprov.c @@ -20,6 +20,7 @@ */ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. + * Copyright 2015 Nexenta Systems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -228,6 +229,7 @@ typedef enum dprov_mech_type { BLOWFISH_CBC_MECH_INFO_TYPE, /* SUN_CKM_BLOWFISH_CBC */ BLOWFISH_ECB_MECH_INFO_TYPE, /* SUN_CKM_BLOWFISH_ECB */ AES_CBC_MECH_INFO_TYPE, /* SUN_CKM_AES_CBC */ + AES_CMAC_MECH_INFO_TYPE, /* SUN_CKM_AES_CMAC */ AES_ECB_MECH_INFO_TYPE, /* SUN_CKM_AES_ECB */ AES_CTR_MECH_INFO_TYPE, /* SUN_CKM_AES_CTR */ AES_CCM_MECH_INFO_TYPE, /* SUN_CKM_AES_CCM */ @@ -476,6 +478,14 @@ static crypto_mech_info_t dprov_mech_info_tab[] = { CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC, AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES}, + /* AES-CMAC */ + {SUN_CKM_AES_CMAC, AES_CMAC_MECH_INFO_TYPE, + CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_MAC | + CRYPTO_FG_ENCRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC | + CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC | + CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | + CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC, + AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES}, /* AES-ECB */ {SUN_CKM_AES_ECB, AES_ECB_MECH_INFO_TYPE, CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC | @@ -2110,7 +2120,8 @@ dprov_valid_mac_mech(crypto_mech_type_t mech_type) mech_type == SHA384_HMAC_GEN_MECH_INFO_TYPE || mech_type == SHA512_HMAC_MECH_INFO_TYPE || mech_type == SHA512_HMAC_GEN_MECH_INFO_TYPE || - mech_type == AES_GMAC_MECH_INFO_TYPE); + mech_type == AES_GMAC_MECH_INFO_TYPE || + mech_type == AES_CMAC_MECH_INFO_TYPE); } static int @@ -2302,6 +2313,7 @@ dprov_valid_cipher_mech(crypto_mech_type_t mech_type) mech_type == BLOWFISH_CBC_MECH_INFO_TYPE || mech_type == BLOWFISH_ECB_MECH_INFO_TYPE || mech_type == AES_CBC_MECH_INFO_TYPE || + mech_type == AES_CMAC_MECH_INFO_TYPE || mech_type == AES_ECB_MECH_INFO_TYPE || mech_type == AES_CTR_MECH_INFO_TYPE || mech_type == AES_CCM_MECH_INFO_TYPE || @@ -9498,7 +9510,7 @@ dprov_object_is_token(dprov_object_t *object) */ static int dprov_get_object_attr_scalar_common(dprov_object_t *object, uint64_t attr_type, - void *value, size_t value_len) + void *value, size_t value_len) { int attr_idx; size_t oa_value_len; diff --git a/usr/src/uts/common/sys/crypto/common.h b/usr/src/uts/common/sys/crypto/common.h index 22e8e7c13f..c20ff8239b 100644 --- a/usr/src/uts/common/sys/crypto/common.h +++ b/usr/src/uts/common/sys/crypto/common.h @@ -206,6 +206,7 @@ typedef uint32_t crypto_keysize_unit_t; #define SUN_CKM_BLOWFISH_CBC "CKM_BLOWFISH_CBC" #define SUN_CKM_BLOWFISH_ECB "CKM_BLOWFISH_ECB" #define SUN_CKM_AES_CBC "CKM_AES_CBC" +#define SUN_CKM_AES_CMAC "CKM_AES_CMAC" #define SUN_CKM_AES_ECB "CKM_AES_ECB" #define SUN_CKM_AES_CTR "CKM_AES_CTR" #define SUN_CKM_AES_CCM "CKM_AES_CCM" diff --git a/usr/src/uts/common/sys/crypto/impl.h b/usr/src/uts/common/sys/crypto/impl.h index aaeae3409c..7d9c959ecd 100644 --- a/usr/src/uts/common/sys/crypto/impl.h +++ b/usr/src/uts/common/sys/crypto/impl.h @@ -510,6 +510,7 @@ typedef struct crypto_session_data { crypto_ctx_t *sd_digest_ctx; crypto_ctx_t *sd_encr_ctx; crypto_ctx_t *sd_decr_ctx; + crypto_ctx_t *sd_mac_ctx; crypto_ctx_t *sd_sign_ctx; crypto_ctx_t *sd_verify_ctx; crypto_ctx_t *sd_sign_recover_ctx; diff --git a/usr/src/uts/common/sys/crypto/ioctl.h b/usr/src/uts/common/sys/crypto/ioctl.h index 32dddf4394..b7b511768b 100644 --- a/usr/src/uts/common/sys/crypto/ioctl.h +++ b/usr/src/uts/common/sys/crypto/ioctl.h @@ -1483,6 +1483,17 @@ typedef struct crypto_get_all_mechanism_info32 { #define CRYPTO_GET_MECHANISM_LIST CRYPTO(140) #define CRYPTO_GET_ALL_MECHANISM_INFO CRYPTO(141) +#define CRYPTO_GET_PROVIDER_BY_MECH CRYPTO(142) + +typedef struct crypto_by_mech { + int rv; + int res; + crypto_mech_type_t mech_type; + uint_t mech_keylen; + crypto_func_group_t mech_fg; + crypto_session_id_t session_id; +} crypto_by_mech_t; + #ifdef __cplusplus } #endif diff --git a/usr/src/uts/common/sys/crypto/spi.h b/usr/src/uts/common/sys/crypto/spi.h index 47741d2876..42294e8dde 100644 --- a/usr/src/uts/common/sys/crypto/spi.h +++ b/usr/src/uts/common/sys/crypto/spi.h @@ -588,6 +588,8 @@ typedef union crypto_provider_dev { dev_info_t *pd_hw; /* for CRYPTO_HW_PROVIDER */ } crypto_provider_dev_t; +#endif /* _KERNEL */ + /* * The mechanism info structure crypto_mech_info_t contains a function group * bit mask cm_func_group_mask. This field, of type crypto_func_group_t, @@ -597,8 +599,6 @@ typedef union crypto_provider_dev { typedef uint32_t crypto_func_group_t; -#endif /* _KERNEL */ - #define CRYPTO_FG_ENCRYPT 0x00000001 /* encrypt_init() */ #define CRYPTO_FG_DECRYPT 0x00000002 /* decrypt_init() */ #define CRYPTO_FG_DIGEST 0x00000004 /* digest_init() */ -- 2.11.4.GIT