diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2019-09-24 11:05:03 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2019-11-13 10:47:04 +0100 |
commit | a5ddb0ea69f21c16b7697a935d7a0c16bb3cffcf (patch) | |
tree | db091fb0f7d091804482156c9f3f55879ac93d5b /freebsd/sys/opencrypto | |
parent | test/syscalls01: Fix sporadic test failures (diff) | |
download | rtems-libbsd-a5ddb0ea69f21c16b7697a935d7a0c16bb3cffcf.tar.bz2 |
Update to FreeBSD head 2019-09-24
Git mirror commit 6b0307a0a5184339393f555d5d424190d8a8277a.
Diffstat (limited to 'freebsd/sys/opencrypto')
24 files changed, 672 insertions, 116 deletions
diff --git a/freebsd/sys/opencrypto/cast.c b/freebsd/sys/opencrypto/cast.c index 1fb62f20..8031dabe 100644 --- a/freebsd/sys/opencrypto/cast.c +++ b/freebsd/sys/opencrypto/cast.c @@ -131,7 +131,7 @@ u_int32_t t, l, r; /***** Key Schedule *****/ -void cast_setkey(cast_key* key, u_int8_t* rawkey, int keybytes) +void cast_setkey(cast_key* key, const u_int8_t* rawkey, int keybytes) { u_int32_t t[4] = {0, 0, 0, 0}, z[4] = {0, 0, 0, 0}, x[4]; int i; diff --git a/freebsd/sys/opencrypto/cast.h b/freebsd/sys/opencrypto/cast.h index 8e2d0d19..2aca9340 100644 --- a/freebsd/sys/opencrypto/cast.h +++ b/freebsd/sys/opencrypto/cast.h @@ -16,7 +16,7 @@ typedef struct { int rounds; /* Number of rounds to use, 12 or 16 */ } cast_key; -void cast_setkey(cast_key * key, u_int8_t * rawkey, int keybytes); +void cast_setkey(cast_key * key, const u_int8_t * rawkey, int keybytes); void cast_encrypt(cast_key * key, u_int8_t * inblock, u_int8_t * outblock); void cast_decrypt(cast_key * key, u_int8_t * inblock, u_int8_t * outblock); diff --git a/freebsd/sys/opencrypto/cbc_mac.c b/freebsd/sys/opencrypto/cbc_mac.c new file mode 100644 index 00000000..1bcf356a --- /dev/null +++ b/freebsd/sys/opencrypto/cbc_mac.c @@ -0,0 +1,267 @@ +#include <machine/rtems-bsd-kernel-space.h> + +/* + * Copyright (c) 2018-2019 iXsystems Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <sys/systm.h> +#include <sys/param.h> +#include <sys/endian.h> +#include <opencrypto/cbc_mac.h> +#include <opencrypto/xform_auth.h> + +/* + * Given two CCM_CBC_BLOCK_LEN blocks, xor + * them into dst, and then encrypt dst. + */ +static void +xor_and_encrypt(struct aes_cbc_mac_ctx *ctx, + const uint8_t *src, uint8_t *dst) +{ + const uint64_t *b1; + uint64_t *b2; + uint64_t temp_block[CCM_CBC_BLOCK_LEN/sizeof(uint64_t)]; + + b1 = (const uint64_t*)src; + b2 = (uint64_t*)dst; + + for (size_t count = 0; + count < CCM_CBC_BLOCK_LEN/sizeof(uint64_t); + count++) { + temp_block[count] = b1[count] ^ b2[count]; + } + rijndaelEncrypt(ctx->keysched, ctx->rounds, (void*)temp_block, dst); +} + +void +AES_CBC_MAC_Init(struct aes_cbc_mac_ctx *ctx) +{ + bzero(ctx, sizeof(*ctx)); +} + +void +AES_CBC_MAC_Setkey(struct aes_cbc_mac_ctx *ctx, const uint8_t *key, uint16_t klen) +{ + ctx->rounds = rijndaelKeySetupEnc(ctx->keysched, key, klen * 8); +} + +/* + * This is called to set the nonce, aka IV. + * Before this call, the authDataLength and cryptDataLength fields + * MUST have been set. Sadly, there's no way to return an error. + * + * The CBC-MAC algorithm requires that the first block contain the + * nonce, as well as information about the sizes and lengths involved. + */ +void +AES_CBC_MAC_Reinit(struct aes_cbc_mac_ctx *ctx, const uint8_t *nonce, uint16_t nonceLen) +{ + uint8_t b0[CCM_CBC_BLOCK_LEN]; + uint8_t *bp = b0, flags = 0; + uint8_t L = 0; + uint64_t dataLength = ctx->cryptDataLength; + + KASSERT(nonceLen >= 7 && nonceLen <= 13, + ("nonceLen must be between 7 and 13 bytes")); + + ctx->nonce = nonce; + ctx->nonceLength = nonceLen; + + ctx->authDataCount = 0; + ctx->blockIndex = 0; + explicit_bzero(ctx->staging_block, sizeof(ctx->staging_block)); + + /* + * Need to determine the L field value. This is the number of + * bytes needed to specify the length of the message; the length + * is whatever is left in the 16 bytes after specifying flags and + * the nonce. + */ + L = 15 - nonceLen; + + flags = ((ctx->authDataLength > 0) << 6) + + (((AES_CBC_MAC_HASH_LEN - 2) / 2) << 3) + + L - 1; + /* + * Now we need to set up the first block, which has flags, nonce, + * and the message length. + */ + b0[0] = flags; + bcopy(nonce, b0 + 1, nonceLen); + bp = b0 + 1 + nonceLen; + + /* Need to copy L' [aka L-1] bytes of cryptDataLength */ + for (uint8_t *dst = b0 + sizeof(b0) - 1; dst >= bp; dst--) { + *dst = dataLength; + dataLength >>= 8; + } + /* Now need to encrypt b0 */ + rijndaelEncrypt(ctx->keysched, ctx->rounds, b0, ctx->block); + /* If there is auth data, we need to set up the staging block */ + if (ctx->authDataLength) { + size_t addLength; + if (ctx->authDataLength < ((1<<16) - (1<<8))) { + uint16_t sizeVal = htobe16(ctx->authDataLength); + bcopy(&sizeVal, ctx->staging_block, sizeof(sizeVal)); + addLength = sizeof(sizeVal); + } else if (ctx->authDataLength < (1ULL<<32)) { + uint32_t sizeVal = htobe32(ctx->authDataLength); + ctx->staging_block[0] = 0xff; + ctx->staging_block[1] = 0xfe; + bcopy(&sizeVal, ctx->staging_block+2, sizeof(sizeVal)); + addLength = 2 + sizeof(sizeVal); + } else { + uint64_t sizeVal = htobe64(ctx->authDataLength); + ctx->staging_block[0] = 0xff; + ctx->staging_block[1] = 0xff; + bcopy(&sizeVal, ctx->staging_block+2, sizeof(sizeVal)); + addLength = 2 + sizeof(sizeVal); + } + ctx->blockIndex = addLength; + /* + * The length descriptor goes into the AAD buffer, so we + * need to account for it. + */ + ctx->authDataLength += addLength; + ctx->authDataCount = addLength; + } +} + +int +AES_CBC_MAC_Update(struct aes_cbc_mac_ctx *ctx, const uint8_t *data, + uint16_t length) +{ + size_t copy_amt; + + /* + * This will be called in one of two phases: + * (1) Applying authentication data, or + * (2) Applying the payload data. + * + * Because CBC-MAC puts the authentication data size before the + * data, subsequent calls won't be block-size-aligned. Which + * complicates things a fair bit. + * + * The payload data doesn't have that problem. + */ + + if (ctx->authDataCount < ctx->authDataLength) { + /* + * We need to process data as authentication data. + * Since we may be out of sync, we may also need + * to pad out the staging block. + */ + const uint8_t *ptr = data; + while (length > 0) { + + copy_amt = MIN(length, + sizeof(ctx->staging_block) - ctx->blockIndex); + + bcopy(ptr, ctx->staging_block + ctx->blockIndex, + copy_amt); + ptr += copy_amt; + length -= copy_amt; + ctx->authDataCount += copy_amt; + ctx->blockIndex += copy_amt; + ctx->blockIndex %= sizeof(ctx->staging_block); + + if (ctx->blockIndex == 0 || + ctx->authDataCount == ctx->authDataLength) { + /* + * We're done with this block, so we + * xor staging_block with block, and then + * encrypt it. + */ + xor_and_encrypt(ctx, ctx->staging_block, ctx->block); + bzero(ctx->staging_block, sizeof(ctx->staging_block)); + ctx->blockIndex = 0; + if (ctx->authDataCount >= ctx->authDataLength) + break; + } + } + /* + * We'd like to be able to check length == 0 and return + * here, but the way OCF calls us, length is always + * blksize (16, in this case). So we have to count on + * the fact that OCF calls us separately for the AAD and + * for the real data. + */ + return (0); + } + /* + * If we're here, then we're encoding payload data. + * This is marginally easier, except that _Update can + * be called with non-aligned update lengths. As a result, + * we still need to use the staging block. + */ + KASSERT((length + ctx->cryptDataCount) <= ctx->cryptDataLength, + ("More encryption data than allowed")); + + while (length) { + uint8_t *ptr; + + copy_amt = MIN(sizeof(ctx->staging_block) - ctx->blockIndex, + length); + ptr = ctx->staging_block + ctx->blockIndex; + bcopy(data, ptr, copy_amt); + data += copy_amt; + ctx->blockIndex += copy_amt; + ctx->cryptDataCount += copy_amt; + length -= copy_amt; + if (ctx->blockIndex == sizeof(ctx->staging_block)) { + /* We've got a full block */ + xor_and_encrypt(ctx, ctx->staging_block, ctx->block); + ctx->blockIndex = 0; + bzero(ctx->staging_block, sizeof(ctx->staging_block)); + } + } + return (0); +} + +void +AES_CBC_MAC_Final(uint8_t *buf, struct aes_cbc_mac_ctx *ctx) +{ + uint8_t s0[CCM_CBC_BLOCK_LEN]; + + /* + * We first need to check to see if we've got any data + * left over to encrypt. + */ + if (ctx->blockIndex != 0) { + xor_and_encrypt(ctx, ctx->staging_block, ctx->block); + ctx->cryptDataCount += ctx->blockIndex; + ctx->blockIndex = 0; + explicit_bzero(ctx->staging_block, sizeof(ctx->staging_block)); + } + bzero(s0, sizeof(s0)); + s0[0] = (15 - ctx->nonceLength) - 1; + bcopy(ctx->nonce, s0 + 1, ctx->nonceLength); + rijndaelEncrypt(ctx->keysched, ctx->rounds, s0, s0); + for (size_t indx = 0; indx < AES_CBC_MAC_HASH_LEN; indx++) + buf[indx] = ctx->block[indx] ^ s0[indx]; + explicit_bzero(s0, sizeof(s0)); +} diff --git a/freebsd/sys/opencrypto/cbc_mac.h b/freebsd/sys/opencrypto/cbc_mac.h new file mode 100644 index 00000000..33e61cc1 --- /dev/null +++ b/freebsd/sys/opencrypto/cbc_mac.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2014 The FreeBSD Foundation + * Copyright (c) 2018, iXsystems Inc. + * All rights reserved. + * + * This software was developed by Sean Eric Fagan, with lots of references + * to existing AES-CCM (gmac) code. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + * + */ + +#ifndef _CBC_CCM_H +# define _CBC_CCM_H + +# include <sys/types.h> +# include <crypto/rijndael/rijndael.h> + +# define CCM_CBC_BLOCK_LEN 16 /* 128 bits */ +# define CCM_CBC_MAX_DIGEST_LEN 16 +# define CCM_CBC_MIN_DIGEST_LEN 4 + +/* + * This is the authentication context structure; + * the encryption one is similar. + */ +struct aes_cbc_mac_ctx { + uint64_t authDataLength, authDataCount; + uint64_t cryptDataLength, cryptDataCount; + int blockIndex; + uint8_t staging_block[CCM_CBC_BLOCK_LEN]; + uint8_t block[CCM_CBC_BLOCK_LEN]; + const uint8_t *nonce; + int nonceLength; /* This one is in bytes, not bits! */ + /* AES state data */ + int rounds; + uint32_t keysched[4*(RIJNDAEL_MAXNR+1)]; +}; + +void AES_CBC_MAC_Init(struct aes_cbc_mac_ctx *); +void AES_CBC_MAC_Setkey(struct aes_cbc_mac_ctx *, const uint8_t *, uint16_t); +void AES_CBC_MAC_Reinit(struct aes_cbc_mac_ctx *, const uint8_t *, uint16_t); +int AES_CBC_MAC_Update(struct aes_cbc_mac_ctx *, const uint8_t *, uint16_t); +void AES_CBC_MAC_Final(uint8_t *, struct aes_cbc_mac_ctx *); + +#endif /* _CBC_CCM_H */ diff --git a/freebsd/sys/opencrypto/cryptodeflate.c b/freebsd/sys/opencrypto/cryptodeflate.c index 8ab063f4..30d0844a 100644 --- a/freebsd/sys/opencrypto/cryptodeflate.c +++ b/freebsd/sys/opencrypto/cryptodeflate.c @@ -31,7 +31,7 @@ /* * This file contains a wrapper around the deflate algo compression - * functions using the zlib library (see libkern/zlib.c and sys/zlib.h}) + * functions using the zlib library (see sys/contrib/zlib) */ #include <sys/cdefs.h> @@ -44,7 +44,7 @@ __FBSDID("$FreeBSD$"); #include <sys/kernel.h> #include <sys/sdt.h> #include <sys/systm.h> -#include <sys/zlib.h> +#include <contrib/zlib/zlib.h> #include <opencrypto/cryptodev.h> #include <opencrypto/deflate.h> @@ -52,16 +52,32 @@ __FBSDID("$FreeBSD$"); SDT_PROVIDER_DECLARE(opencrypto); SDT_PROBE_DEFINE2(opencrypto, deflate, deflate_global, entry, "int", "u_int32_t"); -SDT_PROBE_DEFINE5(opencrypto, deflate, deflate_global, bad, - "int", "int", "int", "int", "int"); -SDT_PROBE_DEFINE5(opencrypto, deflate, deflate_global, iter, - "int", "int", "int", "int", "int"); +SDT_PROBE_DEFINE6(opencrypto, deflate, deflate_global, bad, + "int", "int", "int", "int", "int", "int"); +SDT_PROBE_DEFINE6(opencrypto, deflate, deflate_global, iter, + "int", "int", "int", "int", "int", "int"); SDT_PROBE_DEFINE2(opencrypto, deflate, deflate_global, return, "int", "u_int32_t"); int window_inflate = -1 * MAX_WBITS; int window_deflate = -12; +static void * +crypto_zalloc(void *nil, u_int type, u_int size) +{ + void *ptr; + + ptr = malloc(type *size, M_CRYPTO_DATA, M_NOWAIT); + return ptr; +} + +static void +crypto_zfree(void *nil, void *ptr) +{ + + free(ptr, M_CRYPTO_DATA); +} + /* * This function takes a block of data and (de)compress it using the deflate * algorithm @@ -107,16 +123,16 @@ deflate_global(data, size, decomp, out) bufh = bufp = malloc(sizeof(*bufp) + (size_t)(size * i), M_CRYPTO_DATA, M_NOWAIT); if (bufp == NULL) { - SDT_PROBE5(opencrypto, deflate, deflate_global, bad, - decomp, 0, __LINE__, 0, 0); + SDT_PROBE6(opencrypto, deflate, deflate_global, bad, + decomp, 0, __LINE__, 0, 0, 0); goto bad2; } bufp->next = NULL; bufp->size = size * i; bzero(&zbuf, sizeof(z_stream)); - zbuf.zalloc = z_alloc; - zbuf.zfree = z_free; + zbuf.zalloc = crypto_zalloc; + zbuf.zfree = crypto_zfree; zbuf.opaque = Z_NULL; zbuf.next_in = data; /* Data that is going to be processed. */ zbuf.avail_in = size; /* Total length of data to be processed. */ @@ -127,8 +143,8 @@ deflate_global(data, size, decomp, out) deflateInit2(&zbuf, Z_DEFAULT_COMPRESSION, Z_METHOD, window_deflate, Z_MEMLEVEL, Z_DEFAULT_STRATEGY); if (error != Z_OK) { - SDT_PROBE5(opencrypto, deflate, deflate_global, bad, - decomp, error, __LINE__, 0, 0); + SDT_PROBE6(opencrypto, deflate, deflate_global, bad, + decomp, error, __LINE__, 0, 0, 0); goto bad; } @@ -136,24 +152,14 @@ deflate_global(data, size, decomp, out) error = decomp ? inflate(&zbuf, Z_SYNC_FLUSH) : deflate(&zbuf, Z_FINISH); if (error != Z_OK && error != Z_STREAM_END) { - /* - * Unfortunately we are limited to 5 arguments, - * thus use two probes. - */ - SDT_PROBE5(opencrypto, deflate, deflate_global, bad, - decomp, error, __LINE__, - zbuf.avail_in, zbuf.avail_out); - SDT_PROBE5(opencrypto, deflate, deflate_global, bad, + SDT_PROBE6(opencrypto, deflate, deflate_global, bad, decomp, error, __LINE__, - zbuf.state->dummy, zbuf.total_out); + zbuf.avail_in, zbuf.avail_out, zbuf.total_out); goto bad; } - SDT_PROBE5(opencrypto, deflate, deflate_global, iter, - decomp, error, __LINE__, - zbuf.avail_in, zbuf.avail_out); - SDT_PROBE5(opencrypto, deflate, deflate_global, iter, + SDT_PROBE6(opencrypto, deflate, deflate_global, iter, decomp, error, __LINE__, - zbuf.state->dummy, zbuf.total_out); + zbuf.avail_in, zbuf.avail_out, zbuf.total_out); if (decomp && zbuf.avail_in == 0 && error == Z_STREAM_END) { /* Done. */ break; @@ -167,8 +173,8 @@ deflate_global(data, size, decomp, out) p = malloc(sizeof(*p) + (size_t)(size * i), M_CRYPTO_DATA, M_NOWAIT); if (p == NULL) { - SDT_PROBE5(opencrypto, deflate, deflate_global, - bad, decomp, 0, __LINE__, 0, 0); + SDT_PROBE6(opencrypto, deflate, deflate_global, + bad, decomp, 0, __LINE__, 0, 0, 0); goto bad; } p->next = NULL; @@ -179,16 +185,9 @@ deflate_global(data, size, decomp, out) zbuf.avail_out = bufp->size; } else { /* Unexpect result. */ - /* - * Unfortunately we are limited to 5 arguments, - * thus, again, use two probes. - */ - SDT_PROBE5(opencrypto, deflate, deflate_global, bad, - decomp, error, __LINE__, - zbuf.avail_in, zbuf.avail_out); - SDT_PROBE5(opencrypto, deflate, deflate_global, bad, - decomp, error, __LINE__, - zbuf.state->dummy, zbuf.total_out); + SDT_PROBE6(opencrypto, deflate, deflate_global, + bad, decomp, error, __LINE__, + zbuf.avail_in, zbuf.avail_out, zbuf.total_out); goto bad; } } @@ -197,8 +196,8 @@ deflate_global(data, size, decomp, out) *out = malloc(result, M_CRYPTO_DATA, M_NOWAIT); if (*out == NULL) { - SDT_PROBE5(opencrypto, deflate, deflate_global, bad, - decomp, 0, __LINE__, 0, 0); + SDT_PROBE6(opencrypto, deflate, deflate_global, bad, + decomp, 0, __LINE__, 0, 0, 0); goto bad; } if (decomp) @@ -245,21 +244,3 @@ bad2: *out = NULL; return 0; } - -void * -z_alloc(nil, type, size) - void *nil; - u_int type, size; -{ - void *ptr; - - ptr = malloc(type *size, M_CRYPTO_DATA, M_NOWAIT); - return ptr; -} - -void -z_free(nil, ptr) - void *nil, *ptr; -{ - free(ptr, M_CRYPTO_DATA); -} diff --git a/freebsd/sys/opencrypto/cryptodev.c b/freebsd/sys/opencrypto/cryptodev.c index b569cbf7..575142f2 100644 --- a/freebsd/sys/opencrypto/cryptodev.c +++ b/freebsd/sys/opencrypto/cryptodev.c @@ -296,6 +296,11 @@ struct fcrypt { int sesn; }; +static struct timeval warninterval = { .tv_sec = 60, .tv_usec = 0 }; +SYSCTL_TIMEVAL_SEC(_kern, OID_AUTO, cryptodev_warn_interval, CTLFLAG_RW, + &warninterval, + "Delay in seconds between warnings of deprecated /dev/crypto algorithms"); + #ifndef __rtems__ static int cryptof_ioctl(struct file *, u_long, void *, struct ucred *, struct thread *); @@ -450,6 +455,9 @@ cryptof_ioctl( case CRYPTO_CHACHA20: txform = &enc_xform_chacha20; break; + case CRYPTO_AES_CCM_16: + txform = &enc_xform_ccm; + break; default: CRYPTDEB("invalid cipher"); @@ -494,6 +502,25 @@ cryptof_ioctl( thash = &auth_hash_nist_gmac_aes_256; break; + case CRYPTO_AES_CCM_CBC_MAC: + switch (sop->keylen) { + case 16: + thash = &auth_hash_ccm_cbc_mac_128; + break; + case 24: + thash = &auth_hash_ccm_cbc_mac_192; + break; + case 32: + thash = &auth_hash_ccm_cbc_mac_256; + break; + default: + CRYPTDEB("Invalid CBC MAC key size %d", + sop->keylen); + SDT_PROBE1(opencrypto, dev, ioctl, + error, __LINE__); + return (EINVAL); + } + break; #ifdef notdef case CRYPTO_MD5: thash = &auth_hash_md5; @@ -798,6 +825,47 @@ cod_free(struct cryptop_data *cod) free(cod, M_XDATA); } +static void +cryptodev_warn(struct csession *cse) +{ + static struct timeval arc4warn, blfwarn, castwarn, deswarn, md5warn; + static struct timeval skipwarn, tdeswarn; + + switch (cse->cipher) { + case CRYPTO_DES_CBC: + if (ratecheck(&deswarn, &warninterval)) + gone_in(13, "DES cipher via /dev/crypto"); + break; + case CRYPTO_3DES_CBC: + if (ratecheck(&tdeswarn, &warninterval)) + gone_in(13, "3DES cipher via /dev/crypto"); + break; + case CRYPTO_BLF_CBC: + if (ratecheck(&blfwarn, &warninterval)) + gone_in(13, "Blowfish cipher via /dev/crypto"); + break; + case CRYPTO_CAST_CBC: + if (ratecheck(&castwarn, &warninterval)) + gone_in(13, "CAST128 cipher via /dev/crypto"); + break; + case CRYPTO_SKIPJACK_CBC: + if (ratecheck(&skipwarn, &warninterval)) + gone_in(13, "Skipjack cipher via /dev/crypto"); + break; + case CRYPTO_ARC4: + if (ratecheck(&arc4warn, &warninterval)) + gone_in(13, "ARC4 cipher via /dev/crypto"); + break; + } + + switch (cse->mac) { + case CRYPTO_MD5_HMAC: + if (ratecheck(&md5warn, &warninterval)) + gone_in(13, "MD5-HMAC authenticator via /dev/crypto"); + break; + } +} + static int cryptodev_op( struct csession *cse, @@ -920,6 +988,7 @@ cryptodev_op( error = EINVAL; goto bail; } + cryptodev_warn(cse); again: /* @@ -1030,12 +1099,13 @@ cryptodev_aead( } /* - * For GCM, crd_len covers only the AAD. For other ciphers + * For GCM/CCM, crd_len covers only the AAD. For other ciphers * chained with an HMAC, crd_len covers both the AAD and the * cipher text. */ crda->crd_skip = 0; - if (cse->cipher == CRYPTO_AES_NIST_GCM_16) + if (cse->cipher == CRYPTO_AES_NIST_GCM_16 || + cse->cipher == CRYPTO_AES_CCM_16) crda->crd_len = caead->aadlen; else crda->crd_len = caead->aadlen + caead->len; @@ -1088,6 +1158,7 @@ cryptodev_aead( SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); goto bail; } + cryptodev_warn(cse); again: /* * Let the dispatch run unlocked, then, interlock against the diff --git a/freebsd/sys/opencrypto/cryptodev.h b/freebsd/sys/opencrypto/cryptodev.h index 6431e6d8..bd71e518 100644 --- a/freebsd/sys/opencrypto/cryptodev.h +++ b/freebsd/sys/opencrypto/cryptodev.h @@ -63,10 +63,10 @@ #define _CRYPTO_CRYPTO_H_ #include <sys/ioccom.h> -#include <sys/_task.h> #ifdef _KERNEL #include <opencrypto/_cryptodev.h> +#include <sys/_task.h> #endif /* Some initial values */ @@ -86,6 +86,7 @@ #define SHA1_KPDK_HASH_LEN 20 #define AES_GMAC_HASH_LEN 16 #define POLY1305_HASH_LEN 16 +#define AES_CBC_MAC_HASH_LEN 16 /* Maximum hash algorithm result length */ #define HASH_MAX_LEN SHA2_512_HASH_LEN /* Keep this updated */ @@ -107,6 +108,9 @@ #define AES_128_GMAC_KEY_LEN 16 #define AES_192_GMAC_KEY_LEN 24 #define AES_256_GMAC_KEY_LEN 32 +#define AES_128_CBC_MAC_KEY_LEN 16 +#define AES_192_CBC_MAC_KEY_LEN 24 +#define AES_256_CBC_MAC_KEY_LEN 32 #define POLY1305_KEY_LEN 32 @@ -129,6 +133,7 @@ #define ARC4_IV_LEN 1 #define AES_GCM_IV_LEN 12 +#define AES_CCM_IV_LEN 12 #define AES_XTS_IV_LEN 8 #define AES_XTS_ALPHA 0x87 /* GF(2^128) generator polynomial */ @@ -199,7 +204,9 @@ #define CRYPTO_SHA2_384 36 #define CRYPTO_SHA2_512 37 #define CRYPTO_POLY1305 38 -#define CRYPTO_ALGORITHM_MAX 38 /* Keep updated - see below */ +#define CRYPTO_AES_CCM_CBC_MAC 39 /* auth side */ +#define CRYPTO_AES_CCM_16 40 /* cipher side */ +#define CRYPTO_ALGORITHM_MAX 40 /* Keep updated - see below */ #define CRYPTO_ALGO_VALID(x) ((x) >= CRYPTO_ALGORITHM_MIN && \ (x) <= CRYPTO_ALGORITHM_MAX) diff --git a/freebsd/sys/opencrypto/cryptosoft.c b/freebsd/sys/opencrypto/cryptosoft.c index 43455b48..5e63167a 100644 --- a/freebsd/sys/opencrypto/cryptosoft.c +++ b/freebsd/sys/opencrypto/cryptosoft.c @@ -64,6 +64,9 @@ __FBSDID("$FreeBSD$"); #include <sys/bus.h> #include <rtems/bsd/local/cryptodev_if.h> +_Static_assert(AES_CCM_IV_LEN == AES_GCM_IV_LEN, + "AES_GCM_IV_LEN must currently be the same as AES_CCM_IV_LEN"); + static int32_t swcr_id; u_int8_t hmac_ipad_buffer[HMAC_MAX_BLOCK_LEN]; @@ -508,6 +511,7 @@ swcr_authenc(struct cryptop *crp) caddr_t buf = (caddr_t)crp->crp_buf; uint32_t *blkp; int aadlen, blksz, i, ivlen, len, iskip, oskip, r; + int isccm = 0; ivlen = blksz = iskip = oskip = 0; @@ -522,13 +526,18 @@ swcr_authenc(struct cryptop *crp) sw = &ses->swcr_algorithms[i]; switch (sw->sw_alg) { + case CRYPTO_AES_CCM_16: case CRYPTO_AES_NIST_GCM_16: case CRYPTO_AES_NIST_GMAC: swe = sw; crde = crd; exf = swe->sw_exf; - ivlen = 12; + /* AES_CCM_IV_LEN and AES_GCM_IV_LEN are both 12 */ + ivlen = AES_CCM_IV_LEN; break; + case CRYPTO_AES_CCM_CBC_MAC: + isccm = 1; + /* FALLTHROUGH */ case CRYPTO_AES_128_NIST_GMAC: case CRYPTO_AES_192_NIST_GMAC: case CRYPTO_AES_256_NIST_GMAC: @@ -546,8 +555,26 @@ swcr_authenc(struct cryptop *crp) } if (crde == NULL || crda == NULL) return (EINVAL); + /* + * We need to make sure that the auth algorithm matches the + * encr algorithm. Specifically, for AES-GCM must go with + * AES NIST GMAC, and AES-CCM must go with CBC-MAC. + */ + if (crde->crd_alg == CRYPTO_AES_NIST_GCM_16) { + switch (crda->crd_alg) { + case CRYPTO_AES_128_NIST_GMAC: + case CRYPTO_AES_192_NIST_GMAC: + case CRYPTO_AES_256_NIST_GMAC: + break; /* Good! */ + default: + return (EINVAL); /* Not good! */ + } + } else if (crde->crd_alg == CRYPTO_AES_CCM_16 && + crda->crd_alg != CRYPTO_AES_CCM_CBC_MAC) + return (EINVAL); - if (crde->crd_alg == CRYPTO_AES_NIST_GCM_16 && + if ((crde->crd_alg == CRYPTO_AES_NIST_GCM_16 || + crde->crd_alg == CRYPTO_AES_CCM_16) && (crde->crd_flags & CRD_F_IV_EXPLICIT) == 0) return (EINVAL); @@ -578,6 +605,15 @@ swcr_authenc(struct cryptop *crp) } } + if (swa->sw_alg == CRYPTO_AES_CCM_CBC_MAC) { + /* + * AES CCM-CBC needs to know the length of + * both the auth data, and payload data, before + * doing the auth computation. + */ + ctx.aes_cbc_mac_ctx.authDataLength = crda->crd_len; + ctx.aes_cbc_mac_ctx.cryptDataLength = crde->crd_len; + } /* Supply MAC with IV */ if (axf->Reinit) axf->Reinit(&ctx, iv, ivlen); @@ -612,16 +648,30 @@ swcr_authenc(struct cryptop *crp) bzero(blk, blksz); crypto_copydata(crp->crp_flags, buf, crde->crd_skip + i, len, blk); + /* + * One of the problems with CCM+CBC is that the authentication + * is done on the unecncrypted data. As a result, we have + * to do the authentication update at different times, + * depending on whether it's CCM or not. + */ if (crde->crd_flags & CRD_F_ENCRYPT) { + if (isccm) + axf->Update(&ctx, blk, len); if (exf->encrypt_multi != NULL) exf->encrypt_multi(swe->sw_kschedule, blk, len); else exf->encrypt(swe->sw_kschedule, blk); - axf->Update(&ctx, blk, len); + if (!isccm) + axf->Update(&ctx, blk, len); crypto_copyback(crp->crp_flags, buf, crde->crd_skip + i, len, blk); } else { + if (isccm) { + KASSERT(exf->encrypt_multi == NULL, + ("assume CCM is single-block only")); + exf->decrypt(swe->sw_kschedule, blk); + } axf->Update(&ctx, blk, len); } } @@ -652,6 +702,11 @@ swcr_authenc(struct cryptop *crp) r = timingsafe_bcmp(aalg, uaalg, axf->hashsize); if (r == 0) { /* tag matches, decrypt data */ + if (isccm) { + KASSERT(exf->reinit != NULL, + ("AES-CCM reinit function must be set")); + exf->reinit(swe->sw_kschedule, iv); + } for (i = 0; i < crde->crd_len; i += blksz) { len = MIN(crde->crd_len - i, blksz); if (len < blksz) @@ -801,6 +856,9 @@ swcr_newsession(device_t dev, crypto_session_t cses, struct cryptoini *cri) case CRYPTO_AES_NIST_GCM_16: txf = &enc_xform_aes_nist_gcm; goto enccommon; + case CRYPTO_AES_CCM_16: + txf = &enc_xform_ccm; + goto enccommon; case CRYPTO_AES_NIST_GMAC: txf = &enc_xform_aes_nist_gmac; swd->sw_exf = txf; @@ -945,6 +1003,22 @@ swcr_newsession(device_t dev, crypto_session_t cses, struct cryptoini *cri) swd->sw_axf = axf; break; + case CRYPTO_AES_CCM_CBC_MAC: + switch (cri->cri_klen) { + case 128: + axf = &auth_hash_ccm_cbc_mac_128; + break; + case 192: + axf = &auth_hash_ccm_cbc_mac_192; + break; + case 256: + axf = &auth_hash_ccm_cbc_mac_256; + break; + default: + swcr_freesession(dev, cses); + return EINVAL; + } + goto auth4common; case CRYPTO_AES_128_NIST_GMAC: axf = &auth_hash_nist_gmac_aes_128; goto auth4common; @@ -1044,6 +1118,7 @@ swcr_freesession(device_t dev, crypto_session_t cses) case CRYPTO_CAMELLIA_CBC: case CRYPTO_NULL_CBC: case CRYPTO_CHACHA20: + case CRYPTO_AES_CCM_16: txf = swd->sw_exf; if (swd->sw_kschedule) @@ -1058,6 +1133,7 @@ swcr_freesession(device_t dev, crypto_session_t cses) case CRYPTO_SHA2_512_HMAC: case CRYPTO_RIPEMD160_HMAC: case CRYPTO_NULL_HMAC: + case CRYPTO_AES_CCM_CBC_MAC: axf = swd->sw_axf; if (swd->sw_ictx) { @@ -1203,6 +1279,8 @@ swcr_process(device_t dev, struct cryptop *crp, int hint) case CRYPTO_AES_128_NIST_GMAC: case CRYPTO_AES_192_NIST_GMAC: case CRYPTO_AES_256_NIST_GMAC: + case CRYPTO_AES_CCM_16: + case CRYPTO_AES_CCM_CBC_MAC: crp->crp_etype = swcr_authenc(crp); goto done; @@ -1293,6 +1371,8 @@ swcr_attach(device_t dev) REGISTER(CRYPTO_BLAKE2B); REGISTER(CRYPTO_BLAKE2S); REGISTER(CRYPTO_CHACHA20); + REGISTER(CRYPTO_AES_CCM_16); + REGISTER(CRYPTO_AES_CCM_CBC_MAC); REGISTER(CRYPTO_POLY1305); #undef REGISTER diff --git a/freebsd/sys/opencrypto/deflate.h b/freebsd/sys/opencrypto/deflate.h index d31a3bf2..1be746d7 100644 --- a/freebsd/sys/opencrypto/deflate.h +++ b/freebsd/sys/opencrypto/deflate.h @@ -36,16 +36,12 @@ #ifndef _CRYPTO_DEFLATE_H_ #define _CRYPTO_DEFLATE_H_ -#include <sys/zlib.h> - #define Z_METHOD 8 #define Z_MEMLEVEL 8 #define MINCOMP 2 /* won't be used, but must be defined */ #define ZBUF 10 u_int32_t deflate_global(u_int8_t *, u_int32_t, int, u_int8_t **); -void *z_alloc(void *, u_int, u_int); -void z_free(void *, void *); /* * We are going to use a combined allocation to hold the metadata diff --git a/freebsd/sys/opencrypto/skipjack.c b/freebsd/sys/opencrypto/skipjack.c index 047cf642..455d360d 100644 --- a/freebsd/sys/opencrypto/skipjack.c +++ b/freebsd/sys/opencrypto/skipjack.c @@ -67,7 +67,7 @@ static const u_int8_t ftable[0x100] = */ void -subkey_table_gen (u_int8_t *key, u_int8_t **key_tables) +subkey_table_gen (const u_int8_t *key, u_int8_t **key_tables) { int i, k; diff --git a/freebsd/sys/opencrypto/skipjack.h b/freebsd/sys/opencrypto/skipjack.h index 80367ea4..95b0b9e4 100644 --- a/freebsd/sys/opencrypto/skipjack.h +++ b/freebsd/sys/opencrypto/skipjack.h @@ -19,6 +19,6 @@ extern void skipjack_forwards(u_int8_t *plain, u_int8_t *cipher, u_int8_t **key); extern void skipjack_backwards(u_int8_t *cipher, u_int8_t *plain, u_int8_t **key); -extern void subkey_table_gen(u_int8_t *key, u_int8_t **key_tables); +extern void subkey_table_gen(const u_int8_t *key, u_int8_t **key_tables); #endif diff --git a/freebsd/sys/opencrypto/xform_aes_icm.c b/freebsd/sys/opencrypto/xform_aes_icm.c index 8d3694fa..ba3eca0a 100644 --- a/freebsd/sys/opencrypto/xform_aes_icm.c +++ b/freebsd/sys/opencrypto/xform_aes_icm.c @@ -52,11 +52,12 @@ __FBSDID("$FreeBSD$"); #include <opencrypto/xform_enc.h> -static int aes_icm_setkey(u_int8_t **, u_int8_t *, int); +static int aes_icm_setkey(u_int8_t **, const u_int8_t *, int); static void aes_icm_crypt(caddr_t, u_int8_t *); static void aes_icm_zerokey(u_int8_t **); -static void aes_icm_reinit(caddr_t, u_int8_t *); -static void aes_gcm_reinit(caddr_t, u_int8_t *); +static void aes_icm_reinit(caddr_t, const u_int8_t *); +static void aes_gcm_reinit(caddr_t, const u_int8_t *); +static void aes_ccm_reinit(caddr_t, const u_int8_t *); /* Encryption instances */ struct enc_xform enc_xform_aes_icm = { @@ -79,11 +80,23 @@ struct enc_xform enc_xform_aes_nist_gcm = { aes_gcm_reinit, }; +struct enc_xform enc_xform_ccm = { + .type = CRYPTO_AES_CCM_16, + .name = "AES-CCM", + .blocksize = AES_ICM_BLOCK_LEN, .ivsize = AES_CCM_IV_LEN, + .minkey = AES_MIN_KEY, .maxkey = AES_MAX_KEY, + .encrypt = aes_icm_crypt, + .decrypt = aes_icm_crypt, + .setkey = aes_icm_setkey, + .zerokey = aes_icm_zerokey, + .reinit = aes_ccm_reinit, +}; + /* * Encryption wrapper routines. */ static void -aes_icm_reinit(caddr_t key, u_int8_t *iv) +aes_icm_reinit(caddr_t key, const u_int8_t *iv) { struct aes_icm_ctx *ctx; @@ -92,7 +105,7 @@ aes_icm_reinit(caddr_t key, u_int8_t *iv) } static void -aes_gcm_reinit(caddr_t key, u_int8_t *iv) +aes_gcm_reinit(caddr_t key, const u_int8_t *iv) { struct aes_icm_ctx *ctx; @@ -105,6 +118,21 @@ aes_gcm_reinit(caddr_t key, u_int8_t *iv) } static void +aes_ccm_reinit(caddr_t key, const u_int8_t *iv) +{ + struct aes_icm_ctx *ctx; + + ctx = (struct aes_icm_ctx*)key; + + /* CCM has flags, then the IV, then the counter, which starts at 1 */ + bzero(ctx->ac_block, sizeof(ctx->ac_block)); + /* 3 bytes for length field; this gives a nonce of 12 bytes */ + ctx->ac_block[0] = (15 - AES_CCM_IV_LEN) - 1; + bcopy(iv, ctx->ac_block+1, AES_CCM_IV_LEN); + ctx->ac_block[AESICM_BLOCKSIZE - 1] = 1; +} + +static void aes_icm_crypt(caddr_t key, u_int8_t *data) { struct aes_icm_ctx *ctx; @@ -125,7 +153,7 @@ aes_icm_crypt(caddr_t key, u_int8_t *data) } static int -aes_icm_setkey(u_int8_t **sched, u_int8_t *key, int len) +aes_icm_setkey(u_int8_t **sched, const u_int8_t *key, int len) { struct aes_icm_ctx *ctx; @@ -138,7 +166,7 @@ aes_icm_setkey(u_int8_t **sched, u_int8_t *key, int len) return ENOMEM; ctx = (struct aes_icm_ctx *)*sched; - ctx->ac_nr = rijndaelKeySetupEnc(ctx->ac_ek, (u_char *)key, len * 8); + ctx->ac_nr = rijndaelKeySetupEnc(ctx->ac_ek, key, len * 8); return 0; } diff --git a/freebsd/sys/opencrypto/xform_aes_xts.c b/freebsd/sys/opencrypto/xform_aes_xts.c index dedbe627..33f66a5d 100644 --- a/freebsd/sys/opencrypto/xform_aes_xts.c +++ b/freebsd/sys/opencrypto/xform_aes_xts.c @@ -52,11 +52,11 @@ __FBSDID("$FreeBSD$"); #include <opencrypto/xform_enc.h> -static int aes_xts_setkey(u_int8_t **, u_int8_t *, int); +static int aes_xts_setkey(u_int8_t **, const u_int8_t *, int); static void aes_xts_encrypt(caddr_t, u_int8_t *); static void aes_xts_decrypt(caddr_t, u_int8_t *); static void aes_xts_zerokey(u_int8_t **); -static void aes_xts_reinit(caddr_t, u_int8_t *); +static void aes_xts_reinit(caddr_t, const u_int8_t *); /* Encryption instances */ struct enc_xform enc_xform_aes_xts = { @@ -73,7 +73,7 @@ struct enc_xform enc_xform_aes_xts = { * Encryption wrapper routines. */ static void -aes_xts_reinit(caddr_t key, u_int8_t *iv) +aes_xts_reinit(caddr_t key, const u_int8_t *iv) { struct aes_xts_ctx *ctx = (struct aes_xts_ctx *)key; u_int64_t blocknum; @@ -136,7 +136,7 @@ aes_xts_decrypt(caddr_t key, u_int8_t *data) } static int -aes_xts_setkey(u_int8_t **sched, u_int8_t *key, int len) +aes_xts_setkey(u_int8_t **sched, const u_int8_t *key, int len) { struct aes_xts_ctx *ctx; diff --git a/freebsd/sys/opencrypto/xform_auth.h b/freebsd/sys/opencrypto/xform_auth.h index 9af0f8e6..9b072625 100644 --- a/freebsd/sys/opencrypto/xform_auth.h +++ b/freebsd/sys/opencrypto/xform_auth.h @@ -42,6 +42,7 @@ #include <crypto/sha2/sha512.h> #include <opencrypto/rmd160.h> #include <opencrypto/gmac.h> +#include <opencrypto/cbc_mac.h> #include <opencrypto/cryptodev.h> #include <opencrypto/xform_userland.h> @@ -85,6 +86,9 @@ extern struct auth_hash auth_hash_nist_gmac_aes_256; extern struct auth_hash auth_hash_blake2b; extern struct auth_hash auth_hash_blake2s; extern struct auth_hash auth_hash_poly1305; +extern struct auth_hash auth_hash_ccm_cbc_mac_128; +extern struct auth_hash auth_hash_ccm_cbc_mac_192; +extern struct auth_hash auth_hash_ccm_cbc_mac_256; union authctx { MD5_CTX md5ctx; @@ -95,6 +99,7 @@ union authctx { SHA384_CTX sha384ctx; SHA512_CTX sha512ctx; struct aes_gmac_ctx aes_gmac_ctx; + struct aes_cbc_mac_ctx aes_cbc_mac_ctx; }; #endif /* _CRYPTO_XFORM_AUTH_H_ */ diff --git a/freebsd/sys/opencrypto/xform_blf.c b/freebsd/sys/opencrypto/xform_blf.c index b4be5f8d..d0432c99 100644 --- a/freebsd/sys/opencrypto/xform_blf.c +++ b/freebsd/sys/opencrypto/xform_blf.c @@ -53,7 +53,7 @@ __FBSDID("$FreeBSD$"); #include <crypto/blowfish/blowfish.h> #include <opencrypto/xform_enc.h> -static int blf_setkey(u_int8_t **, u_int8_t *, int); +static int blf_setkey(u_int8_t **, const u_int8_t *, int); static void blf_encrypt(caddr_t, u_int8_t *); static void blf_decrypt(caddr_t, u_int8_t *); static void blf_zerokey(u_int8_t **); @@ -104,7 +104,7 @@ blf_decrypt(caddr_t key, u_int8_t *blk) } static int -blf_setkey(u_int8_t **sched, u_int8_t *key, int len) +blf_setkey(u_int8_t **sched, const u_int8_t *key, int len) { int err; diff --git a/freebsd/sys/opencrypto/xform_cast5.c b/freebsd/sys/opencrypto/xform_cast5.c index 85b346eb..f4d9472d 100644 --- a/freebsd/sys/opencrypto/xform_cast5.c +++ b/freebsd/sys/opencrypto/xform_cast5.c @@ -53,7 +53,7 @@ __FBSDID("$FreeBSD$"); #include <opencrypto/cast.h> #include <opencrypto/xform_enc.h> -static int cast5_setkey(u_int8_t **, u_int8_t *, int); +static int cast5_setkey(u_int8_t **, const u_int8_t *, int); static void cast5_encrypt(caddr_t, u_int8_t *); static void cast5_decrypt(caddr_t, u_int8_t *); static void cast5_zerokey(u_int8_t **); @@ -85,7 +85,7 @@ cast5_decrypt(caddr_t key, u_int8_t *blk) } static int -cast5_setkey(u_int8_t **sched, u_int8_t *key, int len) +cast5_setkey(u_int8_t **sched, const u_int8_t *key, int len) { int err; diff --git a/freebsd/sys/opencrypto/xform_cbc_mac.c b/freebsd/sys/opencrypto/xform_cbc_mac.c new file mode 100644 index 00000000..1de2e976 --- /dev/null +++ b/freebsd/sys/opencrypto/xform_cbc_mac.c @@ -0,0 +1,57 @@ +#include <machine/rtems-bsd-kernel-space.h> + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <opencrypto/cbc_mac.h> +#include <opencrypto/xform_auth.h> + +/* Authentication instances */ +struct auth_hash auth_hash_ccm_cbc_mac_128 = { + .type = CRYPTO_AES_CCM_CBC_MAC, + .name = "CBC-CCM-AES-128", + .keysize = AES_128_CBC_MAC_KEY_LEN, + .hashsize = AES_CBC_MAC_HASH_LEN, + .ctxsize = sizeof(struct aes_cbc_mac_ctx), + .blocksize = CCM_CBC_BLOCK_LEN, + .Init = (void (*)(void *)) AES_CBC_MAC_Init, + .Setkey = + (void (*)(void *, const u_int8_t *, u_int16_t))AES_CBC_MAC_Setkey, + .Reinit = + (void (*)(void *, const u_int8_t *, u_int16_t)) AES_CBC_MAC_Reinit, + .Update = + (int (*)(void *, const u_int8_t *, u_int16_t)) AES_CBC_MAC_Update, + .Final = (void (*)(u_int8_t *, void *)) AES_CBC_MAC_Final, +}; +struct auth_hash auth_hash_ccm_cbc_mac_192 = { + .type = CRYPTO_AES_CCM_CBC_MAC, + .name = "CBC-CCM-AES-192", + .keysize = AES_192_CBC_MAC_KEY_LEN, + .hashsize = AES_CBC_MAC_HASH_LEN, + .ctxsize = sizeof(struct aes_cbc_mac_ctx), + .blocksize = CCM_CBC_BLOCK_LEN, + .Init = (void (*)(void *)) AES_CBC_MAC_Init, + .Setkey = + (void (*)(void *, const u_int8_t *, u_int16_t)) AES_CBC_MAC_Setkey, + .Reinit = + (void (*)(void *, const u_int8_t *, u_int16_t)) AES_CBC_MAC_Reinit, + .Update = + (int (*)(void *, const u_int8_t *, u_int16_t)) AES_CBC_MAC_Update, + .Final = (void (*)(u_int8_t *, void *)) AES_CBC_MAC_Final, +}; +struct auth_hash auth_hash_ccm_cbc_mac_256 = { + .type = CRYPTO_AES_CCM_CBC_MAC, + .name = "CBC-CCM-AES-256", + .keysize = AES_256_CBC_MAC_KEY_LEN, + .hashsize = AES_CBC_MAC_HASH_LEN, + .ctxsize = sizeof(struct aes_cbc_mac_ctx), + .blocksize = CCM_CBC_BLOCK_LEN, + .Init = (void (*)(void *)) AES_CBC_MAC_Init, + .Setkey = + (void (*)(void *, const u_int8_t *, u_int16_t)) AES_CBC_MAC_Setkey, + .Reinit = + (void (*)(void *, const u_int8_t *, u_int16_t)) AES_CBC_MAC_Reinit, + .Update = + (int (*)(void *, const u_int8_t *, u_int16_t)) AES_CBC_MAC_Update, + .Final = (void (*)(u_int8_t *, void *)) AES_CBC_MAC_Final, +}; diff --git a/freebsd/sys/opencrypto/xform_cml.c b/freebsd/sys/opencrypto/xform_cml.c index c807fa97..2f857fe6 100644 --- a/freebsd/sys/opencrypto/xform_cml.c +++ b/freebsd/sys/opencrypto/xform_cml.c @@ -53,7 +53,7 @@ __FBSDID("$FreeBSD$"); #include <crypto/camellia/camellia.h> #include <opencrypto/xform_enc.h> -static int cml_setkey(u_int8_t **, u_int8_t *, int); +static int cml_setkey(u_int8_t **, const u_int8_t *, int); static void cml_encrypt(caddr_t, u_int8_t *); static void cml_decrypt(caddr_t, u_int8_t *); static void cml_zerokey(u_int8_t **); @@ -87,7 +87,7 @@ cml_decrypt(caddr_t key, u_int8_t *blk) } static int -cml_setkey(u_int8_t **sched, u_int8_t *key, int len) +cml_setkey(u_int8_t **sched, const u_int8_t *key, int len) { int err; @@ -96,7 +96,7 @@ cml_setkey(u_int8_t **sched, u_int8_t *key, int len) *sched = KMALLOC(sizeof(camellia_ctx), M_CRYPTO_DATA, M_NOWAIT|M_ZERO); if (*sched != NULL) { - camellia_set_key((camellia_ctx *) *sched, (u_char *) key, + camellia_set_key((camellia_ctx *) *sched, key, len * 8); err = 0; } else diff --git a/freebsd/sys/opencrypto/xform_des1.c b/freebsd/sys/opencrypto/xform_des1.c index cbce5e29..0a778eef 100644 --- a/freebsd/sys/opencrypto/xform_des1.c +++ b/freebsd/sys/opencrypto/xform_des1.c @@ -53,7 +53,7 @@ __FBSDID("$FreeBSD$"); #include <crypto/des/des.h> #include <opencrypto/xform_enc.h> -static int des1_setkey(u_int8_t **, u_int8_t *, int); +static int des1_setkey(u_int8_t **, const u_int8_t *, int); static void des1_encrypt(caddr_t, u_int8_t *); static void des1_decrypt(caddr_t, u_int8_t *); static void des1_zerokey(u_int8_t **); @@ -75,23 +75,21 @@ struct enc_xform enc_xform_des = { static void des1_encrypt(caddr_t key, u_int8_t *blk) { - des_cblock *cb = (des_cblock *) blk; des_key_schedule *p = (des_key_schedule *) key; - des_ecb_encrypt(cb, cb, p[0], DES_ENCRYPT); + des_ecb_encrypt(blk, blk, p[0], DES_ENCRYPT); } static void des1_decrypt(caddr_t key, u_int8_t *blk) { - des_cblock *cb = (des_cblock *) blk; des_key_schedule *p = (des_key_schedule *) key; - des_ecb_encrypt(cb, cb, p[0], DES_DECRYPT); + des_ecb_encrypt(blk, blk, p[0], DES_DECRYPT); } static int -des1_setkey(u_int8_t **sched, u_int8_t *key, int len) +des1_setkey(u_int8_t **sched, const u_int8_t *key, int len) { des_key_schedule *p; int err; @@ -99,7 +97,7 @@ des1_setkey(u_int8_t **sched, u_int8_t *key, int len) p = KMALLOC(sizeof (des_key_schedule), M_CRYPTO_DATA, M_NOWAIT|M_ZERO); if (p != NULL) { - des_set_key((des_cblock *) key, p[0]); + des_set_key(key, p[0]); err = 0; } else err = ENOMEM; diff --git a/freebsd/sys/opencrypto/xform_des3.c b/freebsd/sys/opencrypto/xform_des3.c index 1b26b622..ea32a1ab 100644 --- a/freebsd/sys/opencrypto/xform_des3.c +++ b/freebsd/sys/opencrypto/xform_des3.c @@ -53,7 +53,7 @@ __FBSDID("$FreeBSD$"); #include <crypto/des/des.h> #include <opencrypto/xform_enc.h> -static int des3_setkey(u_int8_t **, u_int8_t *, int); +static int des3_setkey(u_int8_t **, const u_int8_t *, int); static void des3_encrypt(caddr_t, u_int8_t *); static void des3_decrypt(caddr_t, u_int8_t *); static void des3_zerokey(u_int8_t **); @@ -76,23 +76,21 @@ struct enc_xform enc_xform_3des = { static void des3_encrypt(caddr_t key, u_int8_t *blk) { - des_cblock *cb = (des_cblock *) blk; des_key_schedule *p = (des_key_schedule *) key; - des_ecb3_encrypt(cb, cb, p[0], p[1], p[2], DES_ENCRYPT); + des_ecb3_encrypt(blk, blk, p[0], p[1], p[2], DES_ENCRYPT); } static void des3_decrypt(caddr_t key, u_int8_t *blk) { - des_cblock *cb = (des_cblock *) blk; des_key_schedule *p = (des_key_schedule *) key; - des_ecb3_encrypt(cb, cb, p[0], p[1], p[2], DES_DECRYPT); + des_ecb3_encrypt(blk, blk, p[0], p[1], p[2], DES_DECRYPT); } static int -des3_setkey(u_int8_t **sched, u_int8_t *key, int len) +des3_setkey(u_int8_t **sched, const u_int8_t *key, int len) { des_key_schedule *p; int err; @@ -100,9 +98,9 @@ des3_setkey(u_int8_t **sched, u_int8_t *key, int len) p = KMALLOC(3*sizeof (des_key_schedule), M_CRYPTO_DATA, M_NOWAIT|M_ZERO); if (p != NULL) { - des_set_key((des_cblock *)(key + 0), p[0]); - des_set_key((des_cblock *)(key + 8), p[1]); - des_set_key((des_cblock *)(key + 16), p[2]); + des_set_key(key + 0, p[0]); + des_set_key(key + 8, p[1]); + des_set_key(key + 16, p[2]); err = 0; } else err = ENOMEM; diff --git a/freebsd/sys/opencrypto/xform_enc.h b/freebsd/sys/opencrypto/xform_enc.h index 545e0ec2..e2b87f5c 100644 --- a/freebsd/sys/opencrypto/xform_enc.h +++ b/freebsd/sys/opencrypto/xform_enc.h @@ -56,9 +56,9 @@ struct enc_xform { u_int16_t minkey, maxkey; void (*encrypt) (caddr_t, u_int8_t *); void (*decrypt) (caddr_t, u_int8_t *); - int (*setkey) (u_int8_t **, u_int8_t *, int len); + int (*setkey) (u_int8_t **, const u_int8_t *, int len); void (*zerokey) (u_int8_t **); - void (*reinit) (caddr_t, u_int8_t *); + void (*reinit) (caddr_t, const u_int8_t *); /* * Encrypt/decrypt 1+ blocks of input -- total size is 'len' bytes. * Len is guaranteed to be a multiple of the defined 'blocksize'. @@ -84,6 +84,7 @@ extern struct enc_xform enc_xform_aes_xts; extern struct enc_xform enc_xform_arc4; extern struct enc_xform enc_xform_camellia; extern struct enc_xform enc_xform_chacha20; +extern struct enc_xform enc_xform_ccm; struct aes_icm_ctx { u_int32_t ac_ek[4*(RIJNDAEL_MAXNR + 1)]; diff --git a/freebsd/sys/opencrypto/xform_null.c b/freebsd/sys/opencrypto/xform_null.c index 3c499b31..28f20bdf 100644 --- a/freebsd/sys/opencrypto/xform_null.c +++ b/freebsd/sys/opencrypto/xform_null.c @@ -53,7 +53,7 @@ __FBSDID("$FreeBSD$"); #include <opencrypto/xform_auth.h> #include <opencrypto/xform_enc.h> -static int null_setkey(u_int8_t **, u_int8_t *, int); +static int null_setkey(u_int8_t **, const u_int8_t *, int); static void null_encrypt(caddr_t, u_int8_t *); static void null_decrypt(caddr_t, u_int8_t *); static void null_zerokey(u_int8_t **); @@ -104,7 +104,7 @@ null_decrypt(caddr_t key, u_int8_t *blk) } static int -null_setkey(u_int8_t **sched, u_int8_t *key, int len) +null_setkey(u_int8_t **sched, const u_int8_t *key, int len) { *sched = NULL; return 0; diff --git a/freebsd/sys/opencrypto/xform_rijndael.c b/freebsd/sys/opencrypto/xform_rijndael.c index 2c974f3d..378e86c0 100644 --- a/freebsd/sys/opencrypto/xform_rijndael.c +++ b/freebsd/sys/opencrypto/xform_rijndael.c @@ -53,7 +53,7 @@ __FBSDID("$FreeBSD$"); #include <crypto/rijndael/rijndael.h> #include <opencrypto/xform_enc.h> -static int rijndael128_setkey(u_int8_t **, u_int8_t *, int); +static int rijndael128_setkey(u_int8_t **, const u_int8_t *, int); static void rijndael128_encrypt(caddr_t, u_int8_t *); static void rijndael128_decrypt(caddr_t, u_int8_t *); static void rijndael128_zerokey(u_int8_t **); @@ -87,7 +87,7 @@ rijndael128_decrypt(caddr_t key, u_int8_t *blk) } static int -rijndael128_setkey(u_int8_t **sched, u_int8_t *key, int len) +rijndael128_setkey(u_int8_t **sched, const u_int8_t *key, int len) { int err; @@ -96,7 +96,7 @@ rijndael128_setkey(u_int8_t **sched, u_int8_t *key, int len) *sched = KMALLOC(sizeof(rijndael_ctx), M_CRYPTO_DATA, M_NOWAIT|M_ZERO); if (*sched != NULL) { - rijndael_set_key((rijndael_ctx *) *sched, (u_char *) key, + rijndael_set_key((rijndael_ctx *) *sched, key, len * 8); err = 0; } else diff --git a/freebsd/sys/opencrypto/xform_skipjack.c b/freebsd/sys/opencrypto/xform_skipjack.c index 94090d0d..22d74b36 100644 --- a/freebsd/sys/opencrypto/xform_skipjack.c +++ b/freebsd/sys/opencrypto/xform_skipjack.c @@ -53,7 +53,7 @@ __FBSDID("$FreeBSD$"); #include <opencrypto/skipjack.h> #include <opencrypto/xform_enc.h> -static int skipjack_setkey(u_int8_t **, u_int8_t *, int); +static int skipjack_setkey(u_int8_t **, const u_int8_t *, int); static void skipjack_encrypt(caddr_t, u_int8_t *); static void skipjack_decrypt(caddr_t, u_int8_t *); static void skipjack_zerokey(u_int8_t **); @@ -85,7 +85,7 @@ skipjack_decrypt(caddr_t key, u_int8_t *blk) } static int -skipjack_setkey(u_int8_t **sched, u_int8_t *key, int len) +skipjack_setkey(u_int8_t **sched, const u_int8_t *key, int len) { int err; |