summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authortb <tb@openbsd.org>2019-03-17 18:07:41 +0000
committertb <tb@openbsd.org>2019-03-17 18:07:41 +0000
commit7bd973386a5d471a9e204c92c4974e44058a6f1f (patch)
tree5eb35b099991ee560bfcb6fb124f5eb84f76f594 /lib
parentsync (diff)
downloadwireguard-openbsd-7bd973386a5d471a9e204c92c4974e44058a6f1f.tar.xz
wireguard-openbsd-7bd973386a5d471a9e204c92c4974e44058a6f1f.zip
Provide EVP_aes_{128,192,256}_wrap(). This is a compatible
implementation based on the one in OpenSSL 1.0.2r which is still freely licensed. The functions are undocumented in OpenSSL. To use them, one needs to set the undocumented EVP_CIPHER_CTX_FLAG_WRAP_ALLOW flag on the EVP_CIPHER_CTX. resolves #505 ok jsing
Diffstat (limited to 'lib')
-rw-r--r--lib/libcrypto/Symbols.list3
-rw-r--r--lib/libcrypto/evp/c_all.c5
-rw-r--r--lib/libcrypto/evp/e_aes.c146
-rw-r--r--lib/libcrypto/evp/evp.h13
-rw-r--r--lib/libcrypto/evp/evp_enc.c10
-rw-r--r--lib/libcrypto/evp/evp_err.c3
6 files changed, 174 insertions, 6 deletions
diff --git a/lib/libcrypto/Symbols.list b/lib/libcrypto/Symbols.list
index 63e3ee45ace..9fdf723f87f 100644
--- a/lib/libcrypto/Symbols.list
+++ b/lib/libcrypto/Symbols.list
@@ -1515,6 +1515,7 @@ EVP_aes_128_ctr
EVP_aes_128_ecb
EVP_aes_128_gcm
EVP_aes_128_ofb
+EVP_aes_128_wrap
EVP_aes_128_xts
EVP_aes_192_cbc
EVP_aes_192_ccm
@@ -1526,6 +1527,7 @@ EVP_aes_192_ctr
EVP_aes_192_ecb
EVP_aes_192_gcm
EVP_aes_192_ofb
+EVP_aes_192_wrap
EVP_aes_256_cbc
EVP_aes_256_cbc_hmac_sha1
EVP_aes_256_ccm
@@ -1537,6 +1539,7 @@ EVP_aes_256_ctr
EVP_aes_256_ecb
EVP_aes_256_gcm
EVP_aes_256_ofb
+EVP_aes_256_wrap
EVP_aes_256_xts
EVP_bf_cbc
EVP_bf_cfb
diff --git a/lib/libcrypto/evp/c_all.c b/lib/libcrypto/evp/c_all.c
index cce36408666..9e9d39d5aba 100644
--- a/lib/libcrypto/evp/c_all.c
+++ b/lib/libcrypto/evp/c_all.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: c_all.c,v 1.25 2019/03/17 17:42:37 tb Exp $ */
+/* $OpenBSD: c_all.c,v 1.26 2019/03/17 18:07:41 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -159,6 +159,7 @@ OpenSSL_add_all_ciphers_internal(void)
EVP_add_cipher(EVP_aes_128_ofb());
EVP_add_cipher(EVP_aes_128_ctr());
EVP_add_cipher(EVP_aes_128_gcm());
+ EVP_add_cipher(EVP_aes_128_wrap());
EVP_add_cipher(EVP_aes_128_xts());
EVP_add_cipher_alias(SN_aes_128_cbc, "AES128");
EVP_add_cipher_alias(SN_aes_128_cbc, "aes128");
@@ -171,6 +172,7 @@ OpenSSL_add_all_ciphers_internal(void)
EVP_add_cipher(EVP_aes_192_ofb());
EVP_add_cipher(EVP_aes_192_ctr());
EVP_add_cipher(EVP_aes_192_gcm());
+ EVP_add_cipher(EVP_aes_192_wrap());
EVP_add_cipher_alias(SN_aes_192_cbc, "AES192");
EVP_add_cipher_alias(SN_aes_192_cbc, "aes192");
EVP_add_cipher(EVP_aes_256_ecb());
@@ -182,6 +184,7 @@ OpenSSL_add_all_ciphers_internal(void)
EVP_add_cipher(EVP_aes_256_ofb());
EVP_add_cipher(EVP_aes_256_ctr());
EVP_add_cipher(EVP_aes_256_gcm());
+ EVP_add_cipher(EVP_aes_256_wrap());
EVP_add_cipher(EVP_aes_256_xts());
EVP_add_cipher_alias(SN_aes_256_cbc, "AES256");
EVP_add_cipher_alias(SN_aes_256_cbc, "aes256");
diff --git a/lib/libcrypto/evp/e_aes.c b/lib/libcrypto/evp/e_aes.c
index 7c713db0269..6b455dc503c 100644
--- a/lib/libcrypto/evp/e_aes.c
+++ b/lib/libcrypto/evp/e_aes.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_aes.c,v 1.34 2017/05/02 03:59:44 deraadt Exp $ */
+/* $OpenBSD: e_aes.c,v 1.35 2019/03/17 18:07:41 tb Exp $ */
/* ====================================================================
* Copyright (c) 2001-2011 The OpenSSL Project. All rights reserved.
*
@@ -49,6 +49,7 @@
*
*/
+#include <limits.h>
#include <stdlib.h>
#include <string.h>
@@ -1549,4 +1550,147 @@ EVP_aead_aes_256_gcm(void)
return &aead_aes_256_gcm;
}
+typedef struct {
+ union {
+ double align;
+ AES_KEY ks;
+ } ks;
+ unsigned char *iv;
+} EVP_AES_WRAP_CTX;
+
+static int
+aes_wrap_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ EVP_AES_WRAP_CTX *wctx = (EVP_AES_WRAP_CTX *)ctx->cipher_data;
+
+ if (iv == NULL && key == NULL)
+ return 1;
+
+ if (key != NULL) {
+ if (ctx->encrypt)
+ AES_set_encrypt_key(key, 8 * ctx->key_len,
+ &wctx->ks.ks);
+ else
+ AES_set_decrypt_key(key, 8 * ctx->key_len,
+ &wctx->ks.ks);
+
+ if (iv == NULL)
+ wctx->iv = NULL;
+ }
+
+ if (iv != NULL) {
+ memcpy(ctx->iv, iv, EVP_CIPHER_CTX_iv_length(ctx));
+ wctx->iv = ctx->iv;
+ }
+
+ return 1;
+}
+
+static int
+aes_wrap_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inlen)
+{
+ EVP_AES_WRAP_CTX *wctx = ctx->cipher_data;
+ int ret;
+
+ if (in == NULL)
+ return 0;
+
+ if (inlen % 8 != 0)
+ return -1;
+ if (ctx->encrypt && inlen < 8)
+ return -1;
+ if (!ctx->encrypt && inlen < 16)
+ return -1;
+ if (inlen > INT_MAX)
+ return -1;
+
+ if (out == NULL) {
+ if (ctx->encrypt)
+ return inlen + 8;
+ else
+ return inlen - 8;
+ }
+
+ if (ctx->encrypt)
+ ret = AES_wrap_key(&wctx->ks.ks, wctx->iv, out, in,
+ (unsigned int)inlen);
+ else
+ ret = AES_unwrap_key(&wctx->ks.ks, wctx->iv, out, in,
+ (unsigned int)inlen);
+
+ return ret != 0 ? ret : -1;
+}
+
+#define WRAP_FLAGS \
+ ( EVP_CIPH_WRAP_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER | \
+ EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_FLAG_DEFAULT_ASN1 )
+
+static const EVP_CIPHER aes_128_wrap = {
+ .nid = NID_id_aes128_wrap,
+ .block_size = 8,
+ .key_len = 16,
+ .iv_len = 8,
+ .flags = WRAP_FLAGS,
+ .init = aes_wrap_init_key,
+ .do_cipher = aes_wrap_cipher,
+ .cleanup = NULL,
+ .ctx_size = sizeof(EVP_AES_WRAP_CTX),
+ .set_asn1_parameters = NULL,
+ .get_asn1_parameters = NULL,
+ .ctrl = NULL,
+ .app_data = NULL,
+};
+
+const EVP_CIPHER *
+EVP_aes_128_wrap(void)
+{
+ return &aes_128_wrap;
+}
+
+static const EVP_CIPHER aes_192_wrap = {
+ .nid = NID_id_aes192_wrap,
+ .block_size = 8,
+ .key_len = 24,
+ .iv_len = 8,
+ .flags = WRAP_FLAGS,
+ .init = aes_wrap_init_key,
+ .do_cipher = aes_wrap_cipher,
+ .cleanup = NULL,
+ .ctx_size = sizeof(EVP_AES_WRAP_CTX),
+ .set_asn1_parameters = NULL,
+ .get_asn1_parameters = NULL,
+ .ctrl = NULL,
+ .app_data = NULL,
+};
+
+const EVP_CIPHER *
+EVP_aes_192_wrap(void)
+{
+ return &aes_192_wrap;
+}
+
+static const EVP_CIPHER aes_256_wrap = {
+ .nid = NID_id_aes256_wrap,
+ .block_size = 8,
+ .key_len = 32,
+ .iv_len = 8,
+ .flags = WRAP_FLAGS,
+ .init = aes_wrap_init_key,
+ .do_cipher = aes_wrap_cipher,
+ .cleanup = NULL,
+ .ctx_size = sizeof(EVP_AES_WRAP_CTX),
+ .set_asn1_parameters = NULL,
+ .get_asn1_parameters = NULL,
+ .ctrl = NULL,
+ .app_data = NULL,
+};
+
+const EVP_CIPHER *
+EVP_aes_256_wrap(void)
+{
+ return &aes_256_wrap;
+}
+
#endif
diff --git a/lib/libcrypto/evp/evp.h b/lib/libcrypto/evp/evp.h
index cd9b33c9b85..22876f9fe99 100644
--- a/lib/libcrypto/evp/evp.h
+++ b/lib/libcrypto/evp/evp.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: evp.h,v 1.73 2019/03/17 17:42:37 tb Exp $ */
+/* $OpenBSD: evp.h,v 1.74 2019/03/17 18:07:41 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -325,6 +325,7 @@ struct evp_cipher_st {
#define EVP_CIPH_GCM_MODE 0x6
#define EVP_CIPH_CCM_MODE 0x7
#define EVP_CIPH_XTS_MODE 0x10001
+#define EVP_CIPH_WRAP_MODE 0x10002
#define EVP_CIPH_MODE 0xF0007
/* Set if variable length cipher */
#define EVP_CIPH_VARIABLE_LENGTH 0x8
@@ -356,6 +357,12 @@ struct evp_cipher_st {
#define EVP_CIPH_FLAG_CUSTOM_CIPHER 0x100000
#define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000
+/*
+ * Cipher context flag to indicate that we can handle wrap mode: if allowed in
+ * older applications, it could overflow buffers.
+ */
+#define EVP_CIPHER_CTX_FLAG_WRAP_ALLOW 0x1
+
/* ctrl() values */
#define EVP_CTRL_INIT 0x0
@@ -776,6 +783,7 @@ const EVP_CIPHER *EVP_aes_128_ofb(void);
const EVP_CIPHER *EVP_aes_128_ctr(void);
const EVP_CIPHER *EVP_aes_128_ccm(void);
const EVP_CIPHER *EVP_aes_128_gcm(void);
+const EVP_CIPHER *EVP_aes_128_wrap(void);
const EVP_CIPHER *EVP_aes_128_xts(void);
const EVP_CIPHER *EVP_aes_192_ecb(void);
const EVP_CIPHER *EVP_aes_192_cbc(void);
@@ -787,6 +795,7 @@ const EVP_CIPHER *EVP_aes_192_ofb(void);
const EVP_CIPHER *EVP_aes_192_ctr(void);
const EVP_CIPHER *EVP_aes_192_ccm(void);
const EVP_CIPHER *EVP_aes_192_gcm(void);
+const EVP_CIPHER *EVP_aes_192_wrap(void);
const EVP_CIPHER *EVP_aes_256_ecb(void);
const EVP_CIPHER *EVP_aes_256_cbc(void);
const EVP_CIPHER *EVP_aes_256_cfb1(void);
@@ -797,6 +806,7 @@ const EVP_CIPHER *EVP_aes_256_ofb(void);
const EVP_CIPHER *EVP_aes_256_ctr(void);
const EVP_CIPHER *EVP_aes_256_ccm(void);
const EVP_CIPHER *EVP_aes_256_gcm(void);
+const EVP_CIPHER *EVP_aes_256_wrap(void);
const EVP_CIPHER *EVP_aes_256_xts(void);
#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void);
@@ -1523,6 +1533,7 @@ void ERR_load_EVP_strings(void);
#define EVP_R_UNSUPPORTED_KEY_SIZE 108
#define EVP_R_UNSUPPORTED_PRF 125
#define EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM 118
+#define EVP_R_WRAP_MODE_NOT_ALLOWED 170
#define EVP_R_UNSUPPORTED_SALT_TYPE 126
#define EVP_R_WRONG_FINAL_BLOCK_LENGTH 109
#define EVP_R_WRONG_PUBLIC_KEY_TYPE 110
diff --git a/lib/libcrypto/evp/evp_enc.c b/lib/libcrypto/evp/evp_enc.c
index db2deb69050..a229901956d 100644
--- a/lib/libcrypto/evp/evp_enc.c
+++ b/lib/libcrypto/evp/evp_enc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: evp_enc.c,v 1.39 2018/04/14 07:09:21 tb Exp $ */
+/* $OpenBSD: evp_enc.c,v 1.40 2019/03/17 18:07:41 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -153,7 +153,7 @@ EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
ctx->cipher_data = NULL;
}
ctx->key_len = cipher->key_len;
- ctx->flags = 0;
+ ctx->flags &= EVP_CIPHER_CTX_FLAG_WRAP_ALLOW;
if (ctx->cipher->flags & EVP_CIPH_CTRL_INIT) {
if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL)) {
EVPerror(EVP_R_INITIALIZATION_ERROR);
@@ -175,6 +175,12 @@ skip_to_init:
return 0;
}
+ if (!(ctx->flags & EVP_CIPHER_CTX_FLAG_WRAP_ALLOW) &&
+ EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_WRAP_MODE) {
+ EVPerror(EVP_R_WRAP_MODE_NOT_ALLOWED);
+ return 0;
+ }
+
if (!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) {
switch (EVP_CIPHER_CTX_mode(ctx)) {
diff --git a/lib/libcrypto/evp/evp_err.c b/lib/libcrypto/evp/evp_err.c
index 1e1cc8350b7..814637c739e 100644
--- a/lib/libcrypto/evp/evp_err.c
+++ b/lib/libcrypto/evp/evp_err.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: evp_err.c,v 1.22 2017/01/29 17:49:23 beck Exp $ */
+/* $OpenBSD: evp_err.c,v 1.23 2019/03/17 18:07:41 tb Exp $ */
/* ====================================================================
* Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved.
*
@@ -147,6 +147,7 @@ static ERR_STRING_DATA EVP_str_reasons[] = {
{ERR_REASON(EVP_R_UNSUPPORTED_PRF) , "unsupported prf"},
{ERR_REASON(EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM), "unsupported private key algorithm"},
{ERR_REASON(EVP_R_UNSUPPORTED_SALT_TYPE) , "unsupported salt type"},
+ {ERR_REASON(EVP_R_WRAP_MODE_NOT_ALLOWED), "wrap mode not allowed"},
{ERR_REASON(EVP_R_WRONG_FINAL_BLOCK_LENGTH), "wrong final block length"},
{ERR_REASON(EVP_R_WRONG_PUBLIC_KEY_TYPE) , "wrong public key type"},
{0, NULL}