Commit d31fed73 authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

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: default avatarTim Hudson <tjh@openssl.org>
parent 58f4698f
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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());
@@ -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());
@@ -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)
+85 −11
Original line number Diff line number Diff line
/* ====================================================================
 * 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 (pad)
		{
		if (ctx->encrypt)
		rv = CRYPTO_128_wrap(&wctx->ks.ks, wctx->iv, out, in, inlen,
			rv = CRYPTO_128_wrap_pad(&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,
			rv = CRYPTO_128_unwrap_pad(&wctx->ks.ks, wctx->iv,
						out, in, inlen,
						(block128_f)AES_decrypt);
		}
	else
		{
		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;
	}

@@ -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 −0
Original line number Diff line number Diff line
@@ -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);
@@ -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);
@@ -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);
+4 −0
Original line number Diff line number Diff line
@@ -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 −0
Original line number Diff line number Diff line
@@ -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);
Loading