From eba523f0a130f1cce829e6aecdcefa841f526a1a Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Fri, 3 Apr 2020 04:27:03 +0000 Subject: [PATCH] upstream: make Chacha20-POLY1305 context struct opaque; ok tb@ as part of a larger diff at a2k20 OpenBSD-Commit-ID: a4609b7263284f95c9417ef60ed7cdbb7bf52cfd --- cipher-chachapoly.c | 25 +++++++++++++++++++------ cipher-chachapoly.h | 13 ++++++------- cipher.c | 18 ++++++++++-------- regress/Makefile | 3 ++- 4 files changed, 37 insertions(+), 22 deletions(-) diff --git a/cipher-chachapoly.c b/cipher-chachapoly.c index 0899c5ad5..42e8d40b7 100644 --- a/cipher-chachapoly.c +++ b/cipher-chachapoly.c @@ -14,7 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $OpenBSD: cipher-chachapoly.c,v 1.8 2016/08/03 05:41:57 djm Exp $ */ +/* $OpenBSD: cipher-chachapoly.c,v 1.9 2020/04/03 04:27:03 djm Exp $ */ #include "includes.h" @@ -28,15 +28,28 @@ #include "ssherr.h" #include "cipher-chachapoly.h" -int -chachapoly_init(struct chachapoly_ctx *ctx, - const u_char *key, u_int keylen) +struct chachapoly_ctx { + struct chacha_ctx main_ctx, header_ctx; +}; + +struct chachapoly_ctx * +chachapoly_new(const u_char *key, u_int keylen) { + struct chachapoly_ctx *ctx; + if (keylen != (32 + 32)) /* 2 x 256 bit keys */ - return SSH_ERR_INVALID_ARGUMENT; + return NULL; + if ((ctx = calloc(1, sizeof(*ctx))) == NULL) + return NULL; chacha_keysetup(&ctx->main_ctx, key, 256); chacha_keysetup(&ctx->header_ctx, key + 32, 256); - return 0; + return ctx; +} + +void +chachapoly_free(struct chachapoly_ctx *cpctx) +{ + freezero(cpctx, sizeof(*cpctx)); } /* diff --git a/cipher-chachapoly.h b/cipher-chachapoly.h index b7072be7d..026d2de93 100644 --- a/cipher-chachapoly.h +++ b/cipher-chachapoly.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cipher-chachapoly.h,v 1.4 2014/06/24 01:13:21 djm Exp $ */ +/* $OpenBSD: cipher-chachapoly.h,v 1.5 2020/04/03 04:27:03 djm Exp $ */ /* * Copyright (c) Damien Miller 2013 @@ -24,13 +24,12 @@ #define CHACHA_KEYLEN 32 /* Only 256 bit keys used here */ -struct chachapoly_ctx { - struct chacha_ctx main_ctx, header_ctx; -}; +struct chachapoly_ctx; + +struct chachapoly_ctx *chachapoly_new(const u_char *key, u_int keylen) + __attribute__((__bounded__(__buffer__, 1, 2))); +void chachapoly_free(struct chachapoly_ctx *cpctx); -int chachapoly_init(struct chachapoly_ctx *cpctx, - const u_char *key, u_int keylen) - __attribute__((__bounded__(__buffer__, 2, 3))); int chachapoly_crypt(struct chachapoly_ctx *cpctx, u_int seqnr, u_char *dest, const u_char *src, u_int len, u_int aadlen, u_int authlen, int do_encrypt); diff --git a/cipher.c b/cipher.c index cd6e6def0..8195199b3 100644 --- a/cipher.c +++ b/cipher.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cipher.c,v 1.116 2020/03/13 03:17:07 djm Exp $ */ +/* $OpenBSD: cipher.c,v 1.117 2020/04/03 04:27:03 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -59,7 +59,7 @@ struct sshcipher_ctx { int plaintext; int encrypt; EVP_CIPHER_CTX *evp; - struct chachapoly_ctx cp_ctx; /* XXX union with evp? */ + struct chachapoly_ctx *cp_ctx; struct aesctr_ctx ac_ctx; /* XXX union with evp? */ const struct sshcipher *cipher; }; @@ -273,7 +273,8 @@ cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher, cc->cipher = cipher; if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { - ret = chachapoly_init(&cc->cp_ctx, key, keylen); + cc->cp_ctx = chachapoly_new(key, keylen); + ret = cc->cp_ctx != NULL ? 0 : SSH_ERR_INVALID_ARGUMENT; goto out; } if ((cc->cipher->flags & CFLAG_NONE) != 0) { @@ -349,7 +350,7 @@ cipher_crypt(struct sshcipher_ctx *cc, u_int seqnr, u_char *dest, const u_char *src, u_int len, u_int aadlen, u_int authlen) { if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { - return chachapoly_crypt(&cc->cp_ctx, seqnr, dest, src, + return chachapoly_crypt(cc->cp_ctx, seqnr, dest, src, len, aadlen, authlen, cc->encrypt); } if ((cc->cipher->flags & CFLAG_NONE) != 0) { @@ -412,7 +413,7 @@ cipher_get_length(struct sshcipher_ctx *cc, u_int *plenp, u_int seqnr, const u_char *cp, u_int len) { if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) - return chachapoly_get_length(&cc->cp_ctx, plenp, seqnr, + return chachapoly_get_length(cc->cp_ctx, plenp, seqnr, cp, len); if (len < 4) return SSH_ERR_MESSAGE_INCOMPLETE; @@ -425,9 +426,10 @@ cipher_free(struct sshcipher_ctx *cc) { if (cc == NULL) return; - if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) - explicit_bzero(&cc->cp_ctx, sizeof(cc->cp_ctx)); - else if ((cc->cipher->flags & CFLAG_AESCTR) != 0) + if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { + chachapoly_free(cc->cp_ctx); + cc->cp_ctx = NULL; + } else if ((cc->cipher->flags & CFLAG_AESCTR) != 0) explicit_bzero(&cc->ac_ctx, sizeof(cc->ac_ctx)); #ifdef WITH_OPENSSL EVP_CIPHER_CTX_free(cc->evp); diff --git a/regress/Makefile b/regress/Makefile index 774c10d41..8f7b5aa99 100644 --- a/regress/Makefile +++ b/regress/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.106 2020/01/31 23:25:08 djm Exp $ +# $OpenBSD: Makefile,v 1.107 2020/04/03 02:33:31 dtucker Exp $ tests: prep file-tests t-exec unit @@ -66,6 +66,7 @@ LTESTS= connect \ cfgparse \ cfgmatch \ cfgmatchlisten \ + percent \ addrmatch \ localcommand \ forcecommand \