|
|
e79d4b |
From 2f61f102169e4d6652c9b82246353cd276366809 Mon Sep 17 00:00:00 2001
|
|
|
e79d4b |
From: Daiki Ueno <ueno@gnu.org>
|
|
|
e79d4b |
Date: Mon, 27 Jun 2022 11:14:50 +0900
|
|
|
e79d4b |
Subject: [PATCH] cipher: limit plaintext length supplied to AES-GCM
|
|
|
e79d4b |
|
|
|
e79d4b |
According to SP800-38D 5.2.1.1, input data length of AES-GCM
|
|
|
e79d4b |
encryption function must be less than or equal to 2^39-256 bits.
|
|
|
e79d4b |
|
|
|
e79d4b |
Signed-off-by: Daiki Ueno <ueno@gnu.org>
|
|
|
e79d4b |
---
|
|
|
e79d4b |
NEWS | 3 +
|
|
|
e79d4b |
lib/accelerated/aarch64/aes-aarch64.h | 15 ++++
|
|
|
e79d4b |
lib/accelerated/aarch64/aes-gcm-aarch64.c | 9 +++
|
|
|
e79d4b |
lib/accelerated/x86/aes-gcm-padlock.c | 29 ++++---
|
|
|
e79d4b |
lib/accelerated/x86/aes-gcm-x86-aesni.c | 30 +++++---
|
|
|
e79d4b |
lib/accelerated/x86/aes-gcm-x86-pclmul-avx.c | 9 +++
|
|
|
e79d4b |
lib/accelerated/x86/aes-gcm-x86-pclmul.c | 9 +++
|
|
|
e79d4b |
lib/accelerated/x86/aes-gcm-x86-ssse3.c | 30 +++++---
|
|
|
e79d4b |
lib/accelerated/x86/aes-x86.h | 15 ++++
|
|
|
e79d4b |
lib/nettle/cipher.c | 41 ++++++++++
|
|
|
e79d4b |
tests/slow/cipher-api-test.c | 79 ++++++++++++++++++++
|
|
|
e79d4b |
11 files changed, 240 insertions(+), 29 deletions(-)
|
|
|
e79d4b |
|
|
|
e79d4b |
diff --git a/lib/accelerated/aarch64/aes-aarch64.h b/lib/accelerated/aarch64/aes-aarch64.h
|
|
|
e79d4b |
index 692d8620d7..0e64f4ed8d 100644
|
|
|
e79d4b |
--- a/lib/accelerated/aarch64/aes-aarch64.h
|
|
|
e79d4b |
+++ b/lib/accelerated/aarch64/aes-aarch64.h
|
|
|
e79d4b |
@@ -20,6 +20,21 @@ typedef struct {
|
|
|
e79d4b |
if (s != 16 && s != 24 && s != 32) \
|
|
|
e79d4b |
return GNUTLS_E_INVALID_REQUEST
|
|
|
e79d4b |
|
|
|
e79d4b |
+#include <intprops.h>
|
|
|
e79d4b |
+#define AES_GCM_ENCRYPT_MAX_BYTES ((1ULL << 36) - 32)
|
|
|
e79d4b |
+static inline int
|
|
|
e79d4b |
+record_aes_gcm_encrypt_size(size_t *counter, size_t size) {
|
|
|
e79d4b |
+ size_t sum;
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ if (!INT_ADD_OK(*counter, size, &sum) ||
|
|
|
e79d4b |
+ sum > AES_GCM_ENCRYPT_MAX_BYTES) {
|
|
|
e79d4b |
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
|
|
|
e79d4b |
+ }
|
|
|
e79d4b |
+ *counter = sum;
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ return 0;
|
|
|
e79d4b |
+}
|
|
|
e79d4b |
+
|
|
|
e79d4b |
int aes_v8_set_encrypt_key(const unsigned char *userKey, int bits, AES_KEY *key);
|
|
|
e79d4b |
int aes_v8_set_decrypt_key(const unsigned char *userKey, int bits, AES_KEY *key);
|
|
|
e79d4b |
void aes_v8_cbc_encrypt(const unsigned char *in, unsigned char *out,
|
|
|
e79d4b |
diff --git a/lib/accelerated/aarch64/aes-gcm-aarch64.c b/lib/accelerated/aarch64/aes-gcm-aarch64.c
|
|
|
e79d4b |
index 901bd9f60f..be1e69c784 100644
|
|
|
e79d4b |
--- a/lib/accelerated/aarch64/aes-gcm-aarch64.c
|
|
|
e79d4b |
+++ b/lib/accelerated/aarch64/aes-gcm-aarch64.c
|
|
|
e79d4b |
@@ -62,6 +62,7 @@ struct aes_gcm_ctx {
|
|
|
e79d4b |
struct gcm128_context gcm;
|
|
|
e79d4b |
unsigned finished;
|
|
|
e79d4b |
unsigned auth_finished;
|
|
|
e79d4b |
+ size_t rekey_counter;
|
|
|
e79d4b |
};
|
|
|
e79d4b |
|
|
|
e79d4b |
void gcm_init_v8(u128 Htable[16], const uint64_t Xi[2]);
|
|
|
e79d4b |
@@ -116,6 +117,7 @@ aes_gcm_cipher_setkey(void *_ctx, const void *userkey, size_t keysize)
|
|
|
e79d4b |
ctx->gcm.H.u[1] = bswap_64(ctx->gcm.H.u[1]);
|
|
|
e79d4b |
|
|
|
e79d4b |
gcm_init_v8(ctx->gcm.Htable, ctx->gcm.H.u);
|
|
|
e79d4b |
+ ctx->rekey_counter = 0;
|
|
|
e79d4b |
|
|
|
e79d4b |
return 0;
|
|
|
e79d4b |
}
|
|
|
e79d4b |
@@ -141,6 +143,7 @@ static int aes_gcm_setiv(void *_ctx, const void *iv, size_t iv_size)
|
|
|
e79d4b |
ctx->gcm.Yi.c[GCM_BLOCK_SIZE - 1] = 2;
|
|
|
e79d4b |
ctx->finished = 0;
|
|
|
e79d4b |
ctx->auth_finished = 0;
|
|
|
e79d4b |
+ ctx->rekey_counter = 0;
|
|
|
e79d4b |
return 0;
|
|
|
e79d4b |
}
|
|
|
e79d4b |
|
|
|
e79d4b |
@@ -229,6 +232,7 @@ aes_gcm_encrypt(void *_ctx, const void *src, size_t src_size,
|
|
|
e79d4b |
int exp_blocks = blocks * GCM_BLOCK_SIZE;
|
|
|
e79d4b |
int rest = src_size - (exp_blocks);
|
|
|
e79d4b |
uint32_t counter;
|
|
|
e79d4b |
+ int ret;
|
|
|
e79d4b |
|
|
|
e79d4b |
if (unlikely(ctx->finished))
|
|
|
e79d4b |
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
|
|
|
e79d4b |
@@ -236,6 +240,11 @@ aes_gcm_encrypt(void *_ctx, const void *src, size_t src_size,
|
|
|
e79d4b |
if (unlikely(length < src_size))
|
|
|
e79d4b |
return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
|
|
|
e79d4b |
|
|
|
e79d4b |
+ ret = record_aes_gcm_encrypt_size(&ctx->rekey_counter, src_size);
|
|
|
e79d4b |
+ if (ret < 0) {
|
|
|
e79d4b |
+ return gnutls_assert_val(ret);
|
|
|
e79d4b |
+ }
|
|
|
e79d4b |
+
|
|
|
e79d4b |
if (blocks > 0) {
|
|
|
e79d4b |
ctr32_encrypt_blocks(src, dst,
|
|
|
e79d4b |
blocks,
|
|
|
e79d4b |
diff --git a/lib/accelerated/x86/aes-gcm-padlock.c b/lib/accelerated/x86/aes-gcm-padlock.c
|
|
|
e79d4b |
index a9c7441d65..739883ab1b 100644
|
|
|
e79d4b |
--- a/lib/accelerated/x86/aes-gcm-padlock.c
|
|
|
e79d4b |
+++ b/lib/accelerated/x86/aes-gcm-padlock.c
|
|
|
e79d4b |
@@ -43,7 +43,10 @@
|
|
|
e79d4b |
* Actually padlock doesn't include GCM mode. We just use
|
|
|
e79d4b |
* the ECB part of padlock and nettle for everything else.
|
|
|
e79d4b |
*/
|
|
|
e79d4b |
-struct gcm_padlock_aes_ctx GCM_CTX(struct padlock_ctx);
|
|
|
e79d4b |
+struct gcm_padlock_aes_ctx {
|
|
|
e79d4b |
+ struct GCM_CTX(struct padlock_ctx) inner;
|
|
|
e79d4b |
+ size_t rekey_counter;
|
|
|
e79d4b |
+};
|
|
|
e79d4b |
|
|
|
e79d4b |
static void padlock_aes_encrypt(const void *_ctx,
|
|
|
e79d4b |
size_t length, uint8_t * dst,
|
|
|
e79d4b |
@@ -78,7 +81,7 @@ static void padlock_aes256_set_encrypt_key(struct padlock_ctx *_ctx,
|
|
|
e79d4b |
|
|
|
e79d4b |
static void aes_gcm_deinit(void *_ctx)
|
|
|
e79d4b |
{
|
|
|
e79d4b |
- struct padlock_ctx *ctx = _ctx;
|
|
|
e79d4b |
+ struct gcm_padlock_aes_ctx *ctx = _ctx;
|
|
|
e79d4b |
|
|
|
e79d4b |
zeroize_temp_key(ctx, sizeof(*ctx));
|
|
|
e79d4b |
gnutls_free(ctx);
|
|
|
e79d4b |
@@ -108,14 +111,15 @@ aes_gcm_cipher_setkey(void *_ctx, const void *key, size_t keysize)
|
|
|
e79d4b |
struct gcm_padlock_aes_ctx *ctx = _ctx;
|
|
|
e79d4b |
|
|
|
e79d4b |
if (keysize == 16) {
|
|
|
e79d4b |
- GCM_SET_KEY(ctx, padlock_aes128_set_encrypt_key, padlock_aes_encrypt,
|
|
|
e79d4b |
+ GCM_SET_KEY(&ctx->inner, padlock_aes128_set_encrypt_key, padlock_aes_encrypt,
|
|
|
e79d4b |
key);
|
|
|
e79d4b |
} else if (keysize == 32) {
|
|
|
e79d4b |
- GCM_SET_KEY(ctx, padlock_aes256_set_encrypt_key, padlock_aes_encrypt,
|
|
|
e79d4b |
+ GCM_SET_KEY(&ctx->inner, padlock_aes256_set_encrypt_key, padlock_aes_encrypt,
|
|
|
e79d4b |
key);
|
|
|
e79d4b |
} else
|
|
|
e79d4b |
return GNUTLS_E_INVALID_REQUEST;
|
|
|
e79d4b |
|
|
|
e79d4b |
+ ctx->rekey_counter = 0;
|
|
|
e79d4b |
return 0;
|
|
|
e79d4b |
}
|
|
|
e79d4b |
|
|
|
e79d4b |
@@ -126,8 +130,9 @@ static int aes_gcm_setiv(void *_ctx, const void *iv, size_t iv_size)
|
|
|
e79d4b |
if (iv_size != GCM_BLOCK_SIZE - 4)
|
|
|
e79d4b |
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
|
|
|
e79d4b |
|
|
|
e79d4b |
- GCM_SET_IV(ctx, iv_size, iv);
|
|
|
e79d4b |
+ GCM_SET_IV(&ctx->inner, iv_size, iv);
|
|
|
e79d4b |
|
|
|
e79d4b |
+ ctx->rekey_counter = 0;
|
|
|
e79d4b |
return 0;
|
|
|
e79d4b |
}
|
|
|
e79d4b |
|
|
|
e79d4b |
@@ -136,11 +141,17 @@ aes_gcm_encrypt(void *_ctx, const void *src, size_t src_size,
|
|
|
e79d4b |
void *dst, size_t length)
|
|
|
e79d4b |
{
|
|
|
e79d4b |
struct gcm_padlock_aes_ctx *ctx = _ctx;
|
|
|
e79d4b |
+ int ret;
|
|
|
e79d4b |
|
|
|
e79d4b |
if (unlikely(length < src_size))
|
|
|
e79d4b |
return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
|
|
|
e79d4b |
|
|
|
e79d4b |
- GCM_ENCRYPT(ctx, padlock_aes_encrypt, src_size, dst, src);
|
|
|
e79d4b |
+ ret = record_aes_gcm_encrypt_size(&ctx->rekey_counter, src_size);
|
|
|
e79d4b |
+ if (ret < 0) {
|
|
|
e79d4b |
+ return gnutls_assert_val(ret);
|
|
|
e79d4b |
+ }
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ GCM_ENCRYPT(&ctx->inner, padlock_aes_encrypt, src_size, dst, src);
|
|
|
e79d4b |
|
|
|
e79d4b |
return 0;
|
|
|
e79d4b |
}
|
|
|
e79d4b |
@@ -154,7 +165,7 @@ aes_gcm_decrypt(void *_ctx, const void *src, size_t src_size,
|
|
|
e79d4b |
if (unlikely(dst_size < src_size))
|
|
|
e79d4b |
return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
|
|
|
e79d4b |
|
|
|
e79d4b |
- GCM_DECRYPT(ctx, padlock_aes_encrypt, src_size, dst, src);
|
|
|
e79d4b |
+ GCM_DECRYPT(&ctx->inner, padlock_aes_encrypt, src_size, dst, src);
|
|
|
e79d4b |
return 0;
|
|
|
e79d4b |
}
|
|
|
e79d4b |
|
|
|
e79d4b |
@@ -162,7 +173,7 @@ static int aes_gcm_auth(void *_ctx, const void *src, size_t src_size)
|
|
|
e79d4b |
{
|
|
|
e79d4b |
struct gcm_padlock_aes_ctx *ctx = _ctx;
|
|
|
e79d4b |
|
|
|
e79d4b |
- GCM_UPDATE(ctx, src_size, src);
|
|
|
e79d4b |
+ GCM_UPDATE(&ctx->inner, src_size, src);
|
|
|
e79d4b |
|
|
|
e79d4b |
return 0;
|
|
|
e79d4b |
}
|
|
|
e79d4b |
@@ -171,7 +182,7 @@ static void aes_gcm_tag(void *_ctx, void *tag, size_t tagsize)
|
|
|
e79d4b |
{
|
|
|
e79d4b |
struct gcm_padlock_aes_ctx *ctx = _ctx;
|
|
|
e79d4b |
|
|
|
e79d4b |
- GCM_DIGEST(ctx, padlock_aes_encrypt, tagsize, tag);
|
|
|
e79d4b |
+ GCM_DIGEST(&ctx->inner, padlock_aes_encrypt, tagsize, tag);
|
|
|
e79d4b |
}
|
|
|
e79d4b |
|
|
|
e79d4b |
#include "aes-gcm-aead.h"
|
|
|
e79d4b |
diff --git a/lib/accelerated/x86/aes-gcm-x86-aesni.c b/lib/accelerated/x86/aes-gcm-x86-aesni.c
|
|
|
e79d4b |
index b0edaebfba..3be63ddd97 100644
|
|
|
e79d4b |
--- a/lib/accelerated/x86/aes-gcm-x86-aesni.c
|
|
|
e79d4b |
+++ b/lib/accelerated/x86/aes-gcm-x86-aesni.c
|
|
|
e79d4b |
@@ -36,12 +36,14 @@
|
|
|
e79d4b |
#include <x86-common.h>
|
|
|
e79d4b |
#include <byteswap.h>
|
|
|
e79d4b |
#include <nettle/gcm.h>
|
|
|
e79d4b |
-#include <aes-x86.h>
|
|
|
e79d4b |
|
|
|
e79d4b |
/* GCM mode
|
|
|
e79d4b |
* It is used when the CPU doesn't include the PCLMUL instructions.
|
|
|
e79d4b |
*/
|
|
|
e79d4b |
-struct gcm_x86_aes_ctx GCM_CTX(AES_KEY);
|
|
|
e79d4b |
+struct gcm_x86_aes_ctx {
|
|
|
e79d4b |
+ struct GCM_CTX(AES_KEY) inner;
|
|
|
e79d4b |
+ size_t rekey_counter;
|
|
|
e79d4b |
+};
|
|
|
e79d4b |
|
|
|
e79d4b |
static void x86_aes_encrypt(const void *_ctx,
|
|
|
e79d4b |
size_t length, uint8_t * dst,
|
|
|
e79d4b |
@@ -101,17 +103,18 @@ aes_gcm_cipher_setkey(void *_ctx, const void *key, size_t length)
|
|
|
e79d4b |
struct gcm_x86_aes_ctx *ctx = _ctx;
|
|
|
e79d4b |
|
|
|
e79d4b |
if (length == 16) {
|
|
|
e79d4b |
- GCM_SET_KEY(ctx, x86_aes128_set_encrypt_key, x86_aes_encrypt,
|
|
|
e79d4b |
+ GCM_SET_KEY(&ctx->inner, x86_aes128_set_encrypt_key, x86_aes_encrypt,
|
|
|
e79d4b |
key);
|
|
|
e79d4b |
} else if (length == 24) {
|
|
|
e79d4b |
- GCM_SET_KEY(ctx, x86_aes192_set_encrypt_key, x86_aes_encrypt,
|
|
|
e79d4b |
+ GCM_SET_KEY(&ctx->inner, x86_aes192_set_encrypt_key, x86_aes_encrypt,
|
|
|
e79d4b |
key);
|
|
|
e79d4b |
} else if (length == 32) {
|
|
|
e79d4b |
- GCM_SET_KEY(ctx, x86_aes256_set_encrypt_key, x86_aes_encrypt,
|
|
|
e79d4b |
+ GCM_SET_KEY(&ctx->inner, x86_aes256_set_encrypt_key, x86_aes_encrypt,
|
|
|
e79d4b |
key);
|
|
|
e79d4b |
} else
|
|
|
e79d4b |
return GNUTLS_E_INVALID_REQUEST;
|
|
|
e79d4b |
|
|
|
e79d4b |
+ ctx->rekey_counter = 0;
|
|
|
e79d4b |
return 0;
|
|
|
e79d4b |
}
|
|
|
e79d4b |
|
|
|
e79d4b |
@@ -122,8 +125,9 @@ static int aes_gcm_setiv(void *_ctx, const void *iv, size_t iv_size)
|
|
|
e79d4b |
if (iv_size != GCM_BLOCK_SIZE - 4)
|
|
|
e79d4b |
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
|
|
|
e79d4b |
|
|
|
e79d4b |
- GCM_SET_IV(ctx, iv_size, iv);
|
|
|
e79d4b |
+ GCM_SET_IV(&ctx->inner, iv_size, iv);
|
|
|
e79d4b |
|
|
|
e79d4b |
+ ctx->rekey_counter = 0;
|
|
|
e79d4b |
return 0;
|
|
|
e79d4b |
}
|
|
|
e79d4b |
|
|
|
e79d4b |
@@ -132,11 +136,17 @@ aes_gcm_encrypt(void *_ctx, const void *src, size_t src_size,
|
|
|
e79d4b |
void *dst, size_t length)
|
|
|
e79d4b |
{
|
|
|
e79d4b |
struct gcm_x86_aes_ctx *ctx = _ctx;
|
|
|
e79d4b |
+ int ret;
|
|
|
e79d4b |
|
|
|
e79d4b |
if (unlikely(length < src_size))
|
|
|
e79d4b |
return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
|
|
|
e79d4b |
|
|
|
e79d4b |
- GCM_ENCRYPT(ctx, x86_aes_encrypt, src_size, dst, src);
|
|
|
e79d4b |
+ ret = record_aes_gcm_encrypt_size(&ctx->rekey_counter, src_size);
|
|
|
e79d4b |
+ if (ret < 0) {
|
|
|
e79d4b |
+ return gnutls_assert_val(ret);
|
|
|
e79d4b |
+ }
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ GCM_ENCRYPT(&ctx->inner, x86_aes_encrypt, src_size, dst, src);
|
|
|
e79d4b |
|
|
|
e79d4b |
return 0;
|
|
|
e79d4b |
}
|
|
|
e79d4b |
@@ -150,7 +160,7 @@ aes_gcm_decrypt(void *_ctx, const void *src, size_t src_size,
|
|
|
e79d4b |
if (unlikely(dst_size < src_size))
|
|
|
e79d4b |
return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
|
|
|
e79d4b |
|
|
|
e79d4b |
- GCM_DECRYPT(ctx, x86_aes_encrypt, src_size, dst, src);
|
|
|
e79d4b |
+ GCM_DECRYPT(&ctx->inner, x86_aes_encrypt, src_size, dst, src);
|
|
|
e79d4b |
return 0;
|
|
|
e79d4b |
}
|
|
|
e79d4b |
|
|
|
e79d4b |
@@ -158,7 +168,7 @@ static int aes_gcm_auth(void *_ctx, const void *src, size_t src_size)
|
|
|
e79d4b |
{
|
|
|
e79d4b |
struct gcm_x86_aes_ctx *ctx = _ctx;
|
|
|
e79d4b |
|
|
|
e79d4b |
- GCM_UPDATE(ctx, src_size, src);
|
|
|
e79d4b |
+ GCM_UPDATE(&ctx->inner, src_size, src);
|
|
|
e79d4b |
|
|
|
e79d4b |
return 0;
|
|
|
e79d4b |
}
|
|
|
e79d4b |
@@ -167,7 +177,7 @@ static void aes_gcm_tag(void *_ctx, void *tag, size_t tagsize)
|
|
|
e79d4b |
{
|
|
|
e79d4b |
struct gcm_x86_aes_ctx *ctx = _ctx;
|
|
|
e79d4b |
|
|
|
e79d4b |
- GCM_DIGEST(ctx, x86_aes_encrypt, tagsize, tag);
|
|
|
e79d4b |
+ GCM_DIGEST(&ctx->inner, x86_aes_encrypt, tagsize, tag);
|
|
|
e79d4b |
}
|
|
|
e79d4b |
|
|
|
e79d4b |
static void aes_gcm_deinit(void *_ctx)
|
|
|
e79d4b |
diff --git a/lib/accelerated/x86/aes-gcm-x86-pclmul-avx.c b/lib/accelerated/x86/aes-gcm-x86-pclmul-avx.c
|
|
|
e79d4b |
index 21aef94440..fbefe432f4 100644
|
|
|
e79d4b |
--- a/lib/accelerated/x86/aes-gcm-x86-pclmul-avx.c
|
|
|
e79d4b |
+++ b/lib/accelerated/x86/aes-gcm-x86-pclmul-avx.c
|
|
|
e79d4b |
@@ -61,6 +61,7 @@ struct aes_gcm_ctx {
|
|
|
e79d4b |
struct gcm128_context gcm;
|
|
|
e79d4b |
unsigned finished;
|
|
|
e79d4b |
unsigned auth_finished;
|
|
|
e79d4b |
+ size_t rekey_counter;
|
|
|
e79d4b |
};
|
|
|
e79d4b |
|
|
|
e79d4b |
void gcm_init_avx(u128 Htable[16], const uint64_t Xi[2]);
|
|
|
e79d4b |
@@ -116,6 +117,7 @@ aes_gcm_cipher_setkey(void *_ctx, const void *userkey, size_t keysize)
|
|
|
e79d4b |
|
|
|
e79d4b |
gcm_init_avx(ctx->gcm.Htable, ctx->gcm.H.u);
|
|
|
e79d4b |
|
|
|
e79d4b |
+ ctx->rekey_counter = 0;
|
|
|
e79d4b |
return 0;
|
|
|
e79d4b |
}
|
|
|
e79d4b |
|
|
|
e79d4b |
@@ -140,6 +142,7 @@ static int aes_gcm_setiv(void *_ctx, const void *iv, size_t iv_size)
|
|
|
e79d4b |
ctx->gcm.Yi.c[GCM_BLOCK_SIZE - 1] = 2;
|
|
|
e79d4b |
ctx->finished = 0;
|
|
|
e79d4b |
ctx->auth_finished = 0;
|
|
|
e79d4b |
+ ctx->rekey_counter = 0;
|
|
|
e79d4b |
return 0;
|
|
|
e79d4b |
}
|
|
|
e79d4b |
|
|
|
e79d4b |
@@ -184,6 +187,7 @@ aes_gcm_encrypt(void *_ctx, const void *src, size_t src_size,
|
|
|
e79d4b |
int exp_blocks = blocks * GCM_BLOCK_SIZE;
|
|
|
e79d4b |
int rest = src_size - (exp_blocks);
|
|
|
e79d4b |
uint32_t counter;
|
|
|
e79d4b |
+ int ret;
|
|
|
e79d4b |
|
|
|
e79d4b |
if (unlikely(ctx->finished))
|
|
|
e79d4b |
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
|
|
|
e79d4b |
@@ -191,6 +195,11 @@ aes_gcm_encrypt(void *_ctx, const void *src, size_t src_size,
|
|
|
e79d4b |
if (unlikely(length < src_size))
|
|
|
e79d4b |
return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
|
|
|
e79d4b |
|
|
|
e79d4b |
+ ret = record_aes_gcm_encrypt_size(&ctx->rekey_counter, src_size);
|
|
|
e79d4b |
+ if (ret < 0) {
|
|
|
e79d4b |
+ return gnutls_assert_val(ret);
|
|
|
e79d4b |
+ }
|
|
|
e79d4b |
+
|
|
|
e79d4b |
if (blocks > 0) {
|
|
|
e79d4b |
aesni_ctr32_encrypt_blocks(src, dst,
|
|
|
e79d4b |
blocks,
|
|
|
e79d4b |
diff --git a/lib/accelerated/x86/aes-gcm-x86-pclmul.c b/lib/accelerated/x86/aes-gcm-x86-pclmul.c
|
|
|
e79d4b |
index e6b4990cbf..5385acbb6b 100644
|
|
|
e79d4b |
--- a/lib/accelerated/x86/aes-gcm-x86-pclmul.c
|
|
|
e79d4b |
+++ b/lib/accelerated/x86/aes-gcm-x86-pclmul.c
|
|
|
e79d4b |
@@ -60,6 +60,7 @@ struct aes_gcm_ctx {
|
|
|
e79d4b |
struct gcm128_context gcm;
|
|
|
e79d4b |
unsigned finished;
|
|
|
e79d4b |
unsigned auth_finished;
|
|
|
e79d4b |
+ size_t rekey_counter;
|
|
|
e79d4b |
};
|
|
|
e79d4b |
|
|
|
e79d4b |
void gcm_init_clmul(u128 Htable[16], const uint64_t Xi[2]);
|
|
|
e79d4b |
@@ -116,6 +117,7 @@ aes_gcm_cipher_setkey(void *_ctx, const void *userkey, size_t keysize)
|
|
|
e79d4b |
|
|
|
e79d4b |
gcm_init_clmul(ctx->gcm.Htable, ctx->gcm.H.u);
|
|
|
e79d4b |
|
|
|
e79d4b |
+ ctx->rekey_counter = 0;
|
|
|
e79d4b |
return 0;
|
|
|
e79d4b |
}
|
|
|
e79d4b |
|
|
|
e79d4b |
@@ -140,6 +142,7 @@ static int aes_gcm_setiv(void *_ctx, const void *iv, size_t iv_size)
|
|
|
e79d4b |
ctx->gcm.Yi.c[GCM_BLOCK_SIZE - 1] = 2;
|
|
|
e79d4b |
ctx->finished = 0;
|
|
|
e79d4b |
ctx->auth_finished = 0;
|
|
|
e79d4b |
+ ctx->rekey_counter = 0;
|
|
|
e79d4b |
return 0;
|
|
|
e79d4b |
}
|
|
|
e79d4b |
|
|
|
e79d4b |
@@ -184,6 +187,7 @@ aes_gcm_encrypt(void *_ctx, const void *src, size_t src_size,
|
|
|
e79d4b |
int exp_blocks = blocks * GCM_BLOCK_SIZE;
|
|
|
e79d4b |
int rest = src_size - (exp_blocks);
|
|
|
e79d4b |
uint32_t counter;
|
|
|
e79d4b |
+ int ret;
|
|
|
e79d4b |
|
|
|
e79d4b |
if (unlikely(ctx->finished))
|
|
|
e79d4b |
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
|
|
|
e79d4b |
@@ -191,6 +195,11 @@ aes_gcm_encrypt(void *_ctx, const void *src, size_t src_size,
|
|
|
e79d4b |
if (unlikely(length < src_size))
|
|
|
e79d4b |
return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
|
|
|
e79d4b |
|
|
|
e79d4b |
+ ret = record_aes_gcm_encrypt_size(&ctx->rekey_counter, src_size);
|
|
|
e79d4b |
+ if (ret < 0) {
|
|
|
e79d4b |
+ return gnutls_assert_val(ret);
|
|
|
e79d4b |
+ }
|
|
|
e79d4b |
+
|
|
|
e79d4b |
if (blocks > 0) {
|
|
|
e79d4b |
aesni_ctr32_encrypt_blocks(src, dst,
|
|
|
e79d4b |
blocks,
|
|
|
e79d4b |
diff --git a/lib/accelerated/x86/aes-gcm-x86-ssse3.c b/lib/accelerated/x86/aes-gcm-x86-ssse3.c
|
|
|
e79d4b |
index 7a2ac50869..f074cb1096 100644
|
|
|
e79d4b |
--- a/lib/accelerated/x86/aes-gcm-x86-ssse3.c
|
|
|
e79d4b |
+++ b/lib/accelerated/x86/aes-gcm-x86-ssse3.c
|
|
|
e79d4b |
@@ -36,13 +36,15 @@
|
|
|
e79d4b |
#include <x86-common.h>
|
|
|
e79d4b |
#include <byteswap.h>
|
|
|
e79d4b |
#include <nettle/gcm.h>
|
|
|
e79d4b |
-#include <aes-x86.h>
|
|
|
e79d4b |
#include <assert.h>
|
|
|
e79d4b |
|
|
|
e79d4b |
/* GCM mode
|
|
|
e79d4b |
* It is used when the CPU doesn't include the PCLMUL instructions.
|
|
|
e79d4b |
*/
|
|
|
e79d4b |
-struct gcm_x86_aes_ctx GCM_CTX(AES_KEY);
|
|
|
e79d4b |
+struct gcm_x86_aes_ctx {
|
|
|
e79d4b |
+ struct GCM_CTX(AES_KEY) inner;
|
|
|
e79d4b |
+ size_t rekey_counter;
|
|
|
e79d4b |
+};
|
|
|
e79d4b |
|
|
|
e79d4b |
static void x86_aes_encrypt(const void *_ctx,
|
|
|
e79d4b |
size_t length, uint8_t * dst,
|
|
|
e79d4b |
@@ -110,17 +112,18 @@ aes_gcm_cipher_setkey(void *_ctx, const void *key, size_t keysize)
|
|
|
e79d4b |
struct gcm_x86_aes_ctx *ctx = _ctx;
|
|
|
e79d4b |
|
|
|
e79d4b |
if (keysize == 16) {
|
|
|
e79d4b |
- GCM_SET_KEY(ctx, x86_aes_128_set_encrypt_key, x86_aes_encrypt,
|
|
|
e79d4b |
+ GCM_SET_KEY(&ctx->inner, x86_aes_128_set_encrypt_key, x86_aes_encrypt,
|
|
|
e79d4b |
key);
|
|
|
e79d4b |
} else if (keysize == 24) {
|
|
|
e79d4b |
- GCM_SET_KEY(ctx, x86_aes_192_set_encrypt_key, x86_aes_encrypt,
|
|
|
e79d4b |
+ GCM_SET_KEY(&ctx->inner, x86_aes_192_set_encrypt_key, x86_aes_encrypt,
|
|
|
e79d4b |
key);
|
|
|
e79d4b |
} else if (keysize == 32) {
|
|
|
e79d4b |
- GCM_SET_KEY(ctx, x86_aes_256_set_encrypt_key, x86_aes_encrypt,
|
|
|
e79d4b |
+ GCM_SET_KEY(&ctx->inner, x86_aes_256_set_encrypt_key, x86_aes_encrypt,
|
|
|
e79d4b |
key);
|
|
|
e79d4b |
} else
|
|
|
e79d4b |
return GNUTLS_E_INVALID_REQUEST;
|
|
|
e79d4b |
|
|
|
e79d4b |
+ ctx->rekey_counter = 0;
|
|
|
e79d4b |
return 0;
|
|
|
e79d4b |
}
|
|
|
e79d4b |
|
|
|
e79d4b |
@@ -131,8 +134,9 @@ static int aes_gcm_setiv(void *_ctx, const void *iv, size_t iv_size)
|
|
|
e79d4b |
if (iv_size != GCM_BLOCK_SIZE - 4)
|
|
|
e79d4b |
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
|
|
|
e79d4b |
|
|
|
e79d4b |
- GCM_SET_IV(ctx, iv_size, iv);
|
|
|
e79d4b |
+ GCM_SET_IV(&ctx->inner, iv_size, iv);
|
|
|
e79d4b |
|
|
|
e79d4b |
+ ctx->rekey_counter = 0;
|
|
|
e79d4b |
return 0;
|
|
|
e79d4b |
}
|
|
|
e79d4b |
|
|
|
e79d4b |
@@ -141,11 +145,17 @@ aes_gcm_encrypt(void *_ctx, const void *src, size_t src_size,
|
|
|
e79d4b |
void *dst, size_t length)
|
|
|
e79d4b |
{
|
|
|
e79d4b |
struct gcm_x86_aes_ctx *ctx = _ctx;
|
|
|
e79d4b |
+ int ret;
|
|
|
e79d4b |
|
|
|
e79d4b |
if (unlikely(length < src_size))
|
|
|
e79d4b |
return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
|
|
|
e79d4b |
|
|
|
e79d4b |
- GCM_ENCRYPT(ctx, x86_aes_encrypt, src_size, dst, src);
|
|
|
e79d4b |
+ ret = record_aes_gcm_encrypt_size(&ctx->rekey_counter, src_size);
|
|
|
e79d4b |
+ if (ret < 0) {
|
|
|
e79d4b |
+ return gnutls_assert_val(ret);
|
|
|
e79d4b |
+ }
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ GCM_ENCRYPT(&ctx->inner, x86_aes_encrypt, src_size, dst, src);
|
|
|
e79d4b |
|
|
|
e79d4b |
return 0;
|
|
|
e79d4b |
}
|
|
|
e79d4b |
@@ -159,7 +169,7 @@ aes_gcm_decrypt(void *_ctx, const void *src, size_t src_size,
|
|
|
e79d4b |
if (unlikely(dst_size < src_size))
|
|
|
e79d4b |
return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
|
|
|
e79d4b |
|
|
|
e79d4b |
- GCM_DECRYPT(ctx, x86_aes_encrypt, src_size, dst, src);
|
|
|
e79d4b |
+ GCM_DECRYPT(&ctx->inner, x86_aes_encrypt, src_size, dst, src);
|
|
|
e79d4b |
return 0;
|
|
|
e79d4b |
}
|
|
|
e79d4b |
|
|
|
e79d4b |
@@ -167,7 +177,7 @@ static int aes_gcm_auth(void *_ctx, const void *src, size_t src_size)
|
|
|
e79d4b |
{
|
|
|
e79d4b |
struct gcm_x86_aes_ctx *ctx = _ctx;
|
|
|
e79d4b |
|
|
|
e79d4b |
- GCM_UPDATE(ctx, src_size, src);
|
|
|
e79d4b |
+ GCM_UPDATE(&ctx->inner, src_size, src);
|
|
|
e79d4b |
|
|
|
e79d4b |
return 0;
|
|
|
e79d4b |
}
|
|
|
e79d4b |
@@ -176,7 +186,7 @@ static void aes_gcm_tag(void *_ctx, void *tag, size_t tagsize)
|
|
|
e79d4b |
{
|
|
|
e79d4b |
struct gcm_x86_aes_ctx *ctx = _ctx;
|
|
|
e79d4b |
|
|
|
e79d4b |
- GCM_DIGEST(ctx, x86_aes_encrypt, tagsize, tag);
|
|
|
e79d4b |
+ GCM_DIGEST(&ctx->inner, x86_aes_encrypt, tagsize, tag);
|
|
|
e79d4b |
}
|
|
|
e79d4b |
|
|
|
e79d4b |
static void aes_gcm_deinit(void *_ctx)
|
|
|
e79d4b |
diff --git a/lib/accelerated/x86/aes-x86.h b/lib/accelerated/x86/aes-x86.h
|
|
|
e79d4b |
index 023b5f7be6..349d3d5d9c 100644
|
|
|
e79d4b |
--- a/lib/accelerated/x86/aes-x86.h
|
|
|
e79d4b |
+++ b/lib/accelerated/x86/aes-x86.h
|
|
|
e79d4b |
@@ -22,6 +22,21 @@ typedef struct {
|
|
|
e79d4b |
if (s != 16 && s != 24 && s != 32) \
|
|
|
e79d4b |
return GNUTLS_E_INVALID_REQUEST
|
|
|
e79d4b |
|
|
|
e79d4b |
+#include <intprops.h>
|
|
|
e79d4b |
+#define AES_GCM_ENCRYPT_MAX_BYTES ((1ULL << 36) - 32)
|
|
|
e79d4b |
+static inline int
|
|
|
e79d4b |
+record_aes_gcm_encrypt_size(size_t *counter, size_t size) {
|
|
|
e79d4b |
+ size_t sum;
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ if (!INT_ADD_OK(*counter, size, &sum) ||
|
|
|
e79d4b |
+ sum > AES_GCM_ENCRYPT_MAX_BYTES) {
|
|
|
e79d4b |
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
|
|
|
e79d4b |
+ }
|
|
|
e79d4b |
+ *counter = sum;
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ return 0;
|
|
|
e79d4b |
+}
|
|
|
e79d4b |
+
|
|
|
e79d4b |
void aesni_ecb_encrypt(const unsigned char *in, unsigned char *out,
|
|
|
e79d4b |
size_t len, const AES_KEY * key, int enc);
|
|
|
e79d4b |
|
|
|
e79d4b |
diff --git a/lib/nettle/cipher.c b/lib/nettle/cipher.c
|
|
|
e79d4b |
index ab4c46d2d0..b41862d1ea 100644
|
|
|
e79d4b |
--- a/lib/nettle/cipher.c
|
|
|
e79d4b |
+++ b/lib/nettle/cipher.c
|
|
|
e79d4b |
@@ -63,6 +63,7 @@
|
|
|
e79d4b |
#include <nettle/xts.h>
|
|
|
e79d4b |
#include <nettle/siv-cmac.h>
|
|
|
e79d4b |
#include <fips.h>
|
|
|
e79d4b |
+#include <intprops.h>
|
|
|
e79d4b |
|
|
|
e79d4b |
struct nettle_cipher_ctx;
|
|
|
e79d4b |
|
|
|
e79d4b |
@@ -120,8 +121,23 @@ struct nettle_cipher_ctx {
|
|
|
e79d4b |
unsigned iv_size;
|
|
|
e79d4b |
|
|
|
e79d4b |
bool enc;
|
|
|
e79d4b |
+ size_t rekey_counter;
|
|
|
e79d4b |
};
|
|
|
e79d4b |
|
|
|
e79d4b |
+#define AES_GCM_ENCRYPT_MAX_BYTES ((1ULL << 36) - 32)
|
|
|
e79d4b |
+static inline int
|
|
|
e79d4b |
+record_aes_gcm_encrypt_size(size_t *counter, size_t size) {
|
|
|
e79d4b |
+ size_t sum;
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ if (!INT_ADD_OK(*counter, size, &sum) ||
|
|
|
e79d4b |
+ sum > AES_GCM_ENCRYPT_MAX_BYTES) {
|
|
|
e79d4b |
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
|
|
|
e79d4b |
+ }
|
|
|
e79d4b |
+ *counter = sum;
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ return 0;
|
|
|
e79d4b |
+}
|
|
|
e79d4b |
+
|
|
|
e79d4b |
static void
|
|
|
e79d4b |
_stream_encrypt(struct nettle_cipher_ctx *ctx, size_t length, uint8_t * dst,
|
|
|
e79d4b |
const uint8_t * src)
|
|
|
e79d4b |
@@ -1133,6 +1149,16 @@ wrap_nettle_cipher_setkey(void *_ctx, const void *key, size_t keysize)
|
|
|
e79d4b |
else
|
|
|
e79d4b |
ctx->cipher->set_decrypt_key(ctx->ctx_ptr, key);
|
|
|
e79d4b |
|
|
|
e79d4b |
+ switch (ctx->cipher->algo) {
|
|
|
e79d4b |
+ case GNUTLS_CIPHER_AES_128_GCM:
|
|
|
e79d4b |
+ case GNUTLS_CIPHER_AES_192_GCM:
|
|
|
e79d4b |
+ case GNUTLS_CIPHER_AES_256_GCM:
|
|
|
e79d4b |
+ ctx->rekey_counter = 0;
|
|
|
e79d4b |
+ break;
|
|
|
e79d4b |
+ default:
|
|
|
e79d4b |
+ break;
|
|
|
e79d4b |
+ }
|
|
|
e79d4b |
+
|
|
|
e79d4b |
return 0;
|
|
|
e79d4b |
}
|
|
|
e79d4b |
|
|
|
e79d4b |
@@ -1147,6 +1173,7 @@ wrap_nettle_cipher_setiv(void *_ctx, const void *iv, size_t iv_size)
|
|
|
e79d4b |
case GNUTLS_CIPHER_AES_192_GCM:
|
|
|
e79d4b |
case GNUTLS_CIPHER_AES_256_GCM:
|
|
|
e79d4b |
FIPS_RULE(iv_size < GCM_IV_SIZE, GNUTLS_E_INVALID_REQUEST, "access to short GCM nonce size\n");
|
|
|
e79d4b |
+ ctx->rekey_counter = 0;
|
|
|
e79d4b |
break;
|
|
|
e79d4b |
case GNUTLS_CIPHER_SALSA20_256:
|
|
|
e79d4b |
case GNUTLS_CIPHER_ESTREAM_SALSA20_256:
|
|
|
e79d4b |
@@ -1207,10 +1234,24 @@ wrap_nettle_cipher_encrypt(void *_ctx, const void *plain, size_t plain_size,
|
|
|
e79d4b |
void *encr, size_t encr_size)
|
|
|
e79d4b |
{
|
|
|
e79d4b |
struct nettle_cipher_ctx *ctx = _ctx;
|
|
|
e79d4b |
+ int ret;
|
|
|
e79d4b |
|
|
|
e79d4b |
if (unlikely(ctx->cipher->encrypt == NULL))
|
|
|
e79d4b |
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
|
|
|
e79d4b |
|
|
|
e79d4b |
+ switch (ctx->cipher->algo) {
|
|
|
e79d4b |
+ case GNUTLS_CIPHER_AES_128_GCM:
|
|
|
e79d4b |
+ case GNUTLS_CIPHER_AES_192_GCM:
|
|
|
e79d4b |
+ case GNUTLS_CIPHER_AES_256_GCM:
|
|
|
e79d4b |
+ ret = record_aes_gcm_encrypt_size(&ctx->rekey_counter, plain_size);
|
|
|
e79d4b |
+ if (ret < 0) {
|
|
|
e79d4b |
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
|
|
|
e79d4b |
+ }
|
|
|
e79d4b |
+ break;
|
|
|
e79d4b |
+ default:
|
|
|
e79d4b |
+ break;
|
|
|
e79d4b |
+ }
|
|
|
e79d4b |
+
|
|
|
e79d4b |
ctx->cipher->encrypt(ctx, plain_size, encr, plain);
|
|
|
e79d4b |
|
|
|
e79d4b |
return 0;
|
|
|
e79d4b |
diff --git a/tests/slow/cipher-api-test.c b/tests/slow/cipher-api-test.c
|
|
|
e79d4b |
index fc880bcc9f..1d267ce312 100644
|
|
|
e79d4b |
--- a/tests/slow/cipher-api-test.c
|
|
|
e79d4b |
+++ b/tests/slow/cipher-api-test.c
|
|
|
e79d4b |
@@ -21,6 +21,7 @@
|
|
|
e79d4b |
*/
|
|
|
e79d4b |
|
|
|
e79d4b |
#include <config.h>
|
|
|
e79d4b |
+#include <limits.h>
|
|
|
e79d4b |
#include <stdint.h>
|
|
|
e79d4b |
#include <stdio.h>
|
|
|
e79d4b |
#include <string.h>
|
|
|
e79d4b |
@@ -48,6 +49,11 @@ int main(int argc, char **argv)
|
|
|
e79d4b |
#include <assert.h>
|
|
|
e79d4b |
#include <utils.h>
|
|
|
e79d4b |
|
|
|
e79d4b |
+#define AES_GCM_ENCRYPT_PLAINTEXT_MAX ((1ULL << 36) - 32)
|
|
|
e79d4b |
+#if SIZE_MAX >= AES_GCM_ENCRYPT_PLAINTEXT_MAX
|
|
|
e79d4b |
+#define TEST_AES_GCM_ENCRYPT_PLAINTEXT_SIZE 1
|
|
|
e79d4b |
+#endif
|
|
|
e79d4b |
+
|
|
|
e79d4b |
static void tls_log_func(int level, const char *str)
|
|
|
e79d4b |
{
|
|
|
e79d4b |
fprintf(stderr, "<%d>| %s", level, str);
|
|
|
e79d4b |
@@ -401,6 +407,74 @@ static void test_aead_invalid_short_decrypt(int algo)
|
|
|
e79d4b |
return;
|
|
|
e79d4b |
}
|
|
|
e79d4b |
|
|
|
e79d4b |
+#ifdef TEST_AES_GCM_ENCRYPT_PLAINTEXT_SIZE
|
|
|
e79d4b |
+/* Test whether an invalid call to gnutls_cipher_encrypt() with too
|
|
|
e79d4b |
+ * long message is caught */
|
|
|
e79d4b |
+static void test_aead_invalid_too_long_encrypt(int algo)
|
|
|
e79d4b |
+{
|
|
|
e79d4b |
+ int ret;
|
|
|
e79d4b |
+ gnutls_cipher_hd_t ch;
|
|
|
e79d4b |
+ uint8_t key16[64];
|
|
|
e79d4b |
+ uint8_t iv16[32];
|
|
|
e79d4b |
+ uint8_t data[128];
|
|
|
e79d4b |
+ gnutls_datum_t key, iv;
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ if (algo != GNUTLS_CIPHER_AES_128_GCM &&
|
|
|
e79d4b |
+ algo != GNUTLS_CIPHER_AES_192_GCM &&
|
|
|
e79d4b |
+ algo != GNUTLS_CIPHER_AES_256_GCM) {
|
|
|
e79d4b |
+ return;
|
|
|
e79d4b |
+ }
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ key.data = key16;
|
|
|
e79d4b |
+ key.size = gnutls_cipher_get_key_size(algo);
|
|
|
e79d4b |
+ assert(key.size <= sizeof(key16));
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ iv.data = iv16;
|
|
|
e79d4b |
+ iv.size = gnutls_cipher_get_iv_size(algo);
|
|
|
e79d4b |
+ assert(iv.size <= sizeof(iv16));
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ memset(iv.data, 0xff, iv.size);
|
|
|
e79d4b |
+ memset(key.data, 0xfe, key.size);
|
|
|
e79d4b |
+ memset(data, 0xfa, sizeof(data));
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ gnutls_global_set_log_function(tls_log_func);
|
|
|
e79d4b |
+ if (debug)
|
|
|
e79d4b |
+ gnutls_global_set_log_level(4711);
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ ret = global_init();
|
|
|
e79d4b |
+ if (ret < 0) {
|
|
|
e79d4b |
+ fail("Cannot initialize library\n"); /*errcode 1 */
|
|
|
e79d4b |
+ }
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ ret = gnutls_cipher_init(&ch, algo, &key, &iv;;
|
|
|
e79d4b |
+ if (ret < 0)
|
|
|
e79d4b |
+ fail("gnutls_cipher_init failed\n"); /*errcode 1 */
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ /* Test exceeding AES-GCM plaintext limit */
|
|
|
e79d4b |
+ ret = gnutls_cipher_encrypt(ch, data, sizeof(data));
|
|
|
e79d4b |
+ if (ret < 0)
|
|
|
e79d4b |
+ fail("could not encrypt data\n");
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ /* A few blocks larger than AES_GCM_ENCRYPT_PLAINTEXT_MAX combined with
|
|
|
e79d4b |
+ * the previous call. Use NULL for PLAINTEXT so the access to the first
|
|
|
e79d4b |
+ * block always results in page fault (in case the limit is not
|
|
|
e79d4b |
+ * enforced).
|
|
|
e79d4b |
+ */
|
|
|
e79d4b |
+ ret = gnutls_cipher_encrypt(ch, NULL, AES_GCM_ENCRYPT_PLAINTEXT_MAX);
|
|
|
e79d4b |
+ if (ret >= 0)
|
|
|
e79d4b |
+ fail("succeeded in encrypting too long data\n");
|
|
|
e79d4b |
+ if (ret != GNUTLS_E_INVALID_REQUEST)
|
|
|
e79d4b |
+ fail("wrong kind of error on encrypting too long data,"
|
|
|
e79d4b |
+ "%s instead of GNUTLS_E_INVALID_REQUEST\n",
|
|
|
e79d4b |
+ gnutls_strerror_name(ret));
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ gnutls_cipher_deinit(ch);
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ gnutls_global_deinit();
|
|
|
e79d4b |
+ return;
|
|
|
e79d4b |
+}
|
|
|
e79d4b |
+#endif
|
|
|
e79d4b |
+
|
|
|
e79d4b |
static void check_status(int status)
|
|
|
e79d4b |
{
|
|
|
e79d4b |
if (WEXITSTATUS(status) != 0 ||
|
|
|
e79d4b |
@@ -464,6 +538,11 @@ void start(const char *name, int algo, unsigned aead)
|
|
|
e79d4b |
|
|
|
e79d4b |
success("trying %s: test_aead_invalid_short_decrypt\n", name);
|
|
|
e79d4b |
fork_subtest(test_aead_invalid_short_decrypt, algo);
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+#if TEST_AES_GCM_ENCRYPT_PLAINTEXT_SIZE
|
|
|
e79d4b |
+ success("trying %s: test_aead_invalid_too_long_encrypt\n", name);
|
|
|
e79d4b |
+ fork_subtest(test_aead_invalid_too_long_encrypt, algo);
|
|
|
e79d4b |
+#endif
|
|
|
e79d4b |
}
|
|
|
e79d4b |
}
|
|
|
e79d4b |
|
|
|
e79d4b |
--
|
|
|
e79d4b |
2.37.1
|
|
|
e79d4b |
|