diff options
author | Renato Botelho <renato@netgate.com> | 2015-08-17 13:53:21 -0300 |
---|---|---|
committer | Renato Botelho <renato@netgate.com> | 2015-08-17 13:53:21 -0300 |
commit | 46e99a8858f1c843c1774e472c11d422ca2163ae (patch) | |
tree | 485743dc4862158e7bb3b19eccf8f9b54fb8927b /sys/opencrypto | |
parent | fb8160d0fb248c35e8bc74d67dcca6c22e974db3 (diff) | |
download | FreeBSD-src-46e99a8858f1c843c1774e472c11d422ca2163ae.zip FreeBSD-src-46e99a8858f1c843c1774e472c11d422ca2163ae.tar.gz |
Importing pfSense patch aesgcm.soft.1.patch
Diffstat (limited to 'sys/opencrypto')
-rw-r--r-- | sys/opencrypto/cryptodev.c | 20 | ||||
-rw-r--r-- | sys/opencrypto/cryptodev.h | 31 | ||||
-rw-r--r-- | sys/opencrypto/cryptosoft.c | 223 | ||||
-rw-r--r-- | sys/opencrypto/gmac.c | 165 | ||||
-rw-r--r-- | sys/opencrypto/gmac.h | 48 | ||||
-rw-r--r-- | sys/opencrypto/xform.c | 267 | ||||
-rw-r--r-- | sys/opencrypto/xform.h | 18 |
7 files changed, 704 insertions, 68 deletions
diff --git a/sys/opencrypto/cryptodev.c b/sys/opencrypto/cryptodev.c index 44bfa5c..9b27ef0 100644 --- a/sys/opencrypto/cryptodev.c +++ b/sys/opencrypto/cryptodev.c @@ -434,6 +434,16 @@ cryptof_ioctl( case CRYPTO_CAMELLIA_CBC: txform = &enc_xform_camellia; break; + case CRYPTO_AES_CTR: + txform = &enc_xform_aes_ctr; + break; + case CRYPTO_AES_RFC4106_GCM_16: + txform = &enc_xform_aes_gcm; + break; + case CRYPTO_AES_GMAC: + txform = &enc_xform_aes_gmac; + break; + default: return (EINVAL); } @@ -459,6 +469,16 @@ cryptof_ioctl( case CRYPTO_RIPEMD160_HMAC: thash = &auth_hash_hmac_ripemd_160; break; + case CRYPTO_AES_128_GMAC: + thash = &auth_hash_gmac_aes_128; + break; + case CRYPTO_AES_192_GMAC: + thash = &auth_hash_gmac_aes_192; + break; + case CRYPTO_AES_256_GMAC: + thash = &auth_hash_gmac_aes_256; + break; + #ifdef notdef case CRYPTO_MD5: thash = &auth_hash_md5; diff --git a/sys/opencrypto/cryptodev.h b/sys/opencrypto/cryptodev.h index e299522..1476235 100644 --- a/sys/opencrypto/cryptodev.h +++ b/sys/opencrypto/cryptodev.h @@ -72,6 +72,7 @@ #define SHA2_512_HASH_LEN 64 #define MD5_KPDK_HASH_LEN 16 #define SHA1_KPDK_HASH_LEN 20 +#define AES_GMAC_HASH_LEN 16 /* Maximum hash algorithm result length */ #define HASH_MAX_LEN SHA2_512_HASH_LEN /* Keep this updated */ @@ -100,6 +101,17 @@ #define CAMELLIA_BLOCK_LEN 16 #define EALG_MAX_BLOCK_LEN AES_BLOCK_LEN /* Keep this updated */ +/* Maximum hash algorithm result length */ +#define AALG_MAX_RESULT_LEN 64 /* Keep this updated */ + +#define AESCTR_NONCESIZE 4 +#define AESCTR_IVSIZE 8 +#define AESCTR_BLOCKSIZE AES_BLOCK_LEN + +#define AES_XTS_BLOCKSIZE AES_BLOCK_LEN +#define AES_XTS_IVSIZE 8 +#define AES_XTS_ALPHA 0x87 /* GF(2^128) generator polynomial */ + #define CRYPTO_ALGORITHM_MIN 1 #define CRYPTO_DES_CBC 1 #define CRYPTO_3DES_CBC 2 @@ -122,9 +134,15 @@ #define CRYPTO_SHA2_256_HMAC 18 #define CRYPTO_SHA2_384_HMAC 19 #define CRYPTO_SHA2_512_HMAC 20 -#define CRYPTO_CAMELLIA_CBC 21 +#define CRYPTO_CAMELLIA_CBC 21 #define CRYPTO_AES_XTS 22 -#define CRYPTO_ALGORITHM_MAX 22 /* Keep updated - see below */ +#define CRYPTO_AES_CTR 23 +#define CRYPTO_AES_RFC4106_GCM_16 24 +#define CRYPTO_AES_128_GMAC 25 +#define CRYPTO_AES_192_GMAC 26 +#define CRYPTO_AES_256_GMAC 27 +#define CRYPTO_AES_GMAC 28 +#define CRYPTO_ALGORITHM_MAX 28 /* Keep updated - see below */ /* Algorithm flags */ #define CRYPTO_ALG_FLAG_SUPPORTED 0x01 /* Algorithm is supported */ @@ -276,7 +294,12 @@ struct cryptoini { int cri_mlen; /* Number of bytes we want from the entire hash. 0 means all. */ caddr_t cri_key; /* key to use */ - u_int8_t cri_iv[EALG_MAX_BLOCK_LEN]; /* IV to use */ + union { + u_int8_t iv[EALG_MAX_BLOCK_LEN]; /* IV to use */ + u_int8_t esn[4]; /* high-order ESN */ + } u; +#define cri_iv u.iv +#define cri_esn u.esn struct cryptoini *cri_next; }; @@ -294,8 +317,10 @@ struct cryptodesc { #define CRD_F_DSA_SHA_NEEDED 0x08 /* Compute SHA-1 of buffer for DSA */ #define CRD_F_KEY_EXPLICIT 0x10 /* Key explicitly provided */ #define CRD_F_COMP 0x0f /* Set when doing compression */ +#define CRD_F_ESN 0x20 /* Set when doing compression */ struct cryptoini CRD_INI; /* Initialization/context data */ +#define crd_esn CRD_INI.cri_esn #define crd_iv CRD_INI.cri_iv #define crd_key CRD_INI.cri_key #define crd_alg CRD_INI.cri_alg diff --git a/sys/opencrypto/cryptosoft.c b/sys/opencrypto/cryptosoft.c index d73f462..f60c30e 100644 --- a/sys/opencrypto/cryptosoft.c +++ b/sys/opencrypto/cryptosoft.c @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include <sys/random.h> #include <sys/kernel.h> #include <sys/uio.h> +#include <sys/endian.h> #include <crypto/blowfish/blowfish.h> #include <crypto/sha1.h> @@ -60,6 +61,7 @@ u_int8_t hmac_opad_buffer[HMAC_MAX_BLOCK_LEN]; static int swcr_encdec(struct cryptodesc *, struct swcr_data *, caddr_t, int); static int swcr_authcompute(struct cryptodesc *, struct swcr_data *, caddr_t, int); +static int swcr_authenc(struct cryptop *crp); static int swcr_compdec(struct cryptodesc *, struct swcr_data *, caddr_t, int); static int swcr_freesession(device_t dev, u_int64_t tid); @@ -86,21 +88,21 @@ swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf, if (crd->crd_flags & CRD_F_ENCRYPT) { /* IV explicitly provided ? */ if (crd->crd_flags & CRD_F_IV_EXPLICIT) - bcopy(crd->crd_iv, iv, blks); + bcopy(crd->crd_iv, iv, exf->ivsize); else - arc4rand(iv, blks, 0); + arc4rand(iv, exf->ivsize, 0); /* Do we need to write the IV */ if (!(crd->crd_flags & CRD_F_IV_PRESENT)) - crypto_copyback(flags, buf, crd->crd_inject, blks, iv); + crypto_copyback(flags, buf, crd->crd_inject, exf->ivsize, iv); } else { /* Decryption */ /* IV explicitly provided ? */ if (crd->crd_flags & CRD_F_IV_EXPLICIT) - bcopy(crd->crd_iv, iv, blks); + bcopy(crd->crd_iv, iv, exf->ivsize); else { /* Get IV off buf */ - crypto_copydata(flags, buf, crd->crd_inject, blks, iv); + crypto_copydata(flags, buf, crd->crd_inject, exf->ivsize, iv); } } @@ -579,6 +581,165 @@ swcr_authcompute(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf, } /* + * Apply a combined encryption-authentication transformation + */ +static int +swcr_authenc(struct cryptop *crp) +{ + uint32_t blkbuf[howmany(EALG_MAX_BLOCK_LEN, sizeof(uint32_t))]; + u_char *blk = (u_char *)blkbuf; + u_char aalg[AALG_MAX_RESULT_LEN]; + u_char iv[EALG_MAX_BLOCK_LEN]; + union authctx ctx; + struct cryptodesc *crd, *crda = NULL, *crde = NULL; + struct swcr_data *sw, *swa, *swe = NULL; + struct auth_hash *axf = NULL; + struct enc_xform *exf = NULL; + caddr_t buf = (caddr_t)crp->crp_buf; + uint32_t *blkp; + int aadlen, blksz, i, ivlen, len, iskip, oskip; + + ivlen = blksz = iskip = oskip = 0; + + for (crd = crp->crp_desc; crd; crd = crd->crd_next) { + for (sw = swcr_sessions[crp->crp_sid & 0xffffffff]; + sw && sw->sw_alg != crd->crd_alg; + sw = sw->sw_next) + ; + if (sw == NULL) + return (EINVAL); + + switch (sw->sw_alg) { + case CRYPTO_AES_RFC4106_GCM_16: + case CRYPTO_AES_GMAC: + swe = sw; + crde = crd; + exf = swe->sw_exf; + ivlen = exf->ivsize; + break; + case CRYPTO_AES_128_GMAC: + case CRYPTO_AES_192_GMAC: + case CRYPTO_AES_256_GMAC: + swa = sw; + crda = crd; + axf = swa->sw_axf; + if (swa->sw_ictx == 0) + return (EINVAL); + bcopy(swa->sw_ictx, &ctx, axf->ctxsize); + blksz = axf->blocksize; + break; + default: + return (EINVAL); + } + } + if (crde == NULL || crda == NULL) + return (EINVAL); + + /* Initialize the IV */ + if (crde->crd_flags & CRD_F_ENCRYPT) { + /* IV explicitly provided ? */ + if (crde->crd_flags & CRD_F_IV_EXPLICIT) + bcopy(crde->crd_iv, iv, ivlen); + else + arc4rand(iv, ivlen, 0); + + /* Do we need to write the IV */ + if (!(crde->crd_flags & CRD_F_IV_PRESENT)) + crypto_copyback(crp->crp_flags, buf, crde->crd_inject, + ivlen, iv); + + } else { /* Decryption */ + /* IV explicitly provided ? */ + if (crde->crd_flags & CRD_F_IV_EXPLICIT) + bcopy(crde->crd_iv, iv, ivlen); + else { + /* Get IV off buf */ + crypto_copydata(crp->crp_flags, buf, crde->crd_inject, + ivlen, iv); + } + } + + /* Supply MAC with IV */ + if (axf->Reinit) + axf->Reinit(&ctx, iv, ivlen); + + /* Supply MAC with AAD */ + aadlen = crda->crd_len; + /* + * Section 5 of RFC 4106 specifies that AAD construction consists of + * {SPI, ESN, SN} whereas the real packet contains only {SPI, SN}. + * Unfortunately it doesn't follow a good example set in the Section + * 3.3.2.1 of RFC 4303 where upper part of the ESN, located in the + * external (to the packet) memory buffer, is processed by the hash + * function in the end thus allowing to retain simple programming + * interfaces and avoid kludges like the one below. + */ + if (crda->crd_flags & CRD_F_ESN) { + aadlen += 4; + /* SPI */ + crypto_copydata(crp->crp_flags, buf, crda->crd_skip, 4, blk); + iskip = 4; /* loop below will start with an offset of 4 */ + /* ESN */ + bcopy(crda->crd_esn, blk + 4, 4); + oskip = iskip + 4; /* offset output buffer blk by 8 */ + } + for (i = iskip; i < crda->crd_len; i += blksz) { + len = MIN(crda->crd_len - i, blksz - oskip); + crypto_copydata(crp->crp_flags, buf, crda->crd_skip + i, len, + blk + oskip); + bzero(blk + len + oskip, blksz - len - oskip); + axf->Update(&ctx, blk, blksz); + oskip = 0; /* reset initial output offset */ + } + + if (exf->reinit) + exf->reinit(swe->sw_kschedule, iv); + + /* Do encryption/decryption with MAC */ + for (i = 0; i < crde->crd_len; i += blksz) { + len = MIN(crde->crd_len - i, blksz); + if (len < blksz) + bzero(blk, blksz); + crypto_copydata(crp->crp_flags, buf, crde->crd_skip + i, len, + blk); + if (crde->crd_flags & CRD_F_ENCRYPT) { + exf->encrypt(swe->sw_kschedule, blk); + axf->Update(&ctx, blk, len); + } else { + axf->Update(&ctx, blk, len); + exf->decrypt(swe->sw_kschedule, blk); + } + crypto_copyback(crp->crp_flags, buf, crde->crd_skip + i, len, + blk); + } + + /* Do any required special finalization */ + switch (crda->crd_alg) { + case CRYPTO_AES_128_GMAC: + case CRYPTO_AES_192_GMAC: + case CRYPTO_AES_256_GMAC: + /* length block */ + bzero(blk, blksz); + blkp = (uint32_t *)blk + 1; + *blkp = htobe32(aadlen * 8); + blkp = (uint32_t *)blk + 3; + *blkp = htobe32(crde->crd_len * 8); + axf->Update(&ctx, blk, blksz); + break; + } + + /* Finalize MAC */ + axf->Final(aalg, &ctx); + + /* Inject the authentication data */ + crypto_copyback(crp->crp_flags, buf, crda->crd_inject, + crp->crp_ilen - crda->crd_inject, + aalg); + + return (0); +} + +/* * Apply a compression/decompression algorithm */ static int @@ -738,6 +899,16 @@ swcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri) case CRYPTO_AES_XTS: txf = &enc_xform_aes_xts; goto enccommon; + case CRYPTO_AES_CTR: + txf = &enc_xform_aes_ctr; + goto enccommon; + case CRYPTO_AES_RFC4106_GCM_16: + txf = &enc_xform_aes_gcm; + goto enccommon; + case CRYPTO_AES_GMAC: + txf = &enc_xform_aes_gmac; + (*swd)->sw_exf = txf; + break; case CRYPTO_CAMELLIA_CBC: txf = &enc_xform_camellia; goto enccommon; @@ -850,6 +1021,30 @@ swcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri) (*swd)->sw_axf = axf; break; #endif + + case CRYPTO_AES_128_GMAC: + axf = &auth_hash_gmac_aes_128; + goto auth4common; + + case CRYPTO_AES_192_GMAC: + axf = &auth_hash_gmac_aes_192; + goto auth4common; + + case CRYPTO_AES_256_GMAC: + axf = &auth_hash_gmac_aes_256; + auth4common: + (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, + M_NOWAIT); + if ((*swd)->sw_ictx == NULL) { + swcr_freesession(dev, i); + return ENOBUFS; + } + axf->Init((*swd)->sw_ictx); + axf->Setkey((*swd)->sw_ictx, cri->cri_key, + cri->cri_klen / 8); + (*swd)->sw_axf = axf; + break; + case CRYPTO_DEFLATE_COMP: cxf = &comp_algo_deflate; (*swd)->sw_cxf = cxf; @@ -897,6 +1092,9 @@ swcr_freesession(device_t dev, u_int64_t tid) case CRYPTO_SKIPJACK_CBC: case CRYPTO_RIJNDAEL128_CBC: case CRYPTO_AES_XTS: + case CRYPTO_AES_CTR: + case CRYPTO_AES_RFC4106_GCM_16: + case CRYPTO_AES_GMAC: case CRYPTO_CAMELLIA_CBC: case CRYPTO_NULL_CBC: txf = swd->sw_exf; @@ -1011,6 +1209,7 @@ swcr_process(device_t dev, struct cryptop *crp, int hint) case CRYPTO_SKIPJACK_CBC: case CRYPTO_RIJNDAEL128_CBC: case CRYPTO_AES_XTS: + case CRYPTO_AES_CTR: case CRYPTO_CAMELLIA_CBC: if ((crp->crp_etype = swcr_encdec(crd, sw, crp->crp_buf, crp->crp_flags)) != 0) @@ -1035,6 +1234,14 @@ swcr_process(device_t dev, struct cryptop *crp, int hint) goto done; break; + case CRYPTO_AES_RFC4106_GCM_16: + case CRYPTO_AES_GMAC: + case CRYPTO_AES_128_GMAC: + case CRYPTO_AES_192_GMAC: + case CRYPTO_AES_256_GMAC: + crp->crp_etype = swcr_authenc(crp); + goto done; + case CRYPTO_DEFLATE_COMP: if ((crp->crp_etype = swcr_compdec(crd, sw, crp->crp_buf, crp->crp_flags)) != 0) @@ -1104,6 +1311,12 @@ swcr_attach(device_t dev) REGISTER(CRYPTO_SHA1); REGISTER(CRYPTO_RIJNDAEL128_CBC); REGISTER(CRYPTO_AES_XTS); + REGISTER(CRYPTO_AES_CTR); + REGISTER(CRYPTO_AES_RFC4106_GCM_16); + REGISTER(CRYPTO_AES_GMAC); + REGISTER(CRYPTO_AES_128_GMAC); + REGISTER(CRYPTO_AES_192_GMAC); + REGISTER(CRYPTO_AES_256_GMAC); REGISTER(CRYPTO_CAMELLIA_CBC); REGISTER(CRYPTO_DEFLATE_COMP); #undef REGISTER diff --git a/sys/opencrypto/gmac.c b/sys/opencrypto/gmac.c new file mode 100644 index 0000000..b95e3bb --- /dev/null +++ b/sys/opencrypto/gmac.c @@ -0,0 +1,165 @@ +/* $OpenBSD: gmac.c,v 1.3 2011/01/11 15:44:23 deraadt Exp $ */ + +/* + * Copyright (c) 2010 Mike Belopuhov <mike@vantronix.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This code implements the Message Authentication part of the + * Galois/Counter Mode (as being described in the RFC 4543) using + * the AES cipher. FIPS SP 800-38D describes the algorithm details. + */ + +#ifdef _KERNEL +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/endian.h> +#else +#include <sys/types.h> +#include <sys/endian.h> +#include <stdint.h> +#include <string.h> +#endif + +#include <crypto/rijndael/rijndael.h> +#include <opencrypto/gmac.h> + +void ghash_gfmul(uint32_t *, uint32_t *, uint32_t *); +void ghash_update(GHASH_CTX *, uint8_t *, size_t); + +/* Computes a block multiplication in the GF(2^128) */ +void +ghash_gfmul(uint32_t *X, uint32_t *Y, uint32_t *product) +{ + uint32_t v[4]; + uint32_t z[4] = { 0, 0, 0, 0}; + uint8_t *x = (uint8_t *)X; + uint32_t mul; + int i; + + v[0] = be32toh(Y[0]); + v[1] = be32toh(Y[1]); + v[2] = be32toh(Y[2]); + v[3] = be32toh(Y[3]); + + for (i = 0; i < GMAC_BLOCK_LEN * 8; i++) { + /* update Z */ + if (x[i >> 3] & (1 << (~i & 7))) { + z[0] ^= v[0]; + z[1] ^= v[1]; + z[2] ^= v[2]; + z[3] ^= v[3]; + } /* else: we preserve old values */ + + /* update V */ + mul = v[3] & 1; + v[3] = (v[2] << 31) | (v[3] >> 1); + v[2] = (v[1] << 31) | (v[2] >> 1); + v[1] = (v[0] << 31) | (v[1] >> 1); + v[0] = (v[0] >> 1) ^ (0xe1000000 * mul); + } + + product[0] = htobe32(z[0]); + product[1] = htobe32(z[1]); + product[2] = htobe32(z[2]); + product[3] = htobe32(z[3]); +} + +void +ghash_update(GHASH_CTX *ctx, uint8_t *X, size_t len) +{ + uint32_t *x = (uint32_t *)X; + uint32_t *s = (uint32_t *)ctx->S; + uint32_t *y = (uint32_t *)ctx->Z; + int i; + + for (i = 0; i < len / GMAC_BLOCK_LEN; i++) { + s[0] = y[0] ^ x[0]; + s[1] = y[1] ^ x[1]; + s[2] = y[2] ^ x[2]; + s[3] = y[3] ^ x[3]; + + ghash_gfmul((uint32_t *)ctx->S, (uint32_t *)ctx->H, + (uint32_t *)ctx->S); + + y = s; + x += 4; + } + + bcopy(ctx->S, ctx->Z, GMAC_BLOCK_LEN); +} + +#ifndef AESCTR_NONCESIZE +#define AESCTR_NONCESIZE 4 +#endif + +void +AES_GMAC_Init(AES_GMAC_CTX *ctx) +{ + bzero(ctx->ghash.H, GMAC_BLOCK_LEN); + bzero(ctx->ghash.S, GMAC_BLOCK_LEN); + bzero(ctx->ghash.Z, GMAC_BLOCK_LEN); + bzero(ctx->J, GMAC_BLOCK_LEN); +} + +void +AES_GMAC_Setkey(AES_GMAC_CTX *ctx, const uint8_t *key, uint16_t klen) +{ + ctx->rounds = rijndaelKeySetupEnc(ctx->K, (u_char *)key, + (klen - AESCTR_NONCESIZE) * 8); + /* copy out salt to the counter block */ + bcopy(key + klen - AESCTR_NONCESIZE, ctx->J, AESCTR_NONCESIZE); + /* prepare a hash subkey */ + rijndaelEncrypt(ctx->K, ctx->rounds, ctx->ghash.H, ctx->ghash.H); +} + +void +AES_GMAC_Reinit(AES_GMAC_CTX *ctx, const uint8_t *iv, uint16_t ivlen) +{ + /* copy out IV to the counter block */ + bcopy(iv, ctx->J + AESCTR_NONCESIZE, ivlen); +} + +int +AES_GMAC_Update(AES_GMAC_CTX *ctx, const uint8_t *data, uint16_t len) +{ + uint8_t blk[16] = {}; + int plen; + + if (len > 0) { + plen = len % GMAC_BLOCK_LEN; + if (len >= GMAC_BLOCK_LEN) + ghash_update(&ctx->ghash, (uint8_t *)data, len - plen); + if (plen) { + bcopy((uint8_t *)data + (len - plen), blk, plen); + ghash_update(&ctx->ghash, blk, GMAC_BLOCK_LEN); + } + } + return (0); +} + +void +AES_GMAC_Final(uint8_t digest[GMAC_DIGEST_LEN], AES_GMAC_CTX *ctx) +{ + uint8_t keystream[GMAC_BLOCK_LEN]; + int i; + + /* do one round of GCTR */ + ctx->J[GMAC_BLOCK_LEN - 1] = 1; + rijndaelEncrypt(ctx->K, ctx->rounds, ctx->J, keystream); + for (i = 0; i < GMAC_DIGEST_LEN; i++) + digest[i] = ctx->ghash.S[i] ^ keystream[i]; + bzero(keystream, sizeof(keystream)); +} diff --git a/sys/opencrypto/gmac.h b/sys/opencrypto/gmac.h new file mode 100644 index 0000000..94137da --- /dev/null +++ b/sys/opencrypto/gmac.h @@ -0,0 +1,48 @@ +/* $OpenBSD: gmac.h,v 1.2 2012/12/05 23:20:15 deraadt Exp $ */ + +/* + * Copyright (c) 2010 Mike Belopuhov <mike@vantronix.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _GMAC_H_ +#define _GMAC_H_ + +#include <crypto/rijndael/rijndael.h> + +#define GMAC_BLOCK_LEN 16 +#define GMAC_DIGEST_LEN 16 + +typedef struct _GHASH_CTX { + uint8_t H[GMAC_BLOCK_LEN]; /* hash subkey */ + uint8_t S[GMAC_BLOCK_LEN]; /* state */ + uint8_t Z[GMAC_BLOCK_LEN]; /* initial state */ +} GHASH_CTX; + +typedef struct _AES_GMAC_CTX { + GHASH_CTX ghash; + uint32_t K[4*(RIJNDAEL_MAXNR + 1)]; + uint8_t J[GMAC_BLOCK_LEN]; /* counter block */ + int rounds; +} AES_GMAC_CTX; + +__BEGIN_DECLS +void AES_GMAC_Init(AES_GMAC_CTX *); +void AES_GMAC_Setkey(AES_GMAC_CTX *, const uint8_t *, uint16_t); +void AES_GMAC_Reinit(AES_GMAC_CTX *, const uint8_t *, uint16_t); +int AES_GMAC_Update(AES_GMAC_CTX *, const uint8_t *, uint16_t); +void AES_GMAC_Final(uint8_t [GMAC_DIGEST_LEN], AES_GMAC_CTX *); +__END_DECLS + +#endif /* _GMAC_H_ */ diff --git a/sys/opencrypto/xform.c b/sys/opencrypto/xform.c index bfb061b..faa9c4a 100644 --- a/sys/opencrypto/xform.c +++ b/sys/opencrypto/xform.c @@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$"); #include <opencrypto/deflate.h> #include <opencrypto/rmd160.h> #include <opencrypto/skipjack.h> +#include <opencrypto/gmac.h> #include <sys/md5.h> @@ -76,6 +77,7 @@ static int blf_setkey(u_int8_t **, u_int8_t *, int); static int cast5_setkey(u_int8_t **, u_int8_t *, int); static int skipjack_setkey(u_int8_t **, u_int8_t *, int); static int rijndael128_setkey(u_int8_t **, u_int8_t *, int); +static int aes_ctr_setkey(u_int8_t **, u_int8_t *, int); static int aes_xts_setkey(u_int8_t **, u_int8_t *, int); static int cml_setkey(u_int8_t **, u_int8_t *, int); @@ -99,6 +101,8 @@ static void rijndael128_decrypt(caddr_t, u_int8_t *); static void aes_xts_decrypt(caddr_t, u_int8_t *); static void cml_decrypt(caddr_t, u_int8_t *); +static void aes_ctr_crypt(caddr_t, u_int8_t *); + static void null_zerokey(u_int8_t **); static void des1_zerokey(u_int8_t **); static void des3_zerokey(u_int8_t **); @@ -106,103 +110,148 @@ static void blf_zerokey(u_int8_t **); static void cast5_zerokey(u_int8_t **); static void skipjack_zerokey(u_int8_t **); static void rijndael128_zerokey(u_int8_t **); +static void aes_ctr_zerokey(u_int8_t **); static void aes_xts_zerokey(u_int8_t **); static void cml_zerokey(u_int8_t **); +static void aes_ctr_reinit(caddr_t, u_int8_t *); static void aes_xts_reinit(caddr_t, u_int8_t *); +static void aes_gcm_reinit(caddr_t, u_int8_t *); static void null_init(void *); -static int null_update(void *, u_int8_t *, u_int16_t); +static void null_reinit(void *ctx, const u_int8_t *buf, u_int16_t len); +static int null_update(void *, const u_int8_t *, u_int16_t); static void null_final(u_int8_t *, void *); -static int MD5Update_int(void *, u_int8_t *, u_int16_t); +static int MD5Update_int(void *, const u_int8_t *, u_int16_t); static void SHA1Init_int(void *); -static int SHA1Update_int(void *, u_int8_t *, u_int16_t); +static int SHA1Update_int(void *, const u_int8_t *, u_int16_t); static void SHA1Final_int(u_int8_t *, void *); -static int RMD160Update_int(void *, u_int8_t *, u_int16_t); -static int SHA256Update_int(void *, u_int8_t *, u_int16_t); -static int SHA384Update_int(void *, u_int8_t *, u_int16_t); -static int SHA512Update_int(void *, u_int8_t *, u_int16_t); +static int RMD160Update_int(void *, const u_int8_t *, u_int16_t); +static int SHA256Update_int(void *, const u_int8_t *, u_int16_t); +static int SHA384Update_int(void *, const u_int8_t *, u_int16_t); +static int SHA512Update_int(void *, const u_int8_t *, u_int16_t); static u_int32_t deflate_compress(u_int8_t *, u_int32_t, u_int8_t **); static u_int32_t deflate_decompress(u_int8_t *, u_int32_t, u_int8_t **); +struct aes_ctr_ctx { + u_int32_t ac_ek[4*(RIJNDAEL_MAXNR + 1)]; + /* + * ac_block is initalized to: [ NONCE : IV : CNTR ] + * Where NONCE is the last four bytes of the key. + * IV is provided by user. + * CNTR is initalized to 0 for CTR and 1 for GCM. + */ + u_int8_t ac_block[AESCTR_BLOCKSIZE]; + int ac_nr; +}; + MALLOC_DEFINE(M_XDATA, "xform", "xform data buffers"); /* Encryption instances */ struct enc_xform enc_xform_null = { CRYPTO_NULL_CBC, "NULL", /* NB: blocksize of 4 is to generate a properly aligned ESP header */ - NULL_BLOCK_LEN, 0, 256, /* 2048 bits, max key */ + NULL_BLOCK_LEN, 0, 0, 256, /* 2048 bits, max key */ null_encrypt, null_decrypt, null_setkey, null_zerokey, - NULL + NULL, }; struct enc_xform enc_xform_des = { CRYPTO_DES_CBC, "DES", - DES_BLOCK_LEN, 8, 8, + DES_BLOCK_LEN, DES_BLOCK_LEN, 8, 8, des1_encrypt, des1_decrypt, des1_setkey, des1_zerokey, - NULL + NULL, }; struct enc_xform enc_xform_3des = { CRYPTO_3DES_CBC, "3DES", - DES3_BLOCK_LEN, 24, 24, + DES3_BLOCK_LEN, DES3_BLOCK_LEN, 24, 24, des3_encrypt, des3_decrypt, des3_setkey, des3_zerokey, - NULL + NULL, }; struct enc_xform enc_xform_blf = { CRYPTO_BLF_CBC, "Blowfish", - BLOWFISH_BLOCK_LEN, 5, 56 /* 448 bits, max key */, + BLOWFISH_BLOCK_LEN, BLOWFISH_BLOCK_LEN, 5, 56 /* 448 bits, max key */, blf_encrypt, blf_decrypt, blf_setkey, blf_zerokey, - NULL + NULL, }; struct enc_xform enc_xform_cast5 = { CRYPTO_CAST_CBC, "CAST-128", - CAST128_BLOCK_LEN, 5, 16, + CAST128_BLOCK_LEN, CAST128_BLOCK_LEN, 5, 16, cast5_encrypt, cast5_decrypt, cast5_setkey, cast5_zerokey, - NULL + NULL, }; struct enc_xform enc_xform_skipjack = { CRYPTO_SKIPJACK_CBC, "Skipjack", - SKIPJACK_BLOCK_LEN, 10, 10, + SKIPJACK_BLOCK_LEN, SKIPJACK_BLOCK_LEN, 10, 10, skipjack_encrypt, - skipjack_decrypt, - skipjack_setkey, + skipjack_decrypt, skipjack_setkey, skipjack_zerokey, - NULL + NULL, }; struct enc_xform enc_xform_rijndael128 = { CRYPTO_RIJNDAEL128_CBC, "Rijndael-128/AES", - RIJNDAEL128_BLOCK_LEN, 8, 32, + RIJNDAEL128_BLOCK_LEN, 16, 8, 32, rijndael128_encrypt, rijndael128_decrypt, rijndael128_setkey, rijndael128_zerokey, - NULL + NULL, +}; + +struct enc_xform enc_xform_aes_ctr = { + CRYPTO_AES_CTR, "AES-CTR", + AESCTR_BLOCKSIZE, AESCTR_IVSIZE, 8+AESCTR_NONCESIZE, 32+AESCTR_NONCESIZE, + aes_ctr_crypt, + aes_ctr_crypt, + aes_ctr_setkey, + rijndael128_zerokey, + aes_ctr_reinit, +}; + +struct enc_xform enc_xform_aes_gcm = { + CRYPTO_AES_RFC4106_GCM_16, "AES-GCM", + RIJNDAEL128_BLOCK_LEN, AESCTR_IVSIZE, 16+AESCTR_NONCESIZE, 32+AESCTR_NONCESIZE, + aes_ctr_crypt, + aes_ctr_crypt, + aes_ctr_setkey, + aes_ctr_zerokey, + aes_gcm_reinit, +}; + +struct enc_xform enc_xform_aes_gmac = { + CRYPTO_AES_GMAC, "AES-GMAC", + RIJNDAEL128_BLOCK_LEN, 8, 16+4, 32+4, + NULL, + NULL, + NULL, + NULL, + NULL, }; struct enc_xform enc_xform_aes_xts = { CRYPTO_AES_XTS, "AES-XTS", - RIJNDAEL128_BLOCK_LEN, 32, 64, + RIJNDAEL128_BLOCK_LEN, 8, 32, 64, aes_xts_encrypt, aes_xts_decrypt, aes_xts_setkey, @@ -212,85 +261,115 @@ struct enc_xform enc_xform_aes_xts = { struct enc_xform enc_xform_arc4 = { CRYPTO_ARC4, "ARC4", - 1, 1, 32, + 1, 1, 1, 32, + NULL, NULL, NULL, NULL, NULL, - NULL }; struct enc_xform enc_xform_camellia = { CRYPTO_CAMELLIA_CBC, "Camellia", - CAMELLIA_BLOCK_LEN, 8, 32, + CAMELLIA_BLOCK_LEN, CAMELLIA_BLOCK_LEN, 8, 32, cml_encrypt, cml_decrypt, cml_setkey, cml_zerokey, - NULL + NULL, }; /* Authentication instances */ -struct auth_hash auth_hash_null = { +struct auth_hash auth_hash_null = { /* NB: context isn't used */ CRYPTO_NULL_HMAC, "NULL-HMAC", - 0, NULL_HASH_LEN, NULL_HMAC_BLOCK_LEN, sizeof(int), /* NB: context isn't used */ - null_init, null_update, null_final + 0, NULL_HASH_LEN, 12, sizeof(int), NULL_HMAC_BLOCK_LEN, + null_init, null_reinit, null_reinit, null_update, null_final }; struct auth_hash auth_hash_hmac_md5 = { CRYPTO_MD5_HMAC, "HMAC-MD5", - 16, MD5_HASH_LEN, MD5_HMAC_BLOCK_LEN, sizeof(MD5_CTX), - (void (*) (void *)) MD5Init, MD5Update_int, + 16, MD5_HASH_LEN, 12, sizeof(MD5_CTX), MD5_HMAC_BLOCK_LEN, + (void (*) (void *)) MD5Init, NULL, NULL, MD5Update_int, (void (*) (u_int8_t *, void *)) MD5Final }; struct auth_hash auth_hash_hmac_sha1 = { CRYPTO_SHA1_HMAC, "HMAC-SHA1", - 20, SHA1_HASH_LEN, SHA1_HMAC_BLOCK_LEN, sizeof(SHA1_CTX), - SHA1Init_int, SHA1Update_int, SHA1Final_int + 20, SHA1_HASH_LEN, 12, sizeof(SHA1_CTX), SHA1_HMAC_BLOCK_LEN, + SHA1Init_int, NULL, NULL, SHA1Update_int, SHA1Final_int }; struct auth_hash auth_hash_hmac_ripemd_160 = { CRYPTO_RIPEMD160_HMAC, "HMAC-RIPEMD-160", - 20, RIPEMD160_HASH_LEN, RIPEMD160_HMAC_BLOCK_LEN, sizeof(RMD160_CTX), - (void (*)(void *)) RMD160Init, RMD160Update_int, + 20, RIPEMD160_HASH_LEN, 12, sizeof(RMD160_CTX), RIPEMD160_HMAC_BLOCK_LEN, + (void (*)(void *)) RMD160Init, NULL, NULL, RMD160Update_int, (void (*)(u_int8_t *, void *)) RMD160Final }; struct auth_hash auth_hash_key_md5 = { CRYPTO_MD5_KPDK, "Keyed MD5", - 0, MD5_KPDK_HASH_LEN, 0, sizeof(MD5_CTX), - (void (*)(void *)) MD5Init, MD5Update_int, + 0, MD5_KPDK_HASH_LEN, MD5_KPDK_HASH_LEN, sizeof(MD5_CTX), 0, + (void (*)(void *)) MD5Init, NULL, NULL, MD5Update_int, (void (*)(u_int8_t *, void *)) MD5Final }; struct auth_hash auth_hash_key_sha1 = { CRYPTO_SHA1_KPDK, "Keyed SHA1", - 0, SHA1_KPDK_HASH_LEN, 0, sizeof(SHA1_CTX), - SHA1Init_int, SHA1Update_int, SHA1Final_int + 0, SHA1_KPDK_HASH_LEN, SHA1_KPDK_HASH_LEN, sizeof(SHA1_CTX), 0, + SHA1Init_int, NULL, NULL, SHA1Update_int, SHA1Final_int }; struct auth_hash auth_hash_hmac_sha2_256 = { CRYPTO_SHA2_256_HMAC, "HMAC-SHA2-256", - 32, SHA2_256_HASH_LEN, SHA2_256_HMAC_BLOCK_LEN, sizeof(SHA256_CTX), - (void (*)(void *)) SHA256_Init, SHA256Update_int, + 32, SHA2_256_HASH_LEN, 16, sizeof(SHA256_CTX), SHA2_256_HMAC_BLOCK_LEN, + (void (*)(void *)) SHA256_Init, NULL, NULL, SHA256Update_int, (void (*)(u_int8_t *, void *)) SHA256_Final }; struct auth_hash auth_hash_hmac_sha2_384 = { CRYPTO_SHA2_384_HMAC, "HMAC-SHA2-384", - 48, SHA2_384_HASH_LEN, SHA2_384_HMAC_BLOCK_LEN, sizeof(SHA384_CTX), - (void (*)(void *)) SHA384_Init, SHA384Update_int, + 48, SHA2_384_HASH_LEN, 24, sizeof(SHA384_CTX), SHA2_384_HMAC_BLOCK_LEN, + (void (*)(void *)) SHA384_Init, NULL, NULL, SHA384Update_int, (void (*)(u_int8_t *, void *)) SHA384_Final }; struct auth_hash auth_hash_hmac_sha2_512 = { CRYPTO_SHA2_512_HMAC, "HMAC-SHA2-512", - 64, SHA2_512_HASH_LEN, SHA2_512_HMAC_BLOCK_LEN, sizeof(SHA512_CTX), - (void (*)(void *)) SHA512_Init, SHA512Update_int, + 64, SHA2_512_HASH_LEN, 32, sizeof(SHA512_CTX), SHA2_512_HMAC_BLOCK_LEN, + (void (*)(void *)) SHA512_Init, NULL, NULL, SHA512Update_int, (void (*)(u_int8_t *, void *)) SHA512_Final }; +struct auth_hash auth_hash_gmac_aes_128 = { + CRYPTO_AES_128_GMAC, "GMAC-AES-128", + 16+4, 16, GMAC_DIGEST_LEN, sizeof(AES_GMAC_CTX), GMAC_BLOCK_LEN, + (void (*)(void *)) AES_GMAC_Init, + (void (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Setkey, + (void (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Reinit, + (int (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Update, + (void (*)(u_int8_t *, void *)) AES_GMAC_Final +}; + +struct auth_hash auth_hash_gmac_aes_192 = { + CRYPTO_AES_192_GMAC, "GMAC-AES-192", + 24+4, 16, GMAC_DIGEST_LEN, sizeof(AES_GMAC_CTX), GMAC_BLOCK_LEN, + (void (*)(void *)) AES_GMAC_Init, + (void (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Setkey, + (void (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Reinit, + (int (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Update, + (void (*)(u_int8_t *, void *)) AES_GMAC_Final +}; + +struct auth_hash auth_hash_gmac_aes_256 = { + CRYPTO_AES_256_GMAC, "GMAC-AES-256", + 32+4, 16, GMAC_DIGEST_LEN, sizeof(AES_GMAC_CTX), GMAC_BLOCK_LEN, + (void (*)(void *)) AES_GMAC_Init, + (void (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Setkey, + (void (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Reinit, + (int (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Update, + (void (*)(u_int8_t *, void *)) AES_GMAC_Final +}; + /* Compression instance */ struct comp_algo comp_algo_deflate = { CRYPTO_DEFLATE_COMP, "Deflate", @@ -579,9 +658,78 @@ rijndael128_zerokey(u_int8_t **sched) *sched = NULL; } -#define AES_XTS_BLOCKSIZE 16 -#define AES_XTS_IVSIZE 8 -#define AES_XTS_ALPHA 0x87 /* GF(2^128) generator polynomial */ +void +aes_ctr_reinit(caddr_t key, u_int8_t *iv) +{ + struct aes_ctr_ctx *ctx; + + ctx = (struct aes_ctr_ctx *)key; + bcopy(iv, ctx->ac_block + AESCTR_NONCESIZE, AESCTR_IVSIZE); + + /* reset counter */ + bzero(ctx->ac_block + AESCTR_NONCESIZE + AESCTR_IVSIZE, 4); +} + +void +aes_gcm_reinit(caddr_t key, u_int8_t *iv) +{ + struct aes_ctr_ctx *ctx; + + aes_ctr_reinit(key, iv); + + ctx = (struct aes_ctr_ctx *)key; + ctx->ac_block[AESCTR_BLOCKSIZE - 1] = 1; /* GCM starts with 1 */ +} + +void +aes_ctr_crypt(caddr_t key, u_int8_t *data) +{ + struct aes_ctr_ctx *ctx; + u_int8_t keystream[AESCTR_BLOCKSIZE]; + int i; + + ctx = (struct aes_ctr_ctx *)key; + /* increment counter */ + for (i = AESCTR_BLOCKSIZE - 1; + i >= AESCTR_NONCESIZE + AESCTR_IVSIZE; i--) + if (++ctx->ac_block[i]) /* continue on overflow */ + break; + rijndaelEncrypt(ctx->ac_ek, ctx->ac_nr, ctx->ac_block, keystream); + for (i = 0; i < AESCTR_BLOCKSIZE; i++) + data[i] ^= keystream[i]; + bzero(keystream, sizeof(keystream)); +} + +int +aes_ctr_setkey(u_int8_t **sched, u_int8_t *key, int len) +{ + struct aes_ctr_ctx *ctx; + + if (len < AESCTR_NONCESIZE) + return EINVAL; + + *sched = malloc(sizeof(struct aes_ctr_ctx), M_CRYPTO_DATA, + M_NOWAIT | M_ZERO); + if (*sched == NULL) + return ENOMEM; + + ctx = (struct aes_ctr_ctx *)*sched; + ctx->ac_nr = rijndaelKeySetupEnc(ctx->ac_ek, (u_char *)key, + (len - AESCTR_NONCESIZE) * 8); + if (ctx->ac_nr == 0) + return EINVAL; + bcopy(key + len - AESCTR_NONCESIZE, ctx->ac_block, AESCTR_NONCESIZE); + return 0; +} + +void +aes_ctr_zerokey(u_int8_t **sched) +{ + + bzero(*sched, sizeof(struct aes_ctr_ctx)); + free(*sched, M_CRYPTO_DATA); + *sched = NULL; +} struct aes_xts_ctx { rijndael_ctx key1; @@ -728,8 +876,13 @@ null_init(void *ctx) { } +static void +null_reinit(void *ctx, const u_int8_t *buf, u_int16_t len) +{ +} + static int -null_update(void *ctx, u_int8_t *buf, u_int16_t len) +null_update(void *ctx, const u_int8_t *buf, u_int16_t len) { return 0; } @@ -742,14 +895,14 @@ null_final(u_int8_t *buf, void *ctx) } static int -RMD160Update_int(void *ctx, u_int8_t *buf, u_int16_t len) +RMD160Update_int(void *ctx, const u_int8_t *buf, u_int16_t len) { RMD160Update(ctx, buf, len); return 0; } static int -MD5Update_int(void *ctx, u_int8_t *buf, u_int16_t len) +MD5Update_int(void *ctx, const u_int8_t *buf, u_int16_t len) { MD5Update(ctx, buf, len); return 0; @@ -762,7 +915,7 @@ SHA1Init_int(void *ctx) } static int -SHA1Update_int(void *ctx, u_int8_t *buf, u_int16_t len) +SHA1Update_int(void *ctx, const u_int8_t *buf, u_int16_t len) { SHA1Update(ctx, buf, len); return 0; @@ -775,21 +928,21 @@ SHA1Final_int(u_int8_t *blk, void *ctx) } static int -SHA256Update_int(void *ctx, u_int8_t *buf, u_int16_t len) +SHA256Update_int(void *ctx, const u_int8_t *buf, u_int16_t len) { SHA256_Update(ctx, buf, len); return 0; } static int -SHA384Update_int(void *ctx, u_int8_t *buf, u_int16_t len) +SHA384Update_int(void *ctx, const u_int8_t *buf, u_int16_t len) { SHA384_Update(ctx, buf, len); return 0; } static int -SHA512Update_int(void *ctx, u_int8_t *buf, u_int16_t len) +SHA512Update_int(void *ctx, const u_int8_t *buf, u_int16_t len) { SHA512_Update(ctx, buf, len); return 0; diff --git a/sys/opencrypto/xform.h b/sys/opencrypto/xform.h index 8df7b07..98909db 100644 --- a/sys/opencrypto/xform.h +++ b/sys/opencrypto/xform.h @@ -29,6 +29,7 @@ #include <crypto/sha1.h> #include <crypto/sha2/sha2.h> #include <opencrypto/rmd160.h> +#include <opencrypto/gmac.h> /* Declarations */ struct auth_hash { @@ -36,10 +37,13 @@ struct auth_hash { char *name; u_int16_t keysize; u_int16_t hashsize; - u_int16_t blocksize; + u_int16_t authsize; u_int16_t ctxsize; + u_int16_t blocksize; void (*Init) (void *); - int (*Update) (void *, u_int8_t *, u_int16_t); + void (*Setkey) (void *, const u_int8_t *, u_int16_t); + void (*Reinit) (void *, const u_int8_t *, u_int16_t); + int (*Update) (void *, const u_int8_t *, u_int16_t); void (*Final) (u_int8_t *, void *); }; @@ -50,10 +54,11 @@ struct enc_xform { int type; char *name; u_int16_t blocksize; + u_int16_t ivsize; 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 **, u_int8_t *, int); void (*zerokey) (u_int8_t **); void (*reinit) (caddr_t, u_int8_t *); }; @@ -73,6 +78,7 @@ union authctx { SHA256_CTX sha256ctx; SHA384_CTX sha384ctx; SHA512_CTX sha512ctx; + AES_GMAC_CTX aes_gmac_ctx; }; extern struct enc_xform enc_xform_null; @@ -82,6 +88,9 @@ extern struct enc_xform enc_xform_blf; extern struct enc_xform enc_xform_cast5; extern struct enc_xform enc_xform_skipjack; extern struct enc_xform enc_xform_rijndael128; +extern struct enc_xform enc_xform_aes_ctr; +extern struct enc_xform enc_xform_aes_gcm; +extern struct enc_xform enc_xform_aes_gmac; extern struct enc_xform enc_xform_aes_xts; extern struct enc_xform enc_xform_arc4; extern struct enc_xform enc_xform_camellia; @@ -95,6 +104,9 @@ extern struct auth_hash auth_hash_hmac_ripemd_160; extern struct auth_hash auth_hash_hmac_sha2_256; extern struct auth_hash auth_hash_hmac_sha2_384; extern struct auth_hash auth_hash_hmac_sha2_512; +extern struct auth_hash auth_hash_gmac_aes_128; +extern struct auth_hash auth_hash_gmac_aes_192; +extern struct auth_hash auth_hash_gmac_aes_256; extern struct comp_algo comp_algo_deflate; |