aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/evp/e_aes.c
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2014-07-18 13:52:03 +0100
committerDr. Stephen Henson <steve@openssl.org>2014-07-18 21:37:13 +0100
commitd31fed73e25391cd71a0de488d88724db78f6f8a (patch)
tree8024c667ac28638030dcf4fc614fe78164b01f20 /crypto/evp/e_aes.c
parent58f4698f67c33b723a9e99bed1101161a59eea73 (diff)
downloadopenssl-d31fed73e25391cd71a0de488d88724db78f6f8a.tar.gz
RFC 5649 support.
Add support for RFC5649 key wrapping with padding. Add RFC5649 tests to evptests.txt Based on PR#3434 contribution by Petr Spacek <pspacek@redhat.com>. EVP support and minor changes added by Stephen Henson. Doxygen comment block updates by Tim Hudson. Reviewed-by: Tim Hudson <tjh@openssl.org>
Diffstat (limited to 'crypto/evp/e_aes.c')
-rw-r--r--crypto/evp/e_aes.c96
1 files changed, 85 insertions, 11 deletions
diff --git a/crypto/evp/e_aes.c b/crypto/evp/e_aes.c
index 3501066b07..89178bc16d 100644
--- a/crypto/evp/e_aes.c
+++ b/crypto/evp/e_aes.c
@@ -1,5 +1,5 @@
/* ====================================================================
- * Copyright (c) 2001-2011 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 2001-2014 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -2086,7 +2086,7 @@ static int aes_wrap_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
}
if (iv)
{
- memcpy(ctx->iv, iv, 8);
+ memcpy(ctx->iv, iv, EVP_CIPHER_CTX_iv_length(ctx));
wctx->iv = ctx->iv;
}
return 1;
@@ -2097,27 +2097,62 @@ static int aes_wrap_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
{
EVP_AES_WRAP_CTX *wctx = ctx->cipher_data;
size_t rv;
+ /* AES wrap with padding has IV length of 4, without padding 8 */
+ int pad = EVP_CIPHER_CTX_iv_length(ctx) == 4;
+ /* No final operation so always return zero length */
if (!in)
return 0;
- if (inlen % 8)
+ /* Input length must always be non-zero */
+ if (!inlen)
return -1;
- if (ctx->encrypt && inlen < 8)
+ /* If decrypting need at least 16 bytes and multiple of 8 */
+ if (!ctx->encrypt && (inlen < 16 || inlen & 0x7))
return -1;
- if (!ctx->encrypt && inlen < 16)
+ /* If not padding input must be multiple of 8 */
+ if (!pad && inlen & 0x7)
return -1;
if (!out)
{
if (ctx->encrypt)
+ {
+ /* If padding round up to multiple of 8 */
+ if (pad)
+ inlen = (inlen + 7)/8 * 8;
+ /* 8 byte prefix */
return inlen + 8;
+ }
else
+ {
+ /* If not padding output will be exactly 8 bytes
+ * smaller than input. If padding it will be at
+ * least 8 bytes smaller but we don't know how
+ * much.
+ */
return inlen - 8;
+ }
}
- if (ctx->encrypt)
- rv = CRYPTO_128_wrap(&wctx->ks.ks, wctx->iv, out, in, inlen,
+ if (pad)
+ {
+ if (ctx->encrypt)
+ rv = CRYPTO_128_wrap_pad(&wctx->ks.ks, wctx->iv,
+ out, in, inlen,
(block128_f)AES_encrypt);
+ else
+ rv = CRYPTO_128_unwrap_pad(&wctx->ks.ks, wctx->iv,
+ out, in, inlen,
+ (block128_f)AES_decrypt);
+ }
else
- rv = CRYPTO_128_unwrap(&wctx->ks.ks, wctx->iv, out, in, inlen,
+ {
+ if (ctx->encrypt)
+ rv = CRYPTO_128_wrap(&wctx->ks.ks, wctx->iv,
+ out, in, inlen,
+ (block128_f)AES_encrypt);
+ else
+ rv = CRYPTO_128_unwrap(&wctx->ks.ks, wctx->iv,
+ out, in, inlen,
(block128_f)AES_decrypt);
+ }
return rv ? (int)rv : -1;
}
@@ -2129,7 +2164,7 @@ static const EVP_CIPHER aes_128_wrap = {
NID_id_aes128_wrap,
8, 16, 8, WRAP_FLAGS,
aes_wrap_init_key, aes_wrap_cipher,
- NULL,
+ NULL,
sizeof(EVP_AES_WRAP_CTX),
NULL,NULL,NULL,NULL };
@@ -2142,7 +2177,7 @@ static const EVP_CIPHER aes_192_wrap = {
NID_id_aes192_wrap,
8, 24, 8, WRAP_FLAGS,
aes_wrap_init_key, aes_wrap_cipher,
- NULL,
+ NULL,
sizeof(EVP_AES_WRAP_CTX),
NULL,NULL,NULL,NULL };
@@ -2155,7 +2190,7 @@ static const EVP_CIPHER aes_256_wrap = {
NID_id_aes256_wrap,
8, 32, 8, WRAP_FLAGS,
aes_wrap_init_key, aes_wrap_cipher,
- NULL,
+ NULL,
sizeof(EVP_AES_WRAP_CTX),
NULL,NULL,NULL,NULL };
@@ -2164,4 +2199,43 @@ const EVP_CIPHER *EVP_aes_256_wrap(void)
return &aes_256_wrap;
}
+static const EVP_CIPHER aes_128_wrap_pad = {
+ NID_id_aes128_wrap_pad,
+ 8, 16, 4, WRAP_FLAGS,
+ aes_wrap_init_key, aes_wrap_cipher,
+ NULL,
+ sizeof(EVP_AES_WRAP_CTX),
+ NULL,NULL,NULL,NULL };
+
+const EVP_CIPHER *EVP_aes_128_wrap_pad(void)
+ {
+ return &aes_128_wrap_pad;
+ }
+
+static const EVP_CIPHER aes_192_wrap_pad = {
+ NID_id_aes192_wrap_pad,
+ 8, 24, 4, WRAP_FLAGS,
+ aes_wrap_init_key, aes_wrap_cipher,
+ NULL,
+ sizeof(EVP_AES_WRAP_CTX),
+ NULL,NULL,NULL,NULL };
+
+const EVP_CIPHER *EVP_aes_192_wrap_pad(void)
+ {
+ return &aes_192_wrap_pad;
+ }
+
+static const EVP_CIPHER aes_256_wrap_pad = {
+ NID_id_aes256_wrap_pad,
+ 8, 32, 4, WRAP_FLAGS,
+ aes_wrap_init_key, aes_wrap_cipher,
+ NULL,
+ sizeof(EVP_AES_WRAP_CTX),
+ NULL,NULL,NULL,NULL };
+
+const EVP_CIPHER *EVP_aes_256_wrap_pad(void)
+ {
+ return &aes_256_wrap_pad;
+ }
+
#endif