Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
snhenson committed Jul 18, 2014
1 parent 58f4698 commit d31fed7
Show file tree
Hide file tree
Showing 6 changed files with 342 additions and 20 deletions.
3 changes: 3 additions & 0 deletions crypto/evp/c_allc.c
Expand Up @@ -175,6 +175,7 @@ void OpenSSL_add_all_ciphers(void)
EVP_add_cipher(EVP_aes_128_xts());
EVP_add_cipher(EVP_aes_128_ccm());
EVP_add_cipher(EVP_aes_128_wrap());
EVP_add_cipher(EVP_aes_128_wrap_pad());
EVP_add_cipher_alias(SN_aes_128_cbc,"AES128");
EVP_add_cipher_alias(SN_aes_128_cbc,"aes128");
EVP_add_cipher(EVP_aes_192_ecb());
Expand All @@ -187,6 +188,7 @@ void OpenSSL_add_all_ciphers(void)
EVP_add_cipher(EVP_aes_192_gcm());
EVP_add_cipher(EVP_aes_192_ccm());
EVP_add_cipher(EVP_aes_192_wrap());
EVP_add_cipher(EVP_aes_192_wrap_pad());
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());
Expand All @@ -200,6 +202,7 @@ void OpenSSL_add_all_ciphers(void)
EVP_add_cipher(EVP_aes_256_xts());
EVP_add_cipher(EVP_aes_256_ccm());
EVP_add_cipher(EVP_aes_256_wrap());
EVP_add_cipher(EVP_aes_256_wrap_pad());
EVP_add_cipher_alias(SN_aes_256_cbc,"AES256");
EVP_add_cipher_alias(SN_aes_256_cbc,"aes256");
#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
Expand Down
96 changes: 85 additions & 11 deletions 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
Expand Down Expand Up @@ -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;
Expand All @@ -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;
}

Expand All @@ -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 };

Expand All @@ -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 };

Expand All @@ -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 };

Expand All @@ -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
3 changes: 3 additions & 0 deletions crypto/evp/evp.h
Expand Up @@ -849,6 +849,7 @@ const EVP_CIPHER *EVP_aes_128_ccm(void);
const EVP_CIPHER *EVP_aes_128_gcm(void);
const EVP_CIPHER *EVP_aes_128_xts(void);
const EVP_CIPHER *EVP_aes_128_wrap(void);
const EVP_CIPHER *EVP_aes_128_wrap_pad(void);
const EVP_CIPHER *EVP_aes_192_ecb(void);
const EVP_CIPHER *EVP_aes_192_cbc(void);
const EVP_CIPHER *EVP_aes_192_cfb1(void);
Expand All @@ -860,6 +861,7 @@ 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_192_wrap_pad(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);
Expand All @@ -872,6 +874,7 @@ const EVP_CIPHER *EVP_aes_256_ccm(void);
const EVP_CIPHER *EVP_aes_256_gcm(void);
const EVP_CIPHER *EVP_aes_256_xts(void);
const EVP_CIPHER *EVP_aes_256_wrap(void);
const EVP_CIPHER *EVP_aes_256_wrap_pad(void);
# if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void);
const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void);
Expand Down
4 changes: 4 additions & 0 deletions crypto/evp/evptests.txt
Expand Up @@ -401,3 +401,7 @@ id-aes256-wrap:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F:
id-aes192-wrap:000102030405060708090A0B0C0D0E0F1011121314151617::00112233445566778899AABBCCDDEEFF0001020304050607:031D33264E15D33268F24EC260743EDCE1C6C7DDEE725A936BA814915C6762D2
id-aes256-wrap:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F::00112233445566778899AABBCCDDEEFF0001020304050607:A8F9BC1612C68B3FF6E6F4FBE30E71E4769C8B80A32CB8958CD5D17D6B254DA1
id-aes256-wrap:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F::00112233445566778899AABBCCDDEEFF000102030405060708090A0B0C0D0E0F:28C9F404C4B810F4CBCCB35CFB87F8263F5786E2D80ED326CBC7F0E71A99F43BFB988B9B7A02DD21
# AES wrap tests from RFC5649
id-aes192-wrap-pad:5840df6e29b02af1ab493b705bf16ea1ae8338f4dcc176a8::c37b7e6492584340bed12207808941155068f738:138bdeaa9b8fa7fc61f97742e72248ee5ae6ae5360d1ae6a5f54f373fa543b6a
id-aes192-wrap-pad:5840df6e29b02af1ab493b705bf16ea1ae8338f4dcc176a8::466f7250617369:afbeb0f07dfbf5419200f2ccb50bb24f

6 changes: 6 additions & 0 deletions crypto/modes/modes.h
Expand Up @@ -141,3 +141,9 @@ size_t CRYPTO_128_wrap(void *key, const unsigned char *iv,
size_t CRYPTO_128_unwrap(void *key, const unsigned char *iv,
unsigned char *out,
const unsigned char *in, size_t inlen, block128_f block);
size_t CRYPTO_128_wrap_pad(void *key, const unsigned char *icv,
unsigned char *out,
const unsigned char *in, size_t inlen, block128_f block);
size_t CRYPTO_128_unwrap_pad(void *key, const unsigned char *icv,
unsigned char *out,
const unsigned char *in, size_t inlen, block128_f block);

5 comments on commit d31fed7

@agrandville
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, is there any reason why you don't merge aes wrap pad to the release version ?
regards

@richsalz
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you provide more details about what you think is wrong?

@agrandville
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wrap pad functions are only defined in the master branch

@richsalz
Copy link
Contributor

@richsalz richsalz commented on d31fed7 Dec 28, 2015 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@agrandville
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, aes key wrapping with padding seems to be disclosed in the future v1.1.0

Please sign in to comment.