summaryrefslogtreecommitdiff
path: root/sys/opencrypto
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2021-10-06 21:08:49 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2021-10-21 21:19:30 +0000
commit64c043d2d2cfa44128361c9354d1fad023087be8 (patch)
tree989c84842effb1d5653f479c8db6b26e11832fc7 /sys/opencrypto
parentdffa7f13db7855941b270caa6fc5ec72becb07bc (diff)
Diffstat (limited to 'sys/opencrypto')
-rw-r--r--sys/opencrypto/crypto.c7
-rw-r--r--sys/opencrypto/cryptosoft.c3
-rw-r--r--sys/opencrypto/xform_chacha20_poly1305.c31
3 files changed, 31 insertions, 10 deletions
diff --git a/sys/opencrypto/crypto.c b/sys/opencrypto/crypto.c
index a3a42827d51b..f0fd3fe662a9 100644
--- a/sys/opencrypto/crypto.c
+++ b/sys/opencrypto/crypto.c
@@ -882,10 +882,15 @@ check_csp(const struct crypto_session_params *csp)
return (false);
break;
case CRYPTO_AES_NIST_GCM_16:
- case CRYPTO_CHACHA20_POLY1305:
if (csp->csp_auth_mlen > 16)
return (false);
break;
+ case CRYPTO_CHACHA20_POLY1305:
+ if (csp->csp_ivlen != 8 && csp->csp_ivlen != 12)
+ return (false);
+ if (csp->csp_auth_mlen > POLY1305_HASH_LEN)
+ return (false);
+ break;
}
break;
case CSP_MODE_ETA:
diff --git a/sys/opencrypto/cryptosoft.c b/sys/opencrypto/cryptosoft.c
index fb43a08970c7..567a0f4748d5 100644
--- a/sys/opencrypto/cryptosoft.c
+++ b/sys/opencrypto/cryptosoft.c
@@ -1393,9 +1393,6 @@ swcr_setup_chacha20_poly1305(struct swcr_session *ses,
struct swcr_auth *swa;
struct auth_hash *axf;
- if (csp->csp_ivlen != CHACHA20_POLY1305_IV_LEN)
- return (EINVAL);
-
/* First, setup the auth side. */
swa = &ses->swcr_auth;
axf = &auth_hash_chacha20_poly1305;
diff --git a/sys/opencrypto/xform_chacha20_poly1305.c b/sys/opencrypto/xform_chacha20_poly1305.c
index e893287145f2..f593faa9b5ef 100644
--- a/sys/opencrypto/xform_chacha20_poly1305.c
+++ b/sys/opencrypto/xform_chacha20_poly1305.c
@@ -34,6 +34,7 @@
struct chacha20_poly1305_cipher_ctx {
const void *key;
uint32_t ic;
+ bool ietf;
char nonce[CHACHA20_POLY1305_IV_LEN];
};
@@ -58,7 +59,8 @@ chacha20_poly1305_reinit(void *vctx, const uint8_t *iv, size_t ivlen)
("%s: invalid nonce length", __func__));
/* Block 0 is used for the poly1305 key. */
- memcpy(ctx->nonce, iv, sizeof(ctx->nonce));
+ memcpy(ctx->nonce, iv, ivlen);
+ ctx->ietf = (ivlen == CHACHA20_POLY1305_IV_LEN);
ctx->ic = 1;
}
@@ -68,8 +70,12 @@ chacha20_poly1305_crypt(void *vctx, const uint8_t *in, uint8_t *out)
struct chacha20_poly1305_cipher_ctx *ctx = vctx;
int error;
- error = crypto_stream_chacha20_ietf_xor_ic(out, in,
- CHACHA20_NATIVE_BLOCK_LEN, ctx->nonce, ctx->ic, ctx->key);
+ if (ctx->ietf)
+ error = crypto_stream_chacha20_ietf_xor_ic(out, in,
+ CHACHA20_NATIVE_BLOCK_LEN, ctx->nonce, ctx->ic, ctx->key);
+ else
+ error = crypto_stream_chacha20_xor_ic(out, in,
+ CHACHA20_NATIVE_BLOCK_LEN, ctx->nonce, ctx->ic, ctx->key);
KASSERT(error == 0, ("%s failed: %d", __func__, error));
ctx->ic++;
}
@@ -82,8 +88,12 @@ chacha20_poly1305_crypt_last(void *vctx, const uint8_t *in, uint8_t *out,
int error;
- error = crypto_stream_chacha20_ietf_xor_ic(out, in, len, ctx->nonce,
- ctx->ic, ctx->key);
+ if (ctx->ietf)
+ error = crypto_stream_chacha20_ietf_xor_ic(out, in, len,
+ ctx->nonce, ctx->ic, ctx->key);
+ else
+ error = crypto_stream_chacha20_xor_ic(out, in, len, ctx->nonce,
+ ctx->ic, ctx->key);
KASSERT(error == 0, ("%s failed: %d", __func__, error));
}
@@ -129,7 +139,16 @@ chacha20_poly1305_Reinit(void *vctx, const uint8_t *nonce, u_int noncelen)
struct chacha20_poly1305_auth_ctx *ctx = vctx;
char block[CHACHA20_NATIVE_BLOCK_LEN];
- crypto_stream_chacha20_ietf(block, sizeof(block), nonce, ctx->key);
+ switch (noncelen) {
+ case 8:
+ crypto_stream_chacha20(block, sizeof(block), nonce, ctx->key);
+ break;
+ case CHACHA20_POLY1305_IV_LEN:
+ crypto_stream_chacha20_ietf(block, sizeof(block), nonce, ctx->key);
+ break;
+ default:
+ __assert_unreachable();
+ }
crypto_onetimeauth_poly1305_init(&ctx->state, block);
explicit_bzero(block, sizeof(block));
}