Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F111617884
D32111.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D32111.diff
View Options
diff --git a/share/man/man7/crypto.7 b/share/man/man7/crypto.7
--- a/share/man/man7/crypto.7
+++ b/share/man/man7/crypto.7
@@ -1,9 +1,13 @@
-.\" Copyright (c) 2014 The FreeBSD Foundation
+.\" Copyright (c) 2014-2021 The FreeBSD Foundation
.\" All rights reserved.
.\"
-.\" This documentation was written by John-Mark Gurney under
-.\" the sponsorship of the FreeBSD Foundation and
+.\" Portions of this documentation were written by John-Mark Gurney
+.\" under the sponsorship of the FreeBSD Foundation and
.\" Rubicon Communications, LLC (Netgate).
+.\"
+.\" Portions of this documentation were written by Ararat River
+.\" Consulting, LLC under sponsorship of the FreeBSD Foundation.
+.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
@@ -27,7 +31,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd March 3, 2021
+.Dd October 6, 2021
.Dt CRYPTO 7
.Os
.Sh NAME
@@ -153,13 +157,15 @@
via the
.Dv CRYPTO_F_IV_SEPARATE
flag.
+Some AEAD algorithms support multiple nonce sizes.
+The first size listed is the default nonce size.
.Pp
The following AEAD algorithms are supported:
-.Bl -column "CRYPTO_AES_NIST_GCM_16" "Nonce" "16, 24, 32" "Tag"
+.Bl -column "CRYPTO_AES_NIST_GCM_16" "12, 7-13" "16, 24, 32" "Tag"
.It Sy Name Ta Sy Nonce Ta Sy Key Sizes Ta Sy Tag Ta Sy Description
.It Dv CRYPTO_AES_NIST_GCM_16 Ta 12 Ta 16, 24, 32 Ta 16 Ta
AES Galois/Counter Mode
-.It Dv CRYPTO_AES_CCM_16 Ta 12 Ta 16, 24, 32 Ta 16 Ta
+.It Dv CRYPTO_AES_CCM_16 Ta 12, 7-13 Ta 16, 24, 32 Ta 16 Ta
AES Counter with CBC-MAC
.It Dv CRYPTO_CHACHA20_POLY1305 Ta 12 Ta 32 Ta 16 Ta
ChaCha20-Poly1305
diff --git a/sys/opencrypto/crypto.c b/sys/opencrypto/crypto.c
--- a/sys/opencrypto/crypto.c
+++ b/sys/opencrypto/crypto.c
@@ -1,5 +1,9 @@
/*-
* Copyright (c) 2002-2006 Sam Leffler. All rights reserved.
+ * Copyright (c) 2021 The FreeBSD Foundation
+ *
+ * Portions of this software were developed by Ararat River
+ * Consulting, LLC under sponsorship of the FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -713,6 +717,24 @@
return (alg_type(alg) == ALG_AEAD);
}
+static bool
+ccm_tag_length_valid(int len)
+{
+ /* RFC 3610 */
+ switch (len) {
+ case 4:
+ case 6:
+ case 8:
+ case 10:
+ case 12:
+ case 14:
+ case 16:
+ return (true);
+ default:
+ return (false);
+ }
+}
+
#define SUPPORTED_SES (CSP_F_SEPARATE_OUTPUT | CSP_F_SEPARATE_AAD | CSP_F_ESN)
/* Various sanity checks on crypto session parameters. */
@@ -770,8 +792,21 @@
return (false);
/* IV is optional for digests (e.g. GMAC). */
- if (csp->csp_ivlen >= EALG_MAX_BLOCK_LEN)
- return (false);
+ switch (csp->csp_auth_alg) {
+ case CRYPTO_AES_CCM_CBC_MAC:
+ if (csp->csp_ivlen < 7 || csp->csp_ivlen > 13)
+ return (false);
+ break;
+ case CRYPTO_AES_NIST_GMAC:
+ if (csp->csp_ivlen != AES_GCM_IV_LEN)
+ return (false);
+ break;
+ default:
+ if (csp->csp_ivlen != 0)
+ return (false);
+ break;
+ }
+
if (!alg_is_digest(csp->csp_auth_alg))
return (false);
@@ -790,6 +825,10 @@
axf = crypto_auth_hash(csp);
if (axf == NULL || csp->csp_auth_mlen > axf->hashsize)
return (false);
+
+ if (csp->csp_auth_alg == CRYPTO_AES_CCM_CBC_MAC &&
+ !ccm_tag_length_valid(csp->csp_auth_mlen))
+ return (false);
}
break;
case CSP_MODE_AEAD:
@@ -803,13 +842,16 @@
if (csp->csp_auth_alg != 0 || csp->csp_auth_klen != 0)
return (false);
- /*
- * XXX: Would be nice to have a better way to get this
- * value.
- */
switch (csp->csp_cipher_alg) {
- case CRYPTO_AES_NIST_GCM_16:
case CRYPTO_AES_CCM_16:
+ if (csp->csp_auth_mlen != 0 &&
+ !ccm_tag_length_valid(csp->csp_auth_mlen))
+ return (false);
+
+ if (csp->csp_ivlen < 7 || csp->csp_ivlen > 13)
+ return (false);
+ break;
+ case CRYPTO_AES_NIST_GCM_16:
case CRYPTO_CHACHA20_POLY1305:
if (csp->csp_auth_mlen > 16)
return (false);
diff --git a/sys/opencrypto/cryptodev.h b/sys/opencrypto/cryptodev.h
--- a/sys/opencrypto/cryptodev.h
+++ b/sys/opencrypto/cryptodev.h
@@ -686,5 +686,34 @@
crypto_copydata(crp, crp->crp_iv_start, csp->csp_ivlen, iv);
}
+static __inline size_t
+ccm_max_payload_length(const struct crypto_session_params *csp)
+{
+ /* RFC 3160 */
+ const u_int L = 15 - csp->csp_ivlen;
+
+ switch (L) {
+ case 2:
+ return (0xffff);
+ case 3:
+ return (0xffffff);
+#ifdef __LP64__
+ case 4:
+ return (0xffffffff);
+ case 5:
+ return (0xffffffffff);
+ case 6:
+ return (0xffffffffffff);
+ case 7:
+ return (0xffffffffffffff);
+ default:
+ return (0xffffffffffffffff);
+#else
+ default:
+ return (0xffffffff);
+#endif
+ }
+}
+
#endif /* _KERNEL */
#endif /* _CRYPTO_CRYPTO_H_ */
diff --git a/sys/opencrypto/cryptosoft.c b/sys/opencrypto/cryptosoft.c
--- a/sys/opencrypto/cryptosoft.c
+++ b/sys/opencrypto/cryptosoft.c
@@ -642,17 +642,19 @@
u_char tag[AES_CBC_MAC_HASH_LEN];
u_char iv[AES_BLOCK_LEN];
union authctx ctx;
+ const struct crypto_session_params *csp;
struct swcr_auth *swa;
const struct auth_hash *axf;
int error, ivlen;
+ csp = crypto_get_params(crp->crp_session);
swa = &ses->swcr_auth;
axf = swa->sw_axf;
bcopy(swa->sw_ictx, &ctx, axf->ctxsize);
/* Initialize the IV */
- ivlen = AES_CCM_IV_LEN;
+ ivlen = csp->csp_ivlen;
crypto_read_iv(crp, iv);
/*
@@ -694,6 +696,7 @@
static int
swcr_ccm(struct swcr_session *ses, struct cryptop *crp)
{
+ const struct crypto_session_params *csp;
uint32_t blkbuf[howmany(AES_BLOCK_LEN, sizeof(uint32_t))];
u_char *blk = (u_char *)blkbuf;
u_char tag[AES_CBC_MAC_HASH_LEN];
@@ -708,6 +711,7 @@
size_t len;
int blksz, error, ivlen, r, resid;
+ csp = crypto_get_params(crp->crp_session);
swa = &ses->swcr_auth;
axf = swa->sw_axf;
@@ -721,10 +725,13 @@
KASSERT(axf->blocksize == exf->native_blocksize,
("%s: blocksize mismatch", __func__));
+ if (crp->crp_payload_length > ccm_max_payload_length(csp))
+ return (EMSGSIZE);
+
if ((crp->crp_flags & CRYPTO_F_IV_SEPARATE) == 0)
return (EINVAL);
- ivlen = AES_CCM_IV_LEN;
+ ivlen = csp->csp_ivlen;
/*
* AES CCM-CBC-MAC needs to know the length of both the auth
@@ -1130,7 +1137,6 @@
swe = &ses->swcr_encdec;
txf = crypto_cipher(csp);
- MPASS(txf->ivsize == csp->csp_ivlen);
if (txf->ctxsize != 0) {
swe->sw_kschedule = malloc(txf->ctxsize, M_CRYPTO_DATA,
M_NOWAIT);
@@ -1282,9 +1288,6 @@
struct swcr_auth *swa;
const struct auth_hash *axf;
- if (csp->csp_ivlen != AES_CCM_IV_LEN)
- return (EINVAL);
-
/* First, setup the auth side. */
swa = &ses->swcr_auth;
switch (csp->csp_cipher_klen * 8) {
@@ -1392,8 +1395,6 @@
}
if (csp->csp_auth_key == NULL)
return (false);
- if (csp->csp_ivlen != AES_CCM_IV_LEN)
- return (false);
break;
}
return (true);
diff --git a/sys/opencrypto/xform_aes_icm.c b/sys/opencrypto/xform_aes_icm.c
--- a/sys/opencrypto/xform_aes_icm.c
+++ b/sys/opencrypto/xform_aes_icm.c
@@ -144,15 +144,14 @@
{
struct aes_icm_ctx *ctx;
- KASSERT(ivlen == AES_CCM_IV_LEN,
+ KASSERT(ivlen >= 7 && ivlen <= 13,
("%s: invalid IV length", __func__));
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[0] = (15 - ivlen) - 1;
+ bcopy(iv, ctx->ac_block + 1, ivlen);
ctx->ac_block[AESICM_BLOCKSIZE - 1] = 1;
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Mar 7, 2:06 AM (17 h, 47 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17023417
Default Alt Text
D32111.diff (7 KB)
Attached To
Mode
D32111: crypto: Support multiple nonce lengths for AES-CCM.
Attached
Detach File
Event Timeline
Log In to Comment