mirror of
https://github.com/openssl/openssl.git
synced 2024-11-27 20:14:20 +08:00
Add RFC5297 AES-SIV support
Based originally on github.com/dfoxfranke/libaes_siv This creates an SIV128 mode that uses EVP interfaces for the CBC, CTR and CMAC code to reduce complexity at the cost of perfomance. The expected use is for short inputs, not TLS-sized records. Add multiple AAD input capacity in the EVP tests. Reviewed-by: Paul Dale <paul.dale@oracle.com> Reviewed-by: Bernd Edlinger <bernd.edlinger@hotmail.de> (Merged from https://github.com/openssl/openssl/pull/3540)
This commit is contained in:
parent
6de98b4fb6
commit
b1ceb439f2
3
CHANGES
3
CHANGES
@ -36,6 +36,9 @@
|
||||
and retain API/ABI compatibility.
|
||||
[Richard Levitte]
|
||||
|
||||
*) Add support for RFC5297 SIV mode (siv128), including AES-SIV.
|
||||
[Todd Short]
|
||||
|
||||
*) Remove the 'dist' target and add a tarball building script. The
|
||||
'dist' target has fallen out of use, and it shouldn't be
|
||||
necessary to configure just to create a source distribution.
|
||||
|
@ -391,6 +391,7 @@ my @disablables = (
|
||||
"seed",
|
||||
"shared",
|
||||
"siphash",
|
||||
"siv",
|
||||
"sm2",
|
||||
"sm3",
|
||||
"sm4",
|
||||
@ -498,6 +499,8 @@ my @disable_cascades = (
|
||||
sub { !$disabled{"unit-test"} } => [ "heartbeats" ],
|
||||
|
||||
sub { !$disabled{"msan"} } => [ "asm" ],
|
||||
|
||||
sub { $disabled{cmac}; } => [ "siv" ],
|
||||
);
|
||||
|
||||
# Avoid protocol support holes. Also disable all versions below N, if version
|
||||
|
6
INSTALL
6
INSTALL
@ -556,9 +556,9 @@
|
||||
Build without support for the specified algorithm, where
|
||||
<alg> is one of: aria, bf, blake2, camellia, cast, chacha,
|
||||
cmac, des, dh, dsa, ecdh, ecdsa, idea, md4, mdc2, ocb,
|
||||
poly1305, rc2, rc4, rmd160, scrypt, seed, siphash, sm2, sm3,
|
||||
sm4 or whirlpool. The "ripemd" algorithm is deprecated and
|
||||
if used is synonymous with rmd160.
|
||||
poly1305, rc2, rc4, rmd160, scrypt, seed, siphash, siv, sm2,
|
||||
sm3, sm4 or whirlpool. The "ripemd" algorithm is deprecated
|
||||
and if used is synonymous with rmd160.
|
||||
|
||||
-Dxxx, -Ixxx, -Wp, -lxxx, -Lxxx, -Wl, -rpath, -R, -framework, -static
|
||||
These system specific options will be recognised and
|
||||
|
@ -2657,6 +2657,10 @@ int speed_main(int argc, char **argv)
|
||||
EVP_CipherInit_ex(loopargs[k].ctx, NULL, NULL,
|
||||
loopargs[k].key, NULL, -1);
|
||||
OPENSSL_clear_free(loopargs[k].key, keylen);
|
||||
|
||||
/* SIV mode only allows for a single Update operation */
|
||||
if (EVP_CIPHER_mode(evp_cipher) == EVP_CIPH_SIV_MODE)
|
||||
EVP_CIPHER_CTX_ctrl(loopargs[k].ctx, EVP_CTRL_SET_SPEED, 1, NULL);
|
||||
}
|
||||
|
||||
Time_F(START);
|
||||
|
@ -190,7 +190,11 @@ void openssl_add_all_ciphers_int(void)
|
||||
EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1());
|
||||
EVP_add_cipher(EVP_aes_128_cbc_hmac_sha256());
|
||||
EVP_add_cipher(EVP_aes_256_cbc_hmac_sha256());
|
||||
|
||||
#ifndef OPENSSL_NO_SIV
|
||||
EVP_add_cipher(EVP_aes_128_siv());
|
||||
EVP_add_cipher(EVP_aes_192_siv());
|
||||
EVP_add_cipher(EVP_aes_256_siv());
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_ARIA
|
||||
EVP_add_cipher(EVP_aria_128_ecb());
|
||||
EVP_add_cipher(EVP_aria_128_cbc());
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "internal/evp_int.h"
|
||||
#include "modes_lcl.h"
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/cmac.h>
|
||||
#include "evp_locl.h"
|
||||
|
||||
typedef struct {
|
||||
@ -540,7 +541,8 @@ const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
|
||||
# define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \
|
||||
static const EVP_CIPHER aesni_##keylen##_##mode = { \
|
||||
nid##_##keylen##_##mode,blocksize, \
|
||||
(EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
|
||||
(EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE||EVP_CIPH_##MODE##_MODE==EVP_CIPH_SIV_MODE?2:1)*keylen/8, \
|
||||
ivlen, \
|
||||
flags|EVP_CIPH_##MODE##_MODE, \
|
||||
aesni_##mode##_init_key, \
|
||||
aesni_##mode##_cipher, \
|
||||
@ -549,7 +551,8 @@ static const EVP_CIPHER aesni_##keylen##_##mode = { \
|
||||
NULL,NULL,aes_##mode##_ctrl,NULL }; \
|
||||
static const EVP_CIPHER aes_##keylen##_##mode = { \
|
||||
nid##_##keylen##_##mode,blocksize, \
|
||||
(EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
|
||||
(EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE||EVP_CIPH_##MODE##_MODE==EVP_CIPH_SIV_MODE?2:1)*keylen/8, \
|
||||
ivlen, \
|
||||
flags|EVP_CIPH_##MODE##_MODE, \
|
||||
aes_##mode##_init_key, \
|
||||
aes_##mode##_cipher, \
|
||||
@ -948,7 +951,8 @@ const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
|
||||
# define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \
|
||||
static const EVP_CIPHER aes_t4_##keylen##_##mode = { \
|
||||
nid##_##keylen##_##mode,blocksize, \
|
||||
(EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
|
||||
(EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE||EVP_CIPH_##MODE##_MODE==EVP_CIPH_SIV_MODE?2:1)*keylen/8, \
|
||||
ivlen, \
|
||||
flags|EVP_CIPH_##MODE##_MODE, \
|
||||
aes_t4_##mode##_init_key, \
|
||||
aes_t4_##mode##_cipher, \
|
||||
@ -957,7 +961,8 @@ static const EVP_CIPHER aes_t4_##keylen##_##mode = { \
|
||||
NULL,NULL,aes_##mode##_ctrl,NULL }; \
|
||||
static const EVP_CIPHER aes_##keylen##_##mode = { \
|
||||
nid##_##keylen##_##mode,blocksize, \
|
||||
(EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
|
||||
(EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE||EVP_CIPH_##MODE##_MODE==EVP_CIPH_SIV_MODE?2:1)*keylen/8, \
|
||||
ivlen, \
|
||||
flags|EVP_CIPH_##MODE##_MODE, \
|
||||
aes_##mode##_init_key, \
|
||||
aes_##mode##_cipher, \
|
||||
@ -2512,7 +2517,8 @@ const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
|
||||
# define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \
|
||||
static const EVP_CIPHER aes_##keylen##_##mode = { \
|
||||
nid##_##keylen##_##mode,blocksize, \
|
||||
(EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
|
||||
(EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE||EVP_CIPH_##MODE##_MODE==EVP_CIPH_SIV_MODE?2:1)*keylen/8, \
|
||||
ivlen, \
|
||||
flags|EVP_CIPH_##MODE##_MODE, \
|
||||
aes_##mode##_init_key, \
|
||||
aes_##mode##_cipher, \
|
||||
@ -4263,3 +4269,114 @@ BLOCK_CIPHER_custom(NID_aes, 192, 16, 12, ocb, OCB,
|
||||
BLOCK_CIPHER_custom(NID_aes, 256, 16, 12, ocb, OCB,
|
||||
EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS)
|
||||
#endif /* OPENSSL_NO_OCB */
|
||||
|
||||
/* AES-SIV mode */
|
||||
#ifndef OPENSSL_NO_SIV
|
||||
|
||||
typedef SIV128_CONTEXT EVP_AES_SIV_CTX;
|
||||
|
||||
#define aesni_siv_init_key aes_siv_init_key
|
||||
static int aes_siv_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||
const unsigned char *iv, int enc)
|
||||
{
|
||||
const EVP_CIPHER *ctr;
|
||||
const EVP_CIPHER *cbc;
|
||||
SIV128_CONTEXT *sctx = EVP_C_DATA(SIV128_CONTEXT, ctx);
|
||||
int klen = EVP_CIPHER_CTX_key_length(ctx) / 2;
|
||||
|
||||
if (key == NULL)
|
||||
return 1;
|
||||
|
||||
switch (klen) {
|
||||
case 16:
|
||||
cbc = EVP_aes_128_cbc();
|
||||
ctr = EVP_aes_128_ctr();
|
||||
break;
|
||||
case 24:
|
||||
cbc = EVP_aes_192_cbc();
|
||||
ctr = EVP_aes_192_ctr();
|
||||
break;
|
||||
case 32:
|
||||
cbc = EVP_aes_256_cbc();
|
||||
ctr = EVP_aes_256_ctr();
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* klen is the length of the underlying cipher, not the input key,
|
||||
which should be twice as long */
|
||||
return CRYPTO_siv128_init(sctx, key, klen, cbc, ctr);
|
||||
}
|
||||
|
||||
#define aesni_siv_cipher aes_siv_cipher
|
||||
static int aes_siv_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
const unsigned char *in, size_t len)
|
||||
{
|
||||
SIV128_CONTEXT *sctx = EVP_C_DATA(SIV128_CONTEXT, ctx);
|
||||
|
||||
/* EncryptFinal or DecryptFinal */
|
||||
if (in == NULL)
|
||||
return CRYPTO_siv128_finish(sctx);
|
||||
|
||||
/* Deal with associated data */
|
||||
if (out == NULL)
|
||||
return CRYPTO_siv128_aad(sctx, in, len);
|
||||
|
||||
if (EVP_CIPHER_CTX_encrypting(ctx))
|
||||
return CRYPTO_siv128_encrypt(sctx, in, out, len);
|
||||
|
||||
return CRYPTO_siv128_decrypt(sctx, in, out, len);
|
||||
}
|
||||
|
||||
#define aesni_siv_cleanup aes_siv_cleanup
|
||||
static int aes_siv_cleanup(EVP_CIPHER_CTX *c)
|
||||
{
|
||||
SIV128_CONTEXT *sctx = EVP_C_DATA(SIV128_CONTEXT, c);
|
||||
|
||||
return CRYPTO_siv128_cleanup(sctx);
|
||||
}
|
||||
|
||||
|
||||
#define aesni_siv_ctrl aes_siv_ctrl
|
||||
static int aes_siv_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
|
||||
{
|
||||
SIV128_CONTEXT *sctx = EVP_C_DATA(SIV128_CONTEXT, c);
|
||||
SIV128_CONTEXT *sctx_out;
|
||||
|
||||
switch (type) {
|
||||
case EVP_CTRL_INIT:
|
||||
return CRYPTO_siv128_cleanup(sctx);
|
||||
|
||||
case EVP_CTRL_SET_SPEED:
|
||||
return CRYPTO_siv128_speed(sctx, arg);
|
||||
|
||||
case EVP_CTRL_AEAD_SET_TAG:
|
||||
if (!EVP_CIPHER_CTX_encrypting(c))
|
||||
return CRYPTO_siv128_set_tag(sctx, ptr, arg);
|
||||
return 1;
|
||||
|
||||
case EVP_CTRL_AEAD_GET_TAG:
|
||||
if (!EVP_CIPHER_CTX_encrypting(c))
|
||||
return 0;
|
||||
return CRYPTO_siv128_get_tag(sctx, ptr, arg);
|
||||
|
||||
case EVP_CTRL_COPY:
|
||||
sctx_out = EVP_C_DATA(SIV128_CONTEXT, (EVP_CIPHER_CTX*)ptr);
|
||||
return CRYPTO_siv128_copy_ctx(sctx_out, sctx);
|
||||
|
||||
default:
|
||||
return -1;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#define SIV_FLAGS (EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_DEFAULT_ASN1 \
|
||||
| EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \
|
||||
| EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_COPY \
|
||||
| EVP_CIPH_CTRL_INIT)
|
||||
|
||||
BLOCK_CIPHER_custom(NID_aes, 128, 1, 0, siv, SIV, SIV_FLAGS)
|
||||
BLOCK_CIPHER_custom(NID_aes, 192, 1, 0, siv, SIV, SIV_FLAGS)
|
||||
BLOCK_CIPHER_custom(NID_aes, 256, 1, 0, siv, SIV, SIV_FLAGS)
|
||||
#endif
|
||||
|
@ -1,7 +1,7 @@
|
||||
LIBS=../../libcrypto
|
||||
SOURCE[../../libcrypto]=\
|
||||
cbc128.c ctr128.c cts128.c cfb128.c ofb128.c gcm128.c \
|
||||
ccm128.c xts128.c wrap128.c ocb128.c \
|
||||
ccm128.c xts128.c wrap128.c ocb128.c siv128.c \
|
||||
{- $target{modes_asm_src} -}
|
||||
|
||||
INCLUDE[gcm128.o]=..
|
||||
|
@ -188,3 +188,28 @@ struct ocb128_context {
|
||||
} sess;
|
||||
};
|
||||
#endif /* OPENSSL_NO_OCB */
|
||||
|
||||
#ifndef OPENSSL_NO_SIV
|
||||
|
||||
#include <openssl/cmac.h>
|
||||
|
||||
#define SIV_LEN 16
|
||||
|
||||
typedef union siv_block_u {
|
||||
uint64_t word[SIV_LEN/sizeof(uint64_t)];
|
||||
unsigned char byte[SIV_LEN];
|
||||
} SIV_BLOCK;
|
||||
|
||||
struct siv128_context {
|
||||
/* d stores intermediate results of S2V; it corresponds to D from the
|
||||
pseudocode in section 2.4 of RFC 5297. */
|
||||
SIV_BLOCK d;
|
||||
SIV_BLOCK tag;
|
||||
EVP_CIPHER_CTX *cipher_ctx;
|
||||
CMAC_CTX *cmac_ctx_init;
|
||||
CMAC_CTX *cmac_ctx;
|
||||
int final_ret;
|
||||
int crypto_ok;
|
||||
};
|
||||
|
||||
#endif /* OPENSSL_NO_SIV */
|
||||
|
349
crypto/modes/siv128.c
Normal file
349
crypto/modes/siv128.c
Normal file
@ -0,0 +1,349 @@
|
||||
/*
|
||||
* Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/cmac.h>
|
||||
#include "modes_lcl.h"
|
||||
|
||||
#ifndef OPENSSL_NO_SIV
|
||||
|
||||
__owur static ossl_inline uint32_t rotl8(uint32_t x)
|
||||
{
|
||||
return (x << 8) | (x >> 24);
|
||||
}
|
||||
|
||||
__owur static ossl_inline uint32_t rotr8(uint32_t x)
|
||||
{
|
||||
return (x >> 8) | (x << 24);
|
||||
}
|
||||
|
||||
__owur static ossl_inline uint64_t byteswap8(uint64_t x)
|
||||
{
|
||||
uint32_t high = (uint32_t)(x >> 32);
|
||||
uint32_t low = (uint32_t)x;
|
||||
|
||||
high = (rotl8(high) & 0x00ff00ff) | (rotr8(high) & 0xff00ff00);
|
||||
low = (rotl8(low) & 0x00ff00ff) | (rotr8(low) & 0xff00ff00);
|
||||
return ((uint64_t)low) << 32 | (uint64_t)high;
|
||||
}
|
||||
|
||||
__owur static ossl_inline uint64_t siv128_getword(SIV_BLOCK const *b, size_t i)
|
||||
{
|
||||
const union {
|
||||
long one;
|
||||
char little;
|
||||
} is_endian = { 1 };
|
||||
|
||||
if (is_endian.little)
|
||||
return byteswap8(b->word[i]);
|
||||
return b->word[i];
|
||||
}
|
||||
|
||||
static ossl_inline void siv128_putword(SIV_BLOCK *b, size_t i, uint64_t x)
|
||||
{
|
||||
const union {
|
||||
long one;
|
||||
char little;
|
||||
} is_endian = { 1 };
|
||||
|
||||
if (is_endian.little)
|
||||
b->word[i] = byteswap8(x);
|
||||
else
|
||||
b->word[i] = x;
|
||||
}
|
||||
|
||||
static ossl_inline void siv128_xorblock(SIV_BLOCK *x,
|
||||
SIV_BLOCK const *y)
|
||||
{
|
||||
x->word[0] ^= y->word[0];
|
||||
x->word[1] ^= y->word[1];
|
||||
}
|
||||
|
||||
/*
|
||||
* Doubles |b|, which is 16 bytes representing an element
|
||||
* of GF(2**128) modulo the irreducible polynomial
|
||||
* x**128 + x**7 + x**2 + x + 1.
|
||||
* Assumes two's-complement arithmetic
|
||||
*/
|
||||
static ossl_inline void siv128_dbl(SIV_BLOCK *b)
|
||||
{
|
||||
uint64_t high = siv128_getword(b, 0);
|
||||
uint64_t low = siv128_getword(b, 1);
|
||||
uint64_t high_carry = high & (((uint64_t)1) << 63);
|
||||
uint64_t low_carry = low & (((uint64_t)1) << 63);
|
||||
int64_t low_mask = -((int64_t)(high_carry >> 63)) & 0x87;
|
||||
uint64_t high_mask = low_carry >> 63;
|
||||
|
||||
high = (high << 1) | high_mask;
|
||||
low = (low << 1) ^ (uint64_t)low_mask;
|
||||
siv128_putword(b, 0, high);
|
||||
siv128_putword(b, 1, low);
|
||||
}
|
||||
|
||||
__owur static ossl_inline int siv128_do_s2v_p(SIV128_CONTEXT *ctx, SIV_BLOCK *out,
|
||||
unsigned char const* in, size_t len)
|
||||
{
|
||||
SIV_BLOCK t;
|
||||
size_t out_len = sizeof(out->byte);
|
||||
|
||||
if (!CMAC_CTX_copy(ctx->cmac_ctx, ctx->cmac_ctx_init))
|
||||
return 0;
|
||||
|
||||
if (len >= SIV_LEN) {
|
||||
if (!CMAC_Update(ctx->cmac_ctx, in, len - SIV_LEN))
|
||||
return 0;
|
||||
memcpy(&t, in + (len-SIV_LEN), SIV_LEN);
|
||||
siv128_xorblock(&t, &ctx->d);
|
||||
if (!CMAC_Update(ctx->cmac_ctx, t.byte, SIV_LEN))
|
||||
return 0;
|
||||
} else {
|
||||
memset(&t, 0, sizeof(t));
|
||||
memcpy(&t, in, len);
|
||||
t.byte[len] = 0x80;
|
||||
siv128_dbl(&ctx->d);
|
||||
siv128_xorblock(&t, &ctx->d);
|
||||
if (!CMAC_Update(ctx->cmac_ctx, t.byte, SIV_LEN))
|
||||
return 0;
|
||||
}
|
||||
if (!CMAC_Final(ctx->cmac_ctx, out->byte, &out_len)
|
||||
|| out_len != SIV_LEN)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
__owur static ossl_inline int siv128_do_encrypt(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
unsigned char const *in, size_t len,
|
||||
SIV_BLOCK *icv)
|
||||
{
|
||||
int out_len = (int)len;
|
||||
|
||||
if (!EVP_CipherInit_ex(ctx, NULL, NULL, NULL, icv->byte, 1))
|
||||
return 0;
|
||||
return EVP_EncryptUpdate(ctx, out, &out_len, in, out_len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a new SIV128_CONTEXT
|
||||
*/
|
||||
SIV128_CONTEXT *CRYPTO_siv128_new(const unsigned char *key, int klen, EVP_CIPHER* cbc, EVP_CIPHER* ctr)
|
||||
{
|
||||
SIV128_CONTEXT *ctx;
|
||||
int ret;
|
||||
|
||||
if ((ctx = OPENSSL_malloc(sizeof(*ctx))) != NULL) {
|
||||
ret = CRYPTO_siv128_init(ctx, key, klen, cbc, ctr);
|
||||
if (ret)
|
||||
return ctx;
|
||||
OPENSSL_free(ctx);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialise an existing SIV128_CONTEXT
|
||||
*/
|
||||
int CRYPTO_siv128_init(SIV128_CONTEXT *ctx, const unsigned char *key, int klen,
|
||||
const EVP_CIPHER* cbc, const EVP_CIPHER* ctr)
|
||||
{
|
||||
static const unsigned char zero[SIV_LEN] = { 0 };
|
||||
size_t out_len = SIV_LEN;
|
||||
|
||||
memset(&ctx->d, 0, sizeof(ctx->d));
|
||||
ctx->cipher_ctx = NULL;
|
||||
ctx->cmac_ctx = NULL;
|
||||
ctx->cmac_ctx_init = NULL;
|
||||
|
||||
if (key == NULL || cbc == NULL || ctr == NULL
|
||||
|| (ctx->cipher_ctx = EVP_CIPHER_CTX_new()) == NULL
|
||||
|| (ctx->cmac_ctx_init = CMAC_CTX_new()) == NULL
|
||||
|| (ctx->cmac_ctx = CMAC_CTX_new()) == NULL
|
||||
|| !CMAC_Init(ctx->cmac_ctx_init, key, klen, cbc, NULL)
|
||||
|| !EVP_EncryptInit_ex(ctx->cipher_ctx, ctr, NULL, key + klen, NULL)
|
||||
|| !CMAC_CTX_copy(ctx->cmac_ctx, ctx->cmac_ctx_init)
|
||||
|| !CMAC_Update(ctx->cmac_ctx, zero, sizeof(zero))
|
||||
|| !CMAC_Final(ctx->cmac_ctx, ctx->d.byte, &out_len)) {
|
||||
EVP_CIPHER_CTX_free(ctx->cipher_ctx);
|
||||
CMAC_CTX_free(ctx->cmac_ctx_init);
|
||||
CMAC_CTX_free(ctx->cmac_ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ctx->final_ret = -1;
|
||||
ctx->crypto_ok = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy an SIV128_CONTEXT object
|
||||
*/
|
||||
int CRYPTO_siv128_copy_ctx(SIV128_CONTEXT *dest, SIV128_CONTEXT *src)
|
||||
{
|
||||
memcpy(&dest->d, &src->d, sizeof(src->d));
|
||||
if (!EVP_CIPHER_CTX_copy(dest->cipher_ctx, src->cipher_ctx))
|
||||
return 0;
|
||||
if (!CMAC_CTX_copy(dest->cmac_ctx_init, src->cmac_ctx_init))
|
||||
return 0;
|
||||
/* no need to copy cmac_ctx since it's temp storage */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Provide any AAD. This can be called multiple times.
|
||||
* Per RFC5297, the last piece of associated data
|
||||
* is the nonce, but it's not treated special
|
||||
*/
|
||||
int CRYPTO_siv128_aad(SIV128_CONTEXT *ctx, const unsigned char *aad,
|
||||
size_t len)
|
||||
{
|
||||
SIV_BLOCK cmac_out;
|
||||
size_t out_len = SIV_LEN;
|
||||
|
||||
siv128_dbl(&ctx->d);
|
||||
|
||||
if (!CMAC_CTX_copy(ctx->cmac_ctx, ctx->cmac_ctx_init)
|
||||
|| !CMAC_Update(ctx->cmac_ctx, aad, len)
|
||||
|| !CMAC_Final(ctx->cmac_ctx, cmac_out.byte, &out_len)
|
||||
|| out_len != SIV_LEN)
|
||||
return 0;
|
||||
|
||||
siv128_xorblock(&ctx->d, &cmac_out);
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Provide any data to be encrypted. This can be called once.
|
||||
*/
|
||||
int CRYPTO_siv128_encrypt(SIV128_CONTEXT *ctx,
|
||||
const unsigned char *in, unsigned char *out,
|
||||
size_t len)
|
||||
{
|
||||
SIV_BLOCK q;
|
||||
|
||||
/* can only do one crypto operation */
|
||||
if (ctx->crypto_ok == 0)
|
||||
return 0;
|
||||
ctx->crypto_ok--;
|
||||
|
||||
if (!siv128_do_s2v_p(ctx, &q, in, len))
|
||||
return 0;
|
||||
|
||||
memcpy(ctx->tag.byte, &q, SIV_LEN);
|
||||
q.byte[8] &= 0x7f;
|
||||
q.byte[12] &= 0x7f;
|
||||
|
||||
if (!siv128_do_encrypt(ctx->cipher_ctx, out, in, len, &q))
|
||||
return 0;
|
||||
ctx->final_ret = 0;
|
||||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Provide any data to be decrypted. This can be called once.
|
||||
*/
|
||||
int CRYPTO_siv128_decrypt(SIV128_CONTEXT *ctx,
|
||||
const unsigned char *in, unsigned char *out,
|
||||
size_t len)
|
||||
{
|
||||
unsigned char* p;
|
||||
SIV_BLOCK t, q;
|
||||
int i;
|
||||
|
||||
/* can only do one crypto operation */
|
||||
if (ctx->crypto_ok == 0)
|
||||
return 0;
|
||||
ctx->crypto_ok--;
|
||||
|
||||
memcpy(&q, ctx->tag.byte, SIV_LEN);
|
||||
q.byte[8] &= 0x7f;
|
||||
q.byte[12] &= 0x7f;
|
||||
|
||||
if (!siv128_do_encrypt(ctx->cipher_ctx, out, in, len, &q)
|
||||
|| !siv128_do_s2v_p(ctx, &t, out, len))
|
||||
return 0;
|
||||
|
||||
p = ctx->tag.byte;
|
||||
for (i = 0; i < SIV_LEN; i++)
|
||||
t.byte[i] ^= p[i];
|
||||
|
||||
if ((t.word[0] | t.word[1]) != 0) {
|
||||
OPENSSL_cleanse(out, len);
|
||||
return 0;
|
||||
}
|
||||
ctx->final_ret = 0;
|
||||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the already calculated final result.
|
||||
*/
|
||||
int CRYPTO_siv128_finish(SIV128_CONTEXT *ctx)
|
||||
{
|
||||
return ctx->final_ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the tag
|
||||
*/
|
||||
int CRYPTO_siv128_set_tag(SIV128_CONTEXT *ctx, const unsigned char *tag, size_t len)
|
||||
{
|
||||
if (len != SIV_LEN)
|
||||
return 0;
|
||||
|
||||
/* Copy the tag from the supplied buffer */
|
||||
memcpy(ctx->tag.byte, tag, len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieve the calculated tag
|
||||
*/
|
||||
int CRYPTO_siv128_get_tag(SIV128_CONTEXT *ctx, unsigned char *tag, size_t len)
|
||||
{
|
||||
if (len != SIV_LEN)
|
||||
return 0;
|
||||
|
||||
/* Copy the tag into the supplied buffer */
|
||||
memcpy(tag, ctx->tag.byte, len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Release all resources
|
||||
*/
|
||||
int CRYPTO_siv128_cleanup(SIV128_CONTEXT *ctx)
|
||||
{
|
||||
if (ctx != NULL) {
|
||||
EVP_CIPHER_CTX_free(ctx->cipher_ctx);
|
||||
ctx->cipher_ctx = NULL;
|
||||
CMAC_CTX_free(ctx->cmac_ctx_init);
|
||||
ctx->cmac_ctx_init = NULL;
|
||||
CMAC_CTX_free(ctx->cmac_ctx);
|
||||
ctx->cmac_ctx = NULL;
|
||||
OPENSSL_cleanse(&ctx->d, sizeof(ctx->d));
|
||||
OPENSSL_cleanse(&ctx->tag, sizeof(ctx->tag));
|
||||
ctx->final_ret = -1;
|
||||
ctx->crypto_ok = 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CRYPTO_siv128_speed(SIV128_CONTEXT *ctx, int arg)
|
||||
{
|
||||
ctx->crypto_ok = (arg == 1) ? -1 : 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* OPENSSL_NO_SIV */
|
@ -1079,7 +1079,7 @@ static const unsigned char so[7767] = {
|
||||
0x28,0xCC,0x45,0x03,0x04, /* [ 7761] OBJ_gmac */
|
||||
};
|
||||
|
||||
#define NUM_NID 1198
|
||||
#define NUM_NID 1201
|
||||
static const ASN1_OBJECT nid_objs[NUM_NID] = {
|
||||
{"UNDEF", "undefined", NID_undef},
|
||||
{"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]},
|
||||
@ -2279,9 +2279,12 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = {
|
||||
{"GMAC", "gmac", NID_gmac, 5, &so[7761]},
|
||||
{"KMAC128", "kmac128", NID_kmac128},
|
||||
{"KMAC256", "kmac256", NID_kmac256},
|
||||
{"AES-128-SIV", "aes-128-siv", NID_aes_128_siv},
|
||||
{"AES-192-SIV", "aes-192-siv", NID_aes_192_siv},
|
||||
{"AES-256-SIV", "aes-256-siv", NID_aes_256_siv},
|
||||
};
|
||||
|
||||
#define NUM_SN 1189
|
||||
#define NUM_SN 1192
|
||||
static const unsigned int sn_objs[NUM_SN] = {
|
||||
364, /* "AD_DVCS" */
|
||||
419, /* "AES-128-CBC" */
|
||||
@ -2294,6 +2297,7 @@ static const unsigned int sn_objs[NUM_SN] = {
|
||||
418, /* "AES-128-ECB" */
|
||||
958, /* "AES-128-OCB" */
|
||||
420, /* "AES-128-OFB" */
|
||||
1198, /* "AES-128-SIV" */
|
||||
913, /* "AES-128-XTS" */
|
||||
423, /* "AES-192-CBC" */
|
||||
917, /* "AES-192-CBC-HMAC-SHA1" */
|
||||
@ -2305,6 +2309,7 @@ static const unsigned int sn_objs[NUM_SN] = {
|
||||
422, /* "AES-192-ECB" */
|
||||
959, /* "AES-192-OCB" */
|
||||
424, /* "AES-192-OFB" */
|
||||
1199, /* "AES-192-SIV" */
|
||||
427, /* "AES-256-CBC" */
|
||||
918, /* "AES-256-CBC-HMAC-SHA1" */
|
||||
950, /* "AES-256-CBC-HMAC-SHA256" */
|
||||
@ -2315,6 +2320,7 @@ static const unsigned int sn_objs[NUM_SN] = {
|
||||
426, /* "AES-256-ECB" */
|
||||
960, /* "AES-256-OCB" */
|
||||
428, /* "AES-256-OFB" */
|
||||
1200, /* "AES-256-SIV" */
|
||||
914, /* "AES-256-XTS" */
|
||||
1066, /* "ARIA-128-CBC" */
|
||||
1120, /* "ARIA-128-CCM" */
|
||||
@ -3474,7 +3480,7 @@ static const unsigned int sn_objs[NUM_SN] = {
|
||||
1093, /* "x509ExtAdmission" */
|
||||
};
|
||||
|
||||
#define NUM_LN 1189
|
||||
#define NUM_LN 1192
|
||||
static const unsigned int ln_objs[NUM_LN] = {
|
||||
363, /* "AD Time Stamping" */
|
||||
405, /* "ANSI X9.62" */
|
||||
@ -3701,6 +3707,7 @@ static const unsigned int ln_objs[NUM_LN] = {
|
||||
895, /* "aes-128-gcm" */
|
||||
958, /* "aes-128-ocb" */
|
||||
420, /* "aes-128-ofb" */
|
||||
1198, /* "aes-128-siv" */
|
||||
913, /* "aes-128-xts" */
|
||||
423, /* "aes-192-cbc" */
|
||||
917, /* "aes-192-cbc-hmac-sha1" */
|
||||
@ -3714,6 +3721,7 @@ static const unsigned int ln_objs[NUM_LN] = {
|
||||
898, /* "aes-192-gcm" */
|
||||
959, /* "aes-192-ocb" */
|
||||
424, /* "aes-192-ofb" */
|
||||
1199, /* "aes-192-siv" */
|
||||
427, /* "aes-256-cbc" */
|
||||
918, /* "aes-256-cbc-hmac-sha1" */
|
||||
950, /* "aes-256-cbc-hmac-sha256" */
|
||||
@ -3726,6 +3734,7 @@ static const unsigned int ln_objs[NUM_LN] = {
|
||||
901, /* "aes-256-gcm" */
|
||||
960, /* "aes-256-ocb" */
|
||||
428, /* "aes-256-ofb" */
|
||||
1200, /* "aes-256-siv" */
|
||||
914, /* "aes-256-xts" */
|
||||
376, /* "algorithm" */
|
||||
1066, /* "aria-128-cbc" */
|
||||
|
@ -1195,3 +1195,6 @@ hmacWithSHA512_256 1194
|
||||
gmac 1195
|
||||
kmac128 1196
|
||||
kmac256 1197
|
||||
aes_128_siv 1198
|
||||
aes_192_siv 1199
|
||||
aes_256_siv 1200
|
||||
|
@ -1645,7 +1645,6 @@ id-pkinit 5 : pkInitKDC : Signing KDC Response
|
||||
: Poly1305 : poly1305
|
||||
# NID for SipHash
|
||||
: SipHash : siphash
|
||||
|
||||
# NIDs for RFC7919 DH parameters
|
||||
: ffdhe2048
|
||||
: ffdhe3072
|
||||
@ -1682,3 +1681,7 @@ dstu4145le 2 6 : uacurve6 : DSTU curve 6
|
||||
dstu4145le 2 7 : uacurve7 : DSTU curve 7
|
||||
dstu4145le 2 8 : uacurve8 : DSTU curve 8
|
||||
dstu4145le 2 9 : uacurve9 : DSTU curve 9
|
||||
# NID for AES-SIV
|
||||
: AES-128-SIV : aes-128-siv
|
||||
: AES-192-SIV : aes-192-siv
|
||||
: AES-256-SIV : aes-256-siv
|
||||
|
@ -87,7 +87,7 @@ The available flags are:
|
||||
=item EVP_CIPH_STREAM_CIPHER, EVP_CIPH_ECB_MODE EVP_CIPH_CBC_MODE,
|
||||
EVP_CIPH_CFB_MODE, EVP_CIPH_OFB_MODE, EVP_CIPH_CTR_MODE, EVP_CIPH_GCM_MODE,
|
||||
EVP_CIPH_CCM_MODE, EVP_CIPH_XTS_MODE, EVP_CIPH_WRAP_MODE,
|
||||
EVP_CIPH_OCB_MODE
|
||||
EVP_CIPH_OCB_MODE, EVP_CIPH_SIV_MODE
|
||||
|
||||
The cipher mode.
|
||||
|
||||
|
@ -426,6 +426,49 @@ AES.
|
||||
|
||||
=back
|
||||
|
||||
=head2 SIV Mode
|
||||
|
||||
For SIV mode ciphers the behaviour of the EVP interface is subtly
|
||||
altered and several additional ctrl operations are supported.
|
||||
|
||||
To specify any additional authenticated data (AAD) and/or a Nonce, a call to
|
||||
EVP_CipherUpdate(), EVP_EncryptUpdate() or EVP_DecryptUpdate() should be made
|
||||
with the output parameter B<out> set to B<NULL>.
|
||||
|
||||
RFC5297 states that the Nonce is the last piece of AAD before the actual
|
||||
encrypt/decrypt takes place. The API does not differentiate the Nonce from
|
||||
other AAD.
|
||||
|
||||
When decrypting the return value of EVP_DecryptFinal() or EVP_CipherFinal()
|
||||
indicates if the operation was successful. If it does not indicate success
|
||||
the authentication operation has failed and any output data B<MUST NOT>
|
||||
be used as it is corrupted.
|
||||
|
||||
The following ctrls are supported in both SIV modes.
|
||||
|
||||
=over 4
|
||||
|
||||
=item EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, taglen, tag);
|
||||
|
||||
Writes B<taglen> bytes of the tag value to the buffer indicated by B<tag>.
|
||||
This call can only be made when encrypting data and B<after> all data has been
|
||||
processed (e.g. after an EVP_EncryptFinal() call). For SIV mode the taglen must
|
||||
be 16.
|
||||
|
||||
=item EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, taglen, tag);
|
||||
|
||||
Sets the expected tag to B<taglen> bytes from B<tag>. This call is only legal
|
||||
when decrypting data and must be made B<before> any data is processed (e.g.
|
||||
before any EVP_DecryptUpdate() call). For SIV mode the taglen must be 16.
|
||||
|
||||
=back
|
||||
|
||||
SIV mode makes two passes over the input data, thus, only one call to
|
||||
EVP_CipherUpdate(), EVP_EncryptUpdate() or EVP_DecryptUpdate() should be made
|
||||
with B<out> set to a non-B<NULL> value. A call to EVP_Decrypt_Final() or
|
||||
EVP_CipherFinal() is not required, but will indicate if the update
|
||||
operation succeeded.
|
||||
|
||||
=head2 ChaCha20-Poly1305
|
||||
|
||||
The following I<ctrl>s are supported for the ChaCha20-Poly1305 AEAD algorithm.
|
||||
|
@ -245,6 +245,7 @@ int (*EVP_CIPHER_meth_get_ctrl(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *,
|
||||
# define EVP_CIPH_XTS_MODE 0x10001
|
||||
# define EVP_CIPH_WRAP_MODE 0x10002
|
||||
# define EVP_CIPH_OCB_MODE 0x10003
|
||||
# define EVP_CIPH_SIV_MODE 0x10004
|
||||
# define EVP_CIPH_MODE 0xF0007
|
||||
/* Set if variable length cipher */
|
||||
# define EVP_CIPH_VARIABLE_LENGTH 0x8
|
||||
@ -352,6 +353,8 @@ int (*EVP_CIPHER_meth_get_ctrl(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *,
|
||||
# define EVP_CTRL_SET_PIPELINE_INPUT_LENS 0x24
|
||||
/* Get the IV used by the cipher */
|
||||
# define EVP_CTRL_GET_IV 0x25
|
||||
/* Tell the cipher it's doing a speed test (SIV disallows multiple ops) */
|
||||
# define EVP_CTRL_SET_SPEED 0x26
|
||||
|
||||
/* Padding modes */
|
||||
#define EVP_PADDING_PKCS7 1
|
||||
@ -858,6 +861,11 @@ const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void);
|
||||
const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void);
|
||||
const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha256(void);
|
||||
const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha256(void);
|
||||
# ifndef OPENSSL_NO_SIV
|
||||
const EVP_CIPHER *EVP_aes_128_siv(void);
|
||||
const EVP_CIPHER *EVP_aes_192_siv(void);
|
||||
const EVP_CIPHER *EVP_aes_256_siv(void);
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_ARIA
|
||||
const EVP_CIPHER *EVP_aria_128_ecb(void);
|
||||
const EVP_CIPHER *EVP_aria_128_cbc(void);
|
||||
|
@ -11,6 +11,7 @@
|
||||
# define HEADER_MODES_H
|
||||
|
||||
# include <stddef.h>
|
||||
# include <openssl/ossl_typ.h>
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -201,6 +202,32 @@ int CRYPTO_ocb128_tag(OCB128_CONTEXT *ctx, unsigned char *tag, size_t len);
|
||||
void CRYPTO_ocb128_cleanup(OCB128_CONTEXT *ctx);
|
||||
# endif /* OPENSSL_NO_OCB */
|
||||
|
||||
# ifndef OPENSSL_NO_SIV
|
||||
|
||||
typedef struct siv128_context SIV128_CONTEXT;
|
||||
|
||||
# define SIV_LEN 16
|
||||
|
||||
SIV128_CONTEXT *CRYPTO_siv128_new(const unsigned char *key, int klen, EVP_CIPHER* cbc, EVP_CIPHER* ctr);
|
||||
int CRYPTO_siv128_init(SIV128_CONTEXT *ctx, const unsigned char *key, int klen,
|
||||
const EVP_CIPHER* cbc, const EVP_CIPHER* ctr);
|
||||
int CRYPTO_siv128_copy_ctx(SIV128_CONTEXT *dest, SIV128_CONTEXT *src);
|
||||
int CRYPTO_siv128_aad(SIV128_CONTEXT *ctx, const unsigned char *aad,
|
||||
size_t len);
|
||||
int CRYPTO_siv128_encrypt(SIV128_CONTEXT *ctx,
|
||||
const unsigned char *in, unsigned char *out,
|
||||
size_t len);
|
||||
int CRYPTO_siv128_decrypt(SIV128_CONTEXT *ctx,
|
||||
const unsigned char *in, unsigned char *out,
|
||||
size_t len);
|
||||
int CRYPTO_siv128_finish(SIV128_CONTEXT *ctx);
|
||||
int CRYPTO_siv128_set_tag(SIV128_CONTEXT *ctx, const unsigned char *tag, size_t len);
|
||||
int CRYPTO_siv128_get_tag(SIV128_CONTEXT *ctx, unsigned char *tag, size_t len);
|
||||
int CRYPTO_siv128_cleanup(SIV128_CONTEXT *ctx);
|
||||
int CRYPTO_siv128_speed(SIV128_CONTEXT *ctx, int arg);
|
||||
|
||||
# endif /* OPENSSL_NO_SIV */
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
|
@ -5209,3 +5209,15 @@
|
||||
#define LN_uacurve9 "DSTU curve 9"
|
||||
#define NID_uacurve9 1169
|
||||
#define OBJ_uacurve9 OBJ_dstu4145le,2L,9L
|
||||
|
||||
#define SN_aes_128_siv "AES-128-SIV"
|
||||
#define LN_aes_128_siv "aes-128-siv"
|
||||
#define NID_aes_128_siv 1198
|
||||
|
||||
#define SN_aes_192_siv "AES-192-SIV"
|
||||
#define LN_aes_192_siv "aes-192-siv"
|
||||
#define NID_aes_192_siv 1199
|
||||
|
||||
#define SN_aes_256_siv "AES-256-SIV"
|
||||
#define LN_aes_256_siv "aes-256-siv"
|
||||
#define NID_aes_256_siv 1200
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "testutil.h"
|
||||
#include "evp_test.h"
|
||||
|
||||
#define AAD_NUM 4
|
||||
|
||||
typedef struct evp_test_method_st EVP_TEST_METHOD;
|
||||
|
||||
@ -457,9 +458,9 @@ typedef struct cipher_data_st {
|
||||
size_t plaintext_len;
|
||||
unsigned char *ciphertext;
|
||||
size_t ciphertext_len;
|
||||
/* GCM, CCM and OCB only */
|
||||
unsigned char *aad;
|
||||
size_t aad_len;
|
||||
/* GCM, CCM, OCB and SIV only */
|
||||
unsigned char *aad[AAD_NUM];
|
||||
size_t aad_len[AAD_NUM];
|
||||
unsigned char *tag;
|
||||
size_t tag_len;
|
||||
} CIPHER_DATA;
|
||||
@ -484,6 +485,7 @@ static int cipher_test_init(EVP_TEST *t, const char *alg)
|
||||
m = EVP_CIPHER_mode(cipher);
|
||||
if (m == EVP_CIPH_GCM_MODE
|
||||
|| m == EVP_CIPH_OCB_MODE
|
||||
|| m == EVP_CIPH_SIV_MODE
|
||||
|| m == EVP_CIPH_CCM_MODE)
|
||||
cdat->aead = m;
|
||||
else if (EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER)
|
||||
@ -497,13 +499,15 @@ static int cipher_test_init(EVP_TEST *t, const char *alg)
|
||||
|
||||
static void cipher_test_cleanup(EVP_TEST *t)
|
||||
{
|
||||
int i;
|
||||
CIPHER_DATA *cdat = t->data;
|
||||
|
||||
OPENSSL_free(cdat->key);
|
||||
OPENSSL_free(cdat->iv);
|
||||
OPENSSL_free(cdat->ciphertext);
|
||||
OPENSSL_free(cdat->plaintext);
|
||||
OPENSSL_free(cdat->aad);
|
||||
for (i = 0; i < AAD_NUM; i++)
|
||||
OPENSSL_free(cdat->aad[i]);
|
||||
OPENSSL_free(cdat->tag);
|
||||
}
|
||||
|
||||
@ -511,6 +515,7 @@ static int cipher_test_parse(EVP_TEST *t, const char *keyword,
|
||||
const char *value)
|
||||
{
|
||||
CIPHER_DATA *cdat = t->data;
|
||||
int i;
|
||||
|
||||
if (strcmp(keyword, "Key") == 0)
|
||||
return parse_bin(value, &cdat->key, &cdat->key_len);
|
||||
@ -521,8 +526,13 @@ static int cipher_test_parse(EVP_TEST *t, const char *keyword,
|
||||
if (strcmp(keyword, "Ciphertext") == 0)
|
||||
return parse_bin(value, &cdat->ciphertext, &cdat->ciphertext_len);
|
||||
if (cdat->aead) {
|
||||
if (strcmp(keyword, "AAD") == 0)
|
||||
return parse_bin(value, &cdat->aad, &cdat->aad_len);
|
||||
if (strcmp(keyword, "AAD") == 0) {
|
||||
for (i = 0; i < AAD_NUM; i++) {
|
||||
if (cdat->aad[i] == NULL)
|
||||
return parse_bin(value, &cdat->aad[i], &cdat->aad_len[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (strcmp(keyword, "Tag") == 0)
|
||||
return parse_bin(value, &cdat->tag, &cdat->tag_len);
|
||||
}
|
||||
@ -545,7 +555,7 @@ static int cipher_test_enc(EVP_TEST *t, int enc,
|
||||
CIPHER_DATA *expected = t->data;
|
||||
unsigned char *in, *expected_out, *tmp = NULL;
|
||||
size_t in_len, out_len, donelen = 0;
|
||||
int ok = 0, tmplen, chunklen, tmpflen;
|
||||
int ok = 0, tmplen, chunklen, tmpflen, i;
|
||||
EVP_CIPHER_CTX *ctx = NULL;
|
||||
|
||||
t->err = "TEST_FAILURE";
|
||||
@ -647,32 +657,36 @@ static int cipher_test_enc(EVP_TEST *t, int enc,
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
if (expected->aad) {
|
||||
if (expected->aad[0] != NULL) {
|
||||
t->err = "AAD_SET_ERROR";
|
||||
if (!frag) {
|
||||
if (!EVP_CipherUpdate(ctx, NULL, &chunklen, expected->aad,
|
||||
expected->aad_len))
|
||||
goto err;
|
||||
for (i = 0; expected->aad[i] != NULL; i++) {
|
||||
if (!EVP_CipherUpdate(ctx, NULL, &chunklen, expected->aad[i],
|
||||
expected->aad_len[i]))
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Supply the AAD in chunks less than the block size where possible
|
||||
*/
|
||||
if (expected->aad_len > 0) {
|
||||
if (!EVP_CipherUpdate(ctx, NULL, &chunklen, expected->aad, 1))
|
||||
goto err;
|
||||
donelen++;
|
||||
}
|
||||
if (expected->aad_len > 2) {
|
||||
if (!EVP_CipherUpdate(ctx, NULL, &chunklen,
|
||||
expected->aad + donelen,
|
||||
expected->aad_len - 2))
|
||||
goto err;
|
||||
donelen += expected->aad_len - 2;
|
||||
}
|
||||
if (expected->aad_len > 1
|
||||
for (i = 0; expected->aad[i] != NULL; i++) {
|
||||
if (expected->aad_len[i] > 0) {
|
||||
if (!EVP_CipherUpdate(ctx, NULL, &chunklen, expected->aad[i], 1))
|
||||
goto err;
|
||||
donelen++;
|
||||
}
|
||||
if (expected->aad_len[i] > 2) {
|
||||
if (!EVP_CipherUpdate(ctx, NULL, &chunklen,
|
||||
expected->aad[i] + donelen,
|
||||
expected->aad_len[i] - 2))
|
||||
goto err;
|
||||
donelen += expected->aad_len[i] - 2;
|
||||
}
|
||||
if (expected->aad_len[i] > 1
|
||||
&& !EVP_CipherUpdate(ctx, NULL, &chunklen,
|
||||
expected->aad + donelen, 1))
|
||||
goto err;
|
||||
expected->aad[i] + donelen, 1))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
EVP_CIPHER_CTX_set_padding(ctx, 0);
|
||||
@ -798,10 +812,11 @@ static int cipher_test_run(EVP_TEST *t)
|
||||
|
||||
if (out_misalign == 1 && frag == 0) {
|
||||
/*
|
||||
* XTS, CCM and Wrap modes have special requirements about input
|
||||
* XTS, SIV, CCM and Wrap modes have special requirements about input
|
||||
* lengths so we don't fragment for those
|
||||
*/
|
||||
if (cdat->aead == EVP_CIPH_CCM_MODE
|
||||
|| EVP_CIPHER_mode(cdat->cipher) == EVP_CIPH_SIV_MODE
|
||||
|| EVP_CIPHER_mode(cdat->cipher) == EVP_CIPH_XTS_MODE
|
||||
|| EVP_CIPHER_mode(cdat->cipher) == EVP_CIPH_WRAP_MODE)
|
||||
break;
|
||||
|
@ -16,7 +16,7 @@ setup("test_evp");
|
||||
|
||||
my @files = ( "evpciph.txt", "evpdigest.txt", "evpencod.txt", "evpkdf.txt",
|
||||
"evpmac.txt", "evppbe.txt", "evppkey.txt", "evppkey_ecc.txt",
|
||||
"evpcase.txt" );
|
||||
"evpcase.txt", "evpaessiv.txt" );
|
||||
|
||||
plan tests => scalar(@files);
|
||||
|
||||
|
44
test/recipes/30-test_evp_data/evpaessiv.txt
Normal file
44
test/recipes/30-test_evp_data/evpaessiv.txt
Normal file
@ -0,0 +1,44 @@
|
||||
#
|
||||
# Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the OpenSSL license (the "License"). You may not use
|
||||
# this file except in compliance with the License. You can obtain a copy
|
||||
# in the file LICENSE in the source distribution or at
|
||||
# https://www.openssl.org/source/license.html
|
||||
|
||||
# Tests start with one of these keywords
|
||||
# Cipher Decrypt Derive Digest Encoding KDF MAC PBE
|
||||
# PrivPubKeyPair Sign Verify VerifyRecover
|
||||
# and continue until a blank line. Lines starting with a pound sign,
|
||||
# like this prolog, are ignored.
|
||||
|
||||
Title = RFC5297 AES-SIV
|
||||
Cipher = aes-128-siv
|
||||
Key = fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff
|
||||
AAD = 101112131415161718191a1b1c1d1e1f2021222324252627
|
||||
Tag = 85632d07c6e8f37f950acd320a2ecc93
|
||||
Plaintext = 112233445566778899aabbccddee
|
||||
Ciphertext = 40c02b9690c4dc04daef7f6afe5c
|
||||
|
||||
Cipher = aes-128-siv
|
||||
Key = 7f7e7d7c7b7a79787776757473727170404142434445464748494a4b4c4d4e4f
|
||||
AAD = 00112233445566778899aabbccddeeffdeaddadadeaddadaffeeddccbbaa99887766554433221100
|
||||
AAD = 102030405060708090a0
|
||||
AAD = 09f911029d74e35bd84156c5635688c0
|
||||
Tag = 7bdb6e3b432667eb06f4d14bff2fbd0f
|
||||
Plaintext = 7468697320697320736f6d6520706c61696e7465787420746f20656e6372797074207573696e67205349562d414553
|
||||
Ciphertext = cb900f2fddbe404326601965c889bf17dba77ceb094fa663b7a3f748ba8af829ea64ad544a272e9c485b62a3fd5c0d
|
||||
|
||||
Cipher = aes-192-siv
|
||||
Key = fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0f0f1f2f3f4f5f6f7f8f9fafbfcfdfefffffefdfcfbfaf9f8f7f6f5f4f3f2f1f0
|
||||
AAD = 101112131415161718191a1b1c1d1e1f2021222324252627
|
||||
Tag = 89e869b93256785154f0963962fe0740
|
||||
Plaintext = 112233445566778899aabbccddee
|
||||
Ciphertext = eff356e42dec1f4febded36642f2
|
||||
|
||||
Cipher = aes-256-siv
|
||||
Key = fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0f0f1f2f3f4f5f6f7f8f9fafbfcfdfefff0f1f2f3f4f5f6f7f8f9fafbfcfdfefffffefdfcfbfaf9f8f7f6f5f4f3f2f1f0
|
||||
AAD = 101112131415161718191a1b1c1d1e1f2021222324252627
|
||||
Tag = 724dfb2eaf94dbb19b0ba3a299a0801e
|
||||
Plaintext = 112233445566778899aabbccddee
|
||||
Ciphertext = f3b05a55498ec2552690b89810e4
|
@ -4606,3 +4606,17 @@ OPENSSL_version_minor 4561 3_0_0 EXIST::FUNCTION:
|
||||
OPENSSL_version_patch 4562 3_0_0 EXIST::FUNCTION:
|
||||
OPENSSL_version_pre_release 4563 3_0_0 EXIST::FUNCTION:
|
||||
OPENSSL_version_build_metadata 4564 3_0_0 EXIST::FUNCTION:
|
||||
EVP_aes_128_siv 4565 3_0_0 EXIST::FUNCTION:SIV
|
||||
EVP_aes_192_siv 4566 3_0_0 EXIST::FUNCTION:SIV
|
||||
EVP_aes_256_siv 4567 3_0_0 EXIST::FUNCTION:SIV
|
||||
CRYPTO_siv128_new 4568 3_0_0 EXIST::FUNCTION:SIV
|
||||
CRYPTO_siv128_init 4569 3_0_0 EXIST::FUNCTION:SIV
|
||||
CRYPTO_siv128_copy_ctx 4570 3_0_0 EXIST::FUNCTION:SIV
|
||||
CRYPTO_siv128_aad 4571 3_0_0 EXIST::FUNCTION:SIV
|
||||
CRYPTO_siv128_encrypt 4572 3_0_0 EXIST::FUNCTION:SIV
|
||||
CRYPTO_siv128_decrypt 4573 3_0_0 EXIST::FUNCTION:SIV
|
||||
CRYPTO_siv128_finish 4574 3_0_0 EXIST::FUNCTION:SIV
|
||||
CRYPTO_siv128_set_tag 4575 3_0_0 EXIST::FUNCTION:SIV
|
||||
CRYPTO_siv128_get_tag 4576 3_0_0 EXIST::FUNCTION:SIV
|
||||
CRYPTO_siv128_cleanup 4577 3_0_0 EXIST::FUNCTION:SIV
|
||||
CRYPTO_siv128_speed 4578 3_0_0 EXIST::FUNCTION:SIV
|
||||
|
Loading…
Reference in New Issue
Block a user