import gnutls-3.6.8-9.el8

This commit is contained in:
CentOS Sources 2020-01-21 18:20:55 -05:00 committed by Stepan Oksanichenko
parent e50ef7c318
commit 4be9fec1c9
11 changed files with 4980 additions and 119 deletions

View File

@ -313,123 +313,6 @@ index 4fadd4161..0233e6b9f 100644
2.20.1
From 2123049ab9b963ef0ba108ed1cb180016bd672ab Mon Sep 17 00:00:00 2001
From: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Date: Wed, 17 Apr 2019 17:22:40 +0200
Subject: [PATCH 3/7] nettle/pk.c: Do not call gnutls_rnd() during self tests
When the library state is LIB_STATE_SELFTEST, use constant data instead
of calling gnutls_rnd(). This prevents the library to block if there is
insufficient entropy during FIPS self tests.
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
---
lib/nettle/pk.c | 41 ++++++++++++++++++++++++++++++++++-------
1 file changed, 34 insertions(+), 7 deletions(-)
diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c
index 08117c2d8..64633cc73 100644
--- a/lib/nettle/pk.c
+++ b/lib/nettle/pk.c
@@ -60,6 +60,33 @@
static inline const struct ecc_curve *get_supported_nist_curve(int curve);
static inline const struct ecc_curve *get_supported_gost_curve(int curve);
+/* Fill the buffer with data for testing purposes.
+ * This should be called only during self tests.
+ */
+static int _pk_fill_buffer(void *buffer, size_t length)
+{
+ if (_gnutls_get_lib_state() != LIB_STATE_SELFTEST) {
+ return gnutls_assert_val(GNUTLS_E_RANDOM_FAILED);
+ }
+
+ memset(buffer, 0xAA, length);
+
+ return 0;
+}
+
+static int _pk_rnd(gnutls_rnd_level_t level, void *data, size_t len)
+{
+ int ret;
+
+ if (_gnutls_get_lib_state() == LIB_STATE_SELFTEST) {
+ ret = _pk_fill_buffer(data, len);
+ } else {
+ ret = gnutls_rnd(level, data, len);
+ }
+
+ return ret;
+}
+
/* When these callbacks are used for a nettle operation, the
* caller must check the macro HAVE_LIB_ERROR() after the operation
* is complete. If the macro is true, the operation is to be considered
@@ -67,21 +94,21 @@ static inline const struct ecc_curve *get_supported_gost_curve(int curve);
*/
static void rnd_key_func(void *_ctx, size_t length, uint8_t * data)
{
- if (gnutls_rnd(GNUTLS_RND_KEY, data, length) < 0) {
+ if (_pk_rnd(GNUTLS_RND_KEY, data, length) < 0) {
_gnutls_switch_lib_state(LIB_STATE_ERROR);
}
}
static void rnd_tmpkey_func(void *_ctx, size_t length, uint8_t * data)
{
- if (gnutls_rnd(GNUTLS_RND_RANDOM, data, length) < 0) {
+ if (_pk_rnd(GNUTLS_RND_RANDOM, data, length) < 0) {
_gnutls_switch_lib_state(LIB_STATE_ERROR);
}
}
static void rnd_nonce_func(void *_ctx, size_t length, uint8_t * data)
{
- if (gnutls_rnd(GNUTLS_RND_NONCE, data, length) < 0) {
+ if (_pk_rnd(GNUTLS_RND_NONCE, data, length) < 0) {
_gnutls_switch_lib_state(LIB_STATE_ERROR);
}
}
@@ -650,7 +677,7 @@ _rsa_pss_sign_digest_tr(gnutls_digest_algorithm_t dig,
if (salt == NULL)
return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
- ret = gnutls_rnd(GNUTLS_RND_NONCE, salt, salt_size);
+ ret = _pk_rnd(GNUTLS_RND_NONCE, salt, salt_size);
if (ret < 0) {
gnutls_assert();
goto cleanup;
@@ -1732,7 +1759,7 @@ gnutls_x509_spki_st spki;
_gnutls_dsa_q_to_hash(params, &hash_len);
gen_data = gnutls_malloc(hash_len);
- gnutls_rnd(GNUTLS_RND_NONCE, gen_data, hash_len);
+ _pk_rnd(GNUTLS_RND_NONCE, gen_data, hash_len);
ddata.data = (void*)gen_data;
ddata.size = hash_len;
@@ -2101,7 +2128,7 @@ wrap_nettle_pk_generate_keys(gnutls_pk_algorithm_t algo,
goto fail;
}
- ret = gnutls_rnd(rnd_level, params->raw_priv.data, size);
+ ret = _pk_rnd(rnd_level, params->raw_priv.data, size);
if (ret < 0) {
ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
goto fail;
@@ -2240,7 +2267,7 @@ wrap_nettle_pk_generate_keys(gnutls_pk_algorithm_t algo,
goto fail;
}
- ret = gnutls_rnd(rnd_level, params->raw_priv.data, size);
+ ret = _pk_rnd(rnd_level, params->raw_priv.data, size);
if (ret < 0) {
ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
goto fail;
--
2.20.1
From db2b308fdbe98420b722eaf678c1a911bc51b0a5 Mon Sep 17 00:00:00 2001
From: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Date: Thu, 18 Apr 2019 17:22:18 +0200
@ -843,4 +726,3 @@ index fc8ee2525..3d665b723 100644
#if ENABLE_GOST
--
2.20.1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,687 @@
From e0fe31f1fc2ba13ada1d6bc35231847b75be4ee9 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <dueno@redhat.com>
Date: Thu, 8 Aug 2019 18:02:08 +0200
Subject: [PATCH 1/2] gnutls_int.h: make DECR_LEN neutral to signedness
DECR_LEN was previously implemented in a way that it first decrements
the given length and then checks whether the result is negative. This
requires the caller to properly coerce the length argument to a signed
integer, before invoking the macro.
Signed-off-by: Daiki Ueno <dueno@redhat.com>
---
lib/gnutls_int.h | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index 179d71b4a..7f7b6a7c9 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -256,14 +256,15 @@ typedef enum record_send_state_t {
#define MEMSUB(x,y) ((ssize_t)((ptrdiff_t)x-(ptrdiff_t)y))
-#define DECR_LEN(len, x) do { len-=x; if (len<0) {gnutls_assert(); return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;} } while (0)
+#define DECR_LEN(len, x) DECR_LENGTH_RET(len, x, GNUTLS_E_UNEXPECTED_PACKET_LENGTH)
#define DECR_LEN_FINAL(len, x) do { \
- len-=x; \
- if (len != 0) \
+ if (len != x) \
return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH); \
+ else \
+ len = 0; \
} while (0)
-#define DECR_LENGTH_RET(len, x, RET) do { len-=x; if (len<0) {gnutls_assert(); return RET;} } while (0)
-#define DECR_LENGTH_COM(len, x, COM) do { len-=x; if (len<0) {gnutls_assert(); COM;} } while (0)
+#define DECR_LENGTH_RET(len, x, RET) DECR_LENGTH_COM(len, x, return RET)
+#define DECR_LENGTH_COM(len, x, COM) do { if (len<x) {gnutls_assert(); COM;} else len-=x; } while (0)
#define GNUTLS_POINTER_TO_INT(_) ((int) GNUTLS_POINTER_TO_INT_CAST (_))
#define GNUTLS_INT_TO_POINTER(_) ((void*) GNUTLS_POINTER_TO_INT_CAST (_))
--
2.21.0
From 5e9b2ec29449c76b1b938a0ebf0dc9b92cae7057 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <dueno@redhat.com>
Date: Thu, 8 Aug 2019 18:04:18 +0200
Subject: [PATCH 2/2] lib/*: remove unnecessary cast to ssize_t
Signed-off-by: Daiki Ueno <dueno@redhat.com>
---
lib/crypto-api.c | 10 +++++-----
lib/ext/alpn.c | 3 +--
lib/ext/client_cert_type.c | 9 ++++-----
lib/ext/cookie.c | 5 ++---
lib/ext/ec_point_formats.c | 7 +++----
lib/ext/key_share.c | 5 ++---
lib/ext/max_record.c | 3 +--
lib/ext/psk_ke_modes.c | 3 +--
lib/ext/record_size_limit.c | 3 +--
lib/ext/safe_renegotiation.c | 3 +--
lib/ext/server_cert_type.c | 9 ++++-----
lib/ext/server_name.c | 3 +--
lib/ext/session_ticket.c | 5 ++---
lib/ext/signature.c | 3 +--
lib/ext/srp.c | 3 +--
lib/ext/srtp.c | 5 ++---
lib/ext/status_request.c | 3 +--
lib/ext/supported_groups.c | 3 +--
lib/ext/supported_versions.c | 5 ++---
lib/extv.c | 8 ++++----
lib/sslv2_compat.c | 3 +--
lib/supplemental.c | 4 ++--
lib/tls13/certificate.c | 21 +++++++++++----------
lib/tls13/psk_ext_parser.c | 4 +---
lib/tls13/psk_ext_parser.h | 4 ++--
lib/tls13/session_ticket.c | 2 +-
26 files changed, 58 insertions(+), 78 deletions(-)
diff --git a/lib/crypto-api.c b/lib/crypto-api.c
index 2834c0199..09b3d7bfc 100644
--- a/lib/crypto-api.c
+++ b/lib/crypto-api.c
@@ -990,9 +990,9 @@ gnutls_aead_cipher_encryptv(gnutls_aead_cipher_hd_t handle,
api_aead_cipher_hd_st *h = handle;
ssize_t ret;
uint8_t *dst;
- ssize_t dst_size, total = 0;
+ size_t dst_size, total = 0;
uint8_t *p;
- ssize_t blocksize = handle->ctx_enc.e->blocksize;
+ size_t blocksize = handle->ctx_enc.e->blocksize;
struct iov_iter_st iter;
size_t blocks;
@@ -1071,7 +1071,7 @@ gnutls_aead_cipher_encryptv(gnutls_aead_cipher_hd_t handle,
if (ret == 0)
break;
blocks = ret;
- if (unlikely((size_t) dst_size < blocksize * blocks))
+ if (unlikely(dst_size < blocksize * blocks))
return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
ret = _gnutls_cipher_encrypt2(&handle->ctx_enc, p,
blocksize * blocks,
@@ -1083,7 +1083,7 @@ gnutls_aead_cipher_encryptv(gnutls_aead_cipher_hd_t handle,
total += blocksize * blocks;
}
if (iter.block_offset > 0) {
- if (unlikely((size_t) dst_size < iter.block_offset))
+ if (unlikely(dst_size < iter.block_offset))
return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
ret = _gnutls_cipher_encrypt2(&handle->ctx_enc,
iter.block, iter.block_offset,
@@ -1095,7 +1095,7 @@ gnutls_aead_cipher_encryptv(gnutls_aead_cipher_hd_t handle,
total += iter.block_offset;
}
- if ((size_t)dst_size < tag_size)
+ if (dst_size < tag_size)
return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
_gnutls_cipher_tag(&handle->ctx_enc, dst, tag_size);
diff --git a/lib/ext/alpn.c b/lib/ext/alpn.c
index 34f6ce09d..b9991f0a1 100644
--- a/lib/ext/alpn.c
+++ b/lib/ext/alpn.c
@@ -51,13 +51,12 @@ const hello_ext_entry_st ext_mod_alpn = {
static int
_gnutls_alpn_recv_params(gnutls_session_t session,
- const uint8_t * data, size_t _data_size)
+ const uint8_t * data, size_t data_size)
{
unsigned int i;
int ret;
const uint8_t *p = data;
unsigned len1, len;
- ssize_t data_size = _data_size;
alpn_ext_st *priv;
gnutls_ext_priv_data_t epriv;
int selected_protocol_index;
diff --git a/lib/ext/client_cert_type.c b/lib/ext/client_cert_type.c
index 471d42c5f..b627b71f9 100644
--- a/lib/ext/client_cert_type.c
+++ b/lib/ext/client_cert_type.c
@@ -73,7 +73,6 @@ static int _gnutls_client_cert_type_recv_params(gnutls_session_t session,
gnutls_certificate_type_t cert_type;
uint8_t i, found = 0;
- ssize_t len = data_size;
const uint8_t* pdata = data;
/* Only activate this extension if we have cert credentials set
@@ -86,7 +85,7 @@ static int _gnutls_client_cert_type_recv_params(gnutls_session_t session,
/* Compare packet length with expected packet length. For the
* client this is a single byte. */
- if (len != 1) {
+ if (data_size != 1) {
return
gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
}
@@ -136,8 +135,8 @@ static int _gnutls_client_cert_type_recv_params(gnutls_session_t session,
} else { // server mode
// Compare packet length with expected packet length.
- DECR_LEN(len, 1);
- if (data[0] != len) {
+ DECR_LEN(data_size, 1);
+ if (data[0] != data_size) {
return
gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
}
@@ -145,7 +144,7 @@ static int _gnutls_client_cert_type_recv_params(gnutls_session_t session,
// Assign the contents of our data buffer to a gnutls_datum_t
cert_types.data = (uint8_t*)pdata; // Need casting to get rid of 'discards const qualifier' warning
- cert_types.size = len;
+ cert_types.size = data_size;
// Store the client certificate types in our session
_gnutls_hello_ext_set_datum(session,
diff --git a/lib/ext/cookie.c b/lib/ext/cookie.c
index 1e66c3d49..0feb2f0e5 100644
--- a/lib/ext/cookie.c
+++ b/lib/ext/cookie.c
@@ -53,10 +53,9 @@ const hello_ext_entry_st ext_mod_cookie = {
/* Only client sends this extension. */
static int
cookie_recv_params(gnutls_session_t session,
- const uint8_t * data, size_t _data_size)
+ const uint8_t * data, size_t data_size)
{
- ssize_t data_size = _data_size;
- ssize_t csize;
+ size_t csize;
int ret;
gnutls_datum_t tmp;
diff --git a/lib/ext/ec_point_formats.c b/lib/ext/ec_point_formats.c
index eb59ec139..c702d434c 100644
--- a/lib/ext/ec_point_formats.c
+++ b/lib/ext/ec_point_formats.c
@@ -57,11 +57,10 @@ const hello_ext_entry_st ext_mod_supported_ec_point_formats = {
static int
_gnutls_supported_ec_point_formats_recv_params(gnutls_session_t session,
const uint8_t * data,
- size_t _data_size)
+ size_t data_size)
{
- int len, i;
+ size_t len, i;
int uncompressed = 0;
- int data_size = _data_size;
if (session->security_parameters.entity == GNUTLS_CLIENT) {
if (data_size < 1)
@@ -91,7 +90,7 @@ _gnutls_supported_ec_point_formats_recv_params(gnutls_session_t session,
/* only sanity check here. We only support uncompressed points
* and a client must support it thus nothing to check.
*/
- if (_data_size < 1)
+ if (data_size < 1)
return
gnutls_assert_val
(GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION);
diff --git a/lib/ext/key_share.c b/lib/ext/key_share.c
index 599eff8fb..8f0912e69 100644
--- a/lib/ext/key_share.c
+++ b/lib/ext/key_share.c
@@ -504,11 +504,10 @@ client_use_key_share(gnutls_session_t session, const gnutls_group_entry_st *grou
static int
key_share_recv_params(gnutls_session_t session,
- const uint8_t * data, size_t _data_size)
+ const uint8_t * data, size_t data_size)
{
int ret;
- ssize_t data_size = _data_size;
- ssize_t size;
+ size_t size;
unsigned gid;
const version_entry_st *ver;
const gnutls_group_entry_st *group;
diff --git a/lib/ext/max_record.c b/lib/ext/max_record.c
index dbb98cf62..3cada69be 100644
--- a/lib/ext/max_record.c
+++ b/lib/ext/max_record.c
@@ -65,10 +65,9 @@ const hello_ext_entry_st ext_mod_max_record_size = {
static int
_gnutls_max_record_recv_params(gnutls_session_t session,
- const uint8_t * data, size_t _data_size)
+ const uint8_t * data, size_t data_size)
{
ssize_t new_size;
- ssize_t data_size = _data_size;
if (session->internals.hsk_flags & HSK_RECORD_SIZE_LIMIT_NEGOTIATED)
return 0;
diff --git a/lib/ext/psk_ke_modes.c b/lib/ext/psk_ke_modes.c
index da7a55098..8d8effb43 100644
--- a/lib/ext/psk_ke_modes.c
+++ b/lib/ext/psk_ke_modes.c
@@ -106,10 +106,9 @@ psk_ke_modes_send_params(gnutls_session_t session,
*/
static int
psk_ke_modes_recv_params(gnutls_session_t session,
- const unsigned char *data, size_t _len)
+ const unsigned char *data, size_t len)
{
uint8_t ke_modes_len;
- ssize_t len = _len;
const version_entry_st *vers = get_version(session);
gnutls_psk_server_credentials_t cred;
int dhpsk_pos = MAX_POS;
diff --git a/lib/ext/record_size_limit.c b/lib/ext/record_size_limit.c
index e9fe6a1d8..0e94fece3 100644
--- a/lib/ext/record_size_limit.c
+++ b/lib/ext/record_size_limit.c
@@ -48,10 +48,9 @@ const hello_ext_entry_st ext_mod_record_size_limit = {
static int
_gnutls_record_size_limit_recv_params(gnutls_session_t session,
- const uint8_t * data, size_t _data_size)
+ const uint8_t * data, size_t data_size)
{
ssize_t new_size;
- ssize_t data_size = _data_size;
const version_entry_st *vers;
DECR_LEN(data_size, 2);
diff --git a/lib/ext/safe_renegotiation.c b/lib/ext/safe_renegotiation.c
index 6424f45b5..bb4a57e45 100644
--- a/lib/ext/safe_renegotiation.c
+++ b/lib/ext/safe_renegotiation.c
@@ -265,10 +265,9 @@ int _gnutls_ext_sr_send_cs(gnutls_session_t session)
static int
_gnutls_sr_recv_params(gnutls_session_t session,
- const uint8_t * data, size_t _data_size)
+ const uint8_t * data, size_t data_size)
{
unsigned int len;
- ssize_t data_size = _data_size;
sr_ext_st *priv;
gnutls_ext_priv_data_t epriv;
int set = 0, ret;
diff --git a/lib/ext/server_cert_type.c b/lib/ext/server_cert_type.c
index dbcb3971b..864a44bbc 100644
--- a/lib/ext/server_cert_type.c
+++ b/lib/ext/server_cert_type.c
@@ -73,7 +73,6 @@ static int _gnutls_server_cert_type_recv_params(gnutls_session_t session,
gnutls_certificate_type_t cert_type;
uint8_t i, found = 0;
- ssize_t len = data_size;
const uint8_t* pdata = data;
/* Only activate this extension if we have cert credentials set
@@ -86,7 +85,7 @@ static int _gnutls_server_cert_type_recv_params(gnutls_session_t session,
/* Compare packet length with expected packet length. For the
* client this is a single byte. */
- if (len != 1) {
+ if (data_size != 1) {
return
gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
}
@@ -135,8 +134,8 @@ static int _gnutls_server_cert_type_recv_params(gnutls_session_t session,
} else { // server mode
// Compare packet length with expected packet length.
- DECR_LEN(len, 1);
- if (data[0] != len) {
+ DECR_LEN(data_size, 1);
+ if (data[0] != data_size) {
return
gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
}
@@ -144,7 +143,7 @@ static int _gnutls_server_cert_type_recv_params(gnutls_session_t session,
// Assign the contents of our data buffer to a gnutls_datum_t
cert_types.data = (uint8_t*)pdata; // Need casting to get rid of 'discards const qualifier' warning
- cert_types.size = len;
+ cert_types.size = data_size;
// Store the server certificate types in our session
_gnutls_hello_ext_set_datum(session,
diff --git a/lib/ext/server_name.c b/lib/ext/server_name.c
index 259dc998e..0c6331569 100644
--- a/lib/ext/server_name.c
+++ b/lib/ext/server_name.c
@@ -66,11 +66,10 @@ const hello_ext_entry_st ext_mod_server_name = {
*/
static int
_gnutls_server_name_recv_params(gnutls_session_t session,
- const uint8_t * data, size_t _data_size)
+ const uint8_t * data, size_t data_size)
{
const unsigned char *p;
uint16_t len, type;
- ssize_t data_size = _data_size;
gnutls_datum_t name;
if (session->security_parameters.entity == GNUTLS_SERVER) {
diff --git a/lib/ext/session_ticket.c b/lib/ext/session_ticket.c
index 98db39ff8..263273fa2 100644
--- a/lib/ext/session_ticket.c
+++ b/lib/ext/session_ticket.c
@@ -78,7 +78,7 @@ static int
unpack_ticket(const gnutls_datum_t *ticket_data, struct ticket_st *ticket)
{
const uint8_t * data = ticket_data->data;
- ssize_t data_size = ticket_data->size;
+ size_t data_size = ticket_data->size;
const uint8_t *encrypted_state;
/* Format:
@@ -371,11 +371,10 @@ unpack_session(gnutls_session_t session, const gnutls_datum_t *state)
static int
session_ticket_recv_params(gnutls_session_t session,
- const uint8_t * data, size_t _data_size)
+ const uint8_t * data, size_t data_size)
{
gnutls_datum_t ticket_data;
gnutls_datum_t state;
- ssize_t data_size = _data_size;
int ret;
if (session->internals.flags & GNUTLS_NO_TICKETS)
diff --git a/lib/ext/signature.c b/lib/ext/signature.c
index e734d2c7d..a90f58d53 100644
--- a/lib/ext/signature.c
+++ b/lib/ext/signature.c
@@ -187,9 +187,8 @@ _gnutls_sign_algorithm_parse_data(gnutls_session_t session,
static int
_gnutls_signature_algorithm_recv_params(gnutls_session_t session,
const uint8_t * data,
- size_t _data_size)
+ size_t data_size)
{
- ssize_t data_size = _data_size;
int ret;
if (session->security_parameters.entity == GNUTLS_CLIENT) {
diff --git a/lib/ext/srp.c b/lib/ext/srp.c
index 8b58222e0..07f6e6883 100644
--- a/lib/ext/srp.c
+++ b/lib/ext/srp.c
@@ -59,10 +59,9 @@ const hello_ext_entry_st ext_mod_srp = {
static int
_gnutls_srp_recv_params(gnutls_session_t session, const uint8_t * data,
- size_t _data_size)
+ size_t data_size)
{
uint8_t len;
- ssize_t data_size = _data_size;
gnutls_ext_priv_data_t epriv;
srp_ext_st *priv;
diff --git a/lib/ext/srtp.c b/lib/ext/srtp.c
index 3fc7ed35a..412e26d45 100644
--- a/lib/ext/srtp.c
+++ b/lib/ext/srtp.c
@@ -162,13 +162,12 @@ const char *gnutls_srtp_get_profile_name(gnutls_srtp_profile_t profile)
static int
_gnutls_srtp_recv_params(gnutls_session_t session,
- const uint8_t * data, size_t _data_size)
+ const uint8_t * data, size_t data_size)
{
unsigned int i;
int ret;
const uint8_t *p = data;
- int len;
- ssize_t data_size = _data_size;
+ size_t len;
srtp_ext_st *priv;
gnutls_ext_priv_data_t epriv;
uint16_t profile;
diff --git a/lib/ext/status_request.c b/lib/ext/status_request.c
index d8779e8cf..cf9d5bd03 100644
--- a/lib/ext/status_request.c
+++ b/lib/ext/status_request.c
@@ -86,9 +86,8 @@ client_send(gnutls_session_t session,
static int
server_recv(gnutls_session_t session,
status_request_ext_st * priv,
- const uint8_t * data, size_t size)
+ const uint8_t * data, size_t data_size)
{
- ssize_t data_size = size;
unsigned rid_bytes = 0;
/* minimum message is type (1) + responder_id_list (2) +
diff --git a/lib/ext/supported_groups.c b/lib/ext/supported_groups.c
index 952d3bb0c..ef7859f73 100644
--- a/lib/ext/supported_groups.c
+++ b/lib/ext/supported_groups.c
@@ -93,10 +93,9 @@ static unsigned get_min_dh(gnutls_session_t session)
*/
static int
_gnutls_supported_groups_recv_params(gnutls_session_t session,
- const uint8_t * data, size_t _data_size)
+ const uint8_t * data, size_t data_size)
{
int i;
- ssize_t data_size = _data_size;
uint16_t len;
const uint8_t *p = data;
const gnutls_group_entry_st *group = NULL;
diff --git a/lib/ext/supported_versions.c b/lib/ext/supported_versions.c
index 52828ee37..8d52fad5c 100644
--- a/lib/ext/supported_versions.c
+++ b/lib/ext/supported_versions.c
@@ -54,12 +54,11 @@ const hello_ext_entry_st ext_mod_supported_versions = {
static int
supported_versions_recv_params(gnutls_session_t session,
- const uint8_t * data, size_t _data_size)
+ const uint8_t * data, size_t data_size)
{
const version_entry_st *vers;
- ssize_t data_size = _data_size;
uint8_t major, minor;
- ssize_t bytes;
+ size_t bytes;
int ret;
if (session->security_parameters.entity == GNUTLS_SERVER) {
diff --git a/lib/extv.c b/lib/extv.c
index bfdfdf974..0c0c46f32 100644
--- a/lib/extv.c
+++ b/lib/extv.c
@@ -105,7 +105,7 @@ int gnutls_ext_raw_parse(void *ctx, gnutls_ext_raw_process_func cb,
const gnutls_datum_t *data, unsigned int flags)
{
if (flags & GNUTLS_EXT_RAW_FLAG_TLS_CLIENT_HELLO) {
- ssize_t size = data->size;
+ size_t size = data->size;
size_t len;
uint8_t *p = data->data;
@@ -137,12 +137,12 @@ int gnutls_ext_raw_parse(void *ctx, gnutls_ext_raw_process_func cb,
DECR_LEN(size, len);
p += len;
- if (size <= 0)
+ if (size == 0)
return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
return _gnutls_extv_parse(ctx, cb, p, size);
} else if (flags & GNUTLS_EXT_RAW_FLAG_DTLS_CLIENT_HELLO) {
- ssize_t size = data->size;
+ size_t size = data->size;
size_t len;
uint8_t *p = data->data;
@@ -181,7 +181,7 @@ int gnutls_ext_raw_parse(void *ctx, gnutls_ext_raw_process_func cb,
DECR_LEN(size, len);
p += len;
- if (size <= 0)
+ if (size == 0)
return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
return _gnutls_extv_parse(ctx, cb, p, size);
diff --git a/lib/sslv2_compat.c b/lib/sslv2_compat.c
index 6122d1098..9d247ba4c 100644
--- a/lib/sslv2_compat.c
+++ b/lib/sslv2_compat.c
@@ -87,14 +87,13 @@ _gnutls_handshake_select_v2_suite(gnutls_session_t session,
*/
int
_gnutls_read_client_hello_v2(gnutls_session_t session, uint8_t * data,
- unsigned int datalen)
+ unsigned int len)
{
uint16_t session_id_len = 0;
int pos = 0;
int ret = 0, sret = 0;
uint16_t sizeOfSuites;
uint8_t rnd[GNUTLS_RANDOM_SIZE], major, minor;
- int len = datalen;
int neg_version;
const version_entry_st *vers;
uint16_t challenge;
diff --git a/lib/supplemental.c b/lib/supplemental.c
index cd90fa1fb..07b38cc93 100644
--- a/lib/supplemental.c
+++ b/lib/supplemental.c
@@ -192,14 +192,14 @@ _gnutls_parse_supplemental(gnutls_session_t session,
const uint8_t * data, int datalen)
{
const uint8_t *p = data;
- ssize_t dsize = datalen;
+ size_t dsize = datalen;
size_t total_size;
DECR_LEN(dsize, 3);
total_size = _gnutls_read_uint24(p);
p += 3;
- if (dsize != (ssize_t) total_size) {
+ if (dsize != total_size) {
gnutls_assert();
return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
}
diff --git a/lib/tls13/certificate.c b/lib/tls13/certificate.c
index bd257237f..8a1a11872 100644
--- a/lib/tls13/certificate.c
+++ b/lib/tls13/certificate.c
@@ -360,11 +360,12 @@ static int parse_cert_extension(void *_ctx, unsigned tls_id, const uint8_t *data
static int
parse_cert_list(gnutls_session_t session, uint8_t * data, size_t data_size)
{
- int len, ret;
+ int ret;
+ size_t len;
uint8_t *p = data;
cert_auth_info_t info;
gnutls_certificate_credentials_t cred;
- ssize_t dsize = data_size, size;
+ size_t size;
int i;
unsigned npeer_certs, npeer_ocsp, j;
crt_cert_ctx_st ctx;
@@ -395,31 +396,31 @@ parse_cert_list(gnutls_session_t session, uint8_t * data, size_t data_size)
if (info == NULL)
return gnutls_assert_val(GNUTLS_E_INSUFFICIENT_CREDENTIALS);
- DECR_LEN(dsize, 3);
+ DECR_LEN(data_size, 3);
size = _gnutls_read_uint24(p);
p += 3;
- if (size != dsize)
+ if (size != data_size)
return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
if (size == 0)
return gnutls_assert_val(GNUTLS_E_NO_CERTIFICATE_FOUND);
- i = dsize;
+ i = data_size;
while (i > 0) {
- DECR_LEN(dsize, 3);
+ DECR_LEN(data_size, 3);
len = _gnutls_read_uint24(p);
if (len == 0)
return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
- DECR_LEN(dsize, len);
+ DECR_LEN(data_size, len);
p += len + 3;
i -= len + 3;
- DECR_LEN(dsize, 2);
+ DECR_LEN(data_size, 2);
len = _gnutls_read_uint16(p);
- DECR_LEN(dsize, len);
+ DECR_LEN(data_size, len);
i -= len + 2;
p += len + 2;
@@ -427,7 +428,7 @@ parse_cert_list(gnutls_session_t session, uint8_t * data, size_t data_size)
nentries++;
}
- if (dsize != 0)
+ if (data_size != 0)
return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
/* this is unnecessary - keeping to avoid a regression due to a re-org
diff --git a/lib/tls13/psk_ext_parser.c b/lib/tls13/psk_ext_parser.c
index 6e3a12f90..33ebc0461 100644
--- a/lib/tls13/psk_ext_parser.c
+++ b/lib/tls13/psk_ext_parser.c
@@ -28,10 +28,8 @@
* are present, or 0, on success.
*/
int _gnutls13_psk_ext_parser_init(psk_ext_parser_st *p,
- const unsigned char *data, size_t _len)
+ const unsigned char *data, size_t len)
{
- ssize_t len = _len;
-
if (!p || !data || !len)
return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
diff --git a/lib/tls13/psk_ext_parser.h b/lib/tls13/psk_ext_parser.h
index 30b47e904..f46b211e0 100644
--- a/lib/tls13/psk_ext_parser.h
+++ b/lib/tls13/psk_ext_parser.h
@@ -25,10 +25,10 @@
struct psk_ext_parser_st {
const unsigned char *identities_data;
- ssize_t identities_len;
+ size_t identities_len;
const unsigned char *binders_data;
- ssize_t binders_len;
+ size_t binders_len;
};
typedef struct psk_ext_parser_st psk_ext_parser_st;
diff --git a/lib/tls13/session_ticket.c b/lib/tls13/session_ticket.c
index 146aee9b1..072a56d9c 100644
--- a/lib/tls13/session_ticket.c
+++ b/lib/tls13/session_ticket.c
@@ -105,7 +105,7 @@ unpack_ticket(gnutls_session_t session, gnutls_datum_t *packed, tls13_ticket_st
gnutls_mac_algorithm_t kdf;
const mac_entry_st *prf;
uint8_t *p;
- ssize_t len;
+ size_t len;
uint64_t v;
int ret;
--
2.21.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,203 @@
From c7a419e7868fd9342c1799a04d21c2ff6292c405 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <dueno@redhat.com>
Date: Fri, 21 Jun 2019 15:49:26 +0200
Subject: [PATCH] nettle/rnd-fips: add FIPS 140-2 continuous RNG test
This adds a continuous random number generator test as defined in FIPS
140-2 4.9.2, by iteratively fetching fixed sized block from the system
and comparing consecutive blocks.
Signed-off-by: Daiki Ueno <dueno@redhat.com>
---
lib/nettle/rnd-fips.c | 102 +++++++++++++++++++++++++++++++++---------
1 file changed, 81 insertions(+), 21 deletions(-)
diff --git a/lib/nettle/rnd-fips.c b/lib/nettle/rnd-fips.c
index ee68cf68d..ccb92d25a 100644
--- a/lib/nettle/rnd-fips.c
+++ b/lib/nettle/rnd-fips.c
@@ -27,12 +27,13 @@
#include "gnutls_int.h"
#include "errors.h"
-#include <nettle/aes.h>
-#include <nettle/memxor.h>
-#include <locks.h>
+#include <nettle/sha2.h>
#include <atfork.h>
#include <rnd-common.h>
+/* The block size is chosen arbitrarily */
+#define ENTROPY_BLOCK_SIZE SHA256_DIGEST_SIZE
+
/* This provides a random generator for gnutls. It uses
* two instances of the DRBG-AES-CTR generator, one for
* nonce level and another for the other levels of randomness.
@@ -41,11 +42,13 @@ struct fips_ctx {
struct drbg_aes_ctx nonce_context;
struct drbg_aes_ctx normal_context;
unsigned int forkid;
+ uint8_t entropy_hash[SHA256_DIGEST_SIZE];
};
static int _rngfips_ctx_reinit(struct fips_ctx *fctx);
static int _rngfips_ctx_init(struct fips_ctx *fctx);
-static int drbg_reseed(struct drbg_aes_ctx *ctx);
+static int drbg_reseed(struct fips_ctx *fctx, struct drbg_aes_ctx *ctx);
+static int get_entropy(struct fips_ctx *fctx, uint8_t *buffer, size_t length);
static int get_random(struct drbg_aes_ctx *ctx, struct fips_ctx *fctx,
void *buffer, size_t length)
@@ -59,7 +62,7 @@ static int get_random(struct drbg_aes_ctx *ctx, struct fips_ctx *fctx,
}
if (ctx->reseed_counter > DRBG_AES_RESEED_TIME) {
- ret = drbg_reseed(ctx);
+ ret = drbg_reseed(fctx, ctx);
if (ret < 0)
return gnutls_assert_val(ret);
}
@@ -71,54 +74,111 @@ static int get_random(struct drbg_aes_ctx *ctx, struct fips_ctx *fctx,
return 0;
}
+static int get_entropy(struct fips_ctx *fctx, uint8_t *buffer, size_t length)
+{
+ int ret;
+ uint8_t block[ENTROPY_BLOCK_SIZE];
+ uint8_t hash[SHA256_DIGEST_SIZE];
+ struct sha256_ctx ctx;
+ size_t total = 0;
+
+ /* For FIPS 140-2 4.9.2 continuous random number generator
+ * test, iteratively fetch fixed sized block from the system
+ * RNG and compare consecutive blocks.
+ *
+ * Note that we store the hash of the entropy block rather
+ * than the block itself for backward secrecy.
+ */
+ while (total < length) {
+ ret = _rnd_get_system_entropy(block, ENTROPY_BLOCK_SIZE);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ sha256_init(&ctx);
+ sha256_update(&ctx, sizeof(block), block);
+ sha256_digest(&ctx, sizeof(hash), hash);
+
+ if (memcmp(hash, fctx->entropy_hash, sizeof(hash)) == 0) {
+ _gnutls_switch_lib_state(LIB_STATE_ERROR);
+ return gnutls_assert_val(GNUTLS_E_RANDOM_FAILED);
+ }
+ memcpy(fctx->entropy_hash, hash, sizeof(hash));
+
+ memcpy(buffer, block, MIN(length - total, sizeof(block)));
+ total += sizeof(block);
+ buffer += sizeof(block);
+ }
+ zeroize_key(block, sizeof(block));
+
+ return 0;
+}
+
#define PSTRING "gnutls-rng"
#define PSTRING_SIZE (sizeof(PSTRING)-1)
-static int drbg_init(struct drbg_aes_ctx *ctx)
+static int drbg_init(struct fips_ctx *fctx, struct drbg_aes_ctx *ctx)
{
uint8_t buffer[DRBG_AES_SEED_SIZE];
int ret;
- /* Get a key from the standard RNG or from the entropy source. */
- ret = _rnd_get_system_entropy(buffer, sizeof(buffer));
+ ret = get_entropy(fctx, buffer, sizeof(buffer));
if (ret < 0)
return gnutls_assert_val(ret);
- ret = drbg_aes_init(ctx, sizeof(buffer), buffer, PSTRING_SIZE, (void*)PSTRING);
+ ret = drbg_aes_init(ctx, sizeof(buffer), buffer,
+ PSTRING_SIZE, (void*)PSTRING);
+ zeroize_key(buffer, sizeof(buffer));
if (ret == 0)
return gnutls_assert_val(GNUTLS_E_RANDOM_FAILED);
- zeroize_key(buffer, sizeof(buffer));
-
- return 0;
+ return GNUTLS_E_SUCCESS;
}
/* Reseed a generator. */
-static int drbg_reseed(struct drbg_aes_ctx *ctx)
+static int drbg_reseed(struct fips_ctx *fctx, struct drbg_aes_ctx *ctx)
{
uint8_t buffer[DRBG_AES_SEED_SIZE];
int ret;
- /* The other two generators are seeded from /dev/random. */
- ret = _rnd_get_system_entropy(buffer, sizeof(buffer));
+ ret = get_entropy(fctx, buffer, sizeof(buffer));
if (ret < 0)
return gnutls_assert_val(ret);
- drbg_aes_reseed(ctx, sizeof(buffer), buffer, 0, NULL);
+ ret = drbg_aes_reseed(ctx, sizeof(buffer), buffer, 0, NULL);
+ zeroize_key(buffer, sizeof(buffer));
+ if (ret == 0)
+ return gnutls_assert_val(GNUTLS_E_RANDOM_FAILED);
- return 0;
+ return GNUTLS_E_SUCCESS;
}
static int _rngfips_ctx_init(struct fips_ctx *fctx)
{
+ uint8_t block[ENTROPY_BLOCK_SIZE];
+ struct sha256_ctx ctx;
int ret;
+ /* For FIPS 140-2 4.9.2 continuous random number generator
+ * test, get the initial entropy from the system RNG and keep
+ * it for comparison.
+ *
+ * Note that we store the hash of the entropy block rather
+ * than the block itself for backward secrecy.
+ */
+ ret = _rnd_get_system_entropy(block, sizeof(block));
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+ sha256_init(&ctx);
+ sha256_update(&ctx, sizeof(block), block);
+ zeroize_key(block, sizeof(block));
+ sha256_digest(&ctx, sizeof(fctx->entropy_hash), fctx->entropy_hash);
+
/* normal */
- ret = drbg_init(&fctx->normal_context);
+ ret = drbg_init(fctx, &fctx->normal_context);
if (ret < 0)
return gnutls_assert_val(ret);
/* nonce */
- ret = drbg_init(&fctx->nonce_context);
+ ret = drbg_init(fctx, &fctx->nonce_context);
if (ret < 0)
return gnutls_assert_val(ret);
@@ -132,12 +192,12 @@ static int _rngfips_ctx_reinit(struct fips_ctx *fctx)
int ret;
/* normal */
- ret = drbg_reseed(&fctx->normal_context);
+ ret = drbg_reseed(fctx, &fctx->normal_context);
if (ret < 0)
return gnutls_assert_val(ret);
/* nonce */
- ret = drbg_reseed(&fctx->nonce_context);
+ ret = drbg_reseed(fctx, &fctx->nonce_context);
if (ret < 0)
return gnutls_assert_val(ret);
--
2.21.0

View File

@ -0,0 +1,124 @@
From fbb6dd2a65c6fc7a2e9bd82fe66fde54f6cf2952 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <dueno@redhat.com>
Date: Fri, 16 Aug 2019 17:01:05 +0200
Subject: [PATCH] nettle: disable RSA blinding in FIPS selftests
Nettle's RSA signing, encryption and decryption functions still
require randomness for blinding, so fallback to use a fixed buffer in
selftests where entropy might not be available.
Signed-off-by: Daiki Ueno <dueno@redhat.com>
---
lib/nettle/pk.c | 37 +++++++++++++++++++++++++++++++++----
1 file changed, 33 insertions(+), 4 deletions(-)
diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c
index b2d27cf74..772fcdc21 100644
--- a/lib/nettle/pk.c
+++ b/lib/nettle/pk.c
@@ -94,6 +94,15 @@ static void rnd_mpz_func(void *_ctx, size_t length, uint8_t * data)
nettle_mpz_get_str_256 (length, data, *k);
}
+static void rnd_nonce_func_fallback(void *_ctx, size_t length, uint8_t * data)
+{
+ if (unlikely(_gnutls_get_lib_state() != LIB_STATE_SELFTEST)) {
+ _gnutls_switch_lib_state(LIB_STATE_ERROR);
+ }
+
+ memset(data, 0xAA, length);
+}
+
static void
ecc_scalar_zclear (struct ecc_scalar *s)
{
@@ -435,6 +444,7 @@ _wrap_nettle_pk_encrypt(gnutls_pk_algorithm_t algo,
case GNUTLS_PK_RSA:
{
struct rsa_public_key pub;
+ nettle_random_func *random_func;
ret = _rsa_params_to_pubkey(pk_params, &pub);
if (ret < 0) {
@@ -442,8 +452,12 @@ _wrap_nettle_pk_encrypt(gnutls_pk_algorithm_t algo,
goto cleanup;
}
+ if (_gnutls_get_lib_state() == LIB_STATE_SELFTEST)
+ random_func = rnd_nonce_func_fallback;
+ else
+ random_func = rnd_nonce_func;
ret =
- rsa_encrypt(&pub, NULL, rnd_nonce_func,
+ rsa_encrypt(&pub, NULL, random_func,
plaintext->size, plaintext->data,
p);
if (ret == 0 || HAVE_LIB_ERROR()) {
@@ -496,6 +510,7 @@ _wrap_nettle_pk_decrypt(gnutls_pk_algorithm_t algo,
struct rsa_public_key pub;
size_t length;
bigint_t c;
+ nettle_random_func *random_func;
_rsa_params_to_privkey(pk_params, &priv);
ret = _rsa_params_to_pubkey(pk_params, &pub);
@@ -526,8 +541,12 @@ _wrap_nettle_pk_decrypt(gnutls_pk_algorithm_t algo,
goto cleanup;
}
+ if (_gnutls_get_lib_state() == LIB_STATE_SELFTEST)
+ random_func = rnd_nonce_func_fallback;
+ else
+ random_func = rnd_nonce_func;
ret =
- rsa_decrypt_tr(&pub, &priv, NULL, rnd_nonce_func,
+ rsa_decrypt_tr(&pub, &priv, NULL, random_func,
&length, plaintext->data,
TOMPZ(c));
_gnutls_mpi_release(&c);
@@ -573,6 +592,7 @@ _wrap_nettle_pk_decrypt2(gnutls_pk_algorithm_t algo,
bigint_t c;
uint32_t is_err;
int ret;
+ nettle_random_func *random_func;
if (algo != GNUTLS_PK_RSA || plaintext == NULL) {
gnutls_assert();
@@ -592,7 +612,11 @@ _wrap_nettle_pk_decrypt2(gnutls_pk_algorithm_t algo,
return gnutls_assert_val (GNUTLS_E_MPI_SCAN_FAILED);
}
- ret = rsa_sec_decrypt(&pub, &priv, NULL, rnd_nonce_func,
+ if (_gnutls_get_lib_state() == LIB_STATE_SELFTEST)
+ random_func = rnd_nonce_func_fallback;
+ else
+ random_func = rnd_nonce_func;
+ ret = rsa_sec_decrypt(&pub, &priv, NULL, random_func,
plaintext_size, plaintext, TOMPZ(c));
/* after this point, any conditional on failure that cause differences
* in execution may create a timing or cache access pattern side
@@ -942,6 +966,7 @@ _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
{
struct rsa_private_key priv;
struct rsa_public_key pub;
+ nettle_random_func *random_func;
mpz_t s;
_rsa_params_to_privkey(pk_params, &priv);
@@ -952,8 +977,12 @@ _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
mpz_init(s);
+ if (_gnutls_get_lib_state() == LIB_STATE_SELFTEST)
+ random_func = rnd_nonce_func_fallback;
+ else
+ random_func = rnd_nonce_func;
ret =
- rsa_pkcs1_sign_tr(&pub, &priv, NULL, rnd_nonce_func,
+ rsa_pkcs1_sign_tr(&pub, &priv, NULL, random_func,
vdata->size, vdata->data, s);
if (ret == 0 || HAVE_LIB_ERROR()) {
gnutls_assert();
--
2.21.0

View File

@ -0,0 +1,767 @@
From bbb312749780928cc10b45662c6d7eadcaa98f0b Mon Sep 17 00:00:00 2001
From: Daiki Ueno <dueno@redhat.com>
Date: Thu, 3 Oct 2019 10:34:18 +0200
Subject: [PATCH 1/3] iov: _gnutls_iov_iter_next: return bytes instead of
blocks
This eliminates the need of special handling of final block. Also
adds more tests in exceptional cases.
Signed-off-by: Daiki Ueno <dueno@redhat.com>
---
lib/crypto-api.c | 82 +++++-------------------------
lib/iov.c | 31 +++++++++---
tests/iov.c | 126 ++++++++++++++++++++++++++++++++---------------
3 files changed, 121 insertions(+), 118 deletions(-)
diff --git a/lib/crypto-api.c b/lib/crypto-api.c
index 09b3d7bfc..41e759b74 100644
--- a/lib/crypto-api.c
+++ b/lib/crypto-api.c
@@ -992,9 +992,9 @@ gnutls_aead_cipher_encryptv(gnutls_aead_cipher_hd_t handle,
uint8_t *dst;
size_t dst_size, total = 0;
uint8_t *p;
+ size_t len;
size_t blocksize = handle->ctx_enc.e->blocksize;
struct iov_iter_st iter;
- size_t blocks;
/* Limitation: this function provides an optimization under the internally registered
* AEAD ciphers. When an AEAD cipher is used registered with gnutls_crypto_register_aead_cipher(),
@@ -1045,15 +1045,7 @@ gnutls_aead_cipher_encryptv(gnutls_aead_cipher_hd_t handle,
return gnutls_assert_val(ret);
if (ret == 0)
break;
- blocks = ret;
- ret = _gnutls_cipher_auth(&handle->ctx_enc, p,
- blocksize * blocks);
- if (unlikely(ret < 0))
- return gnutls_assert_val(ret);
- }
- if (iter.block_offset > 0) {
- ret = _gnutls_cipher_auth(&handle->ctx_enc,
- iter.block, iter.block_offset);
+ ret = _gnutls_cipher_auth(&handle->ctx_enc, p, ret);
if (unlikely(ret < 0))
return gnutls_assert_val(ret);
}
@@ -1070,29 +1062,15 @@ gnutls_aead_cipher_encryptv(gnutls_aead_cipher_hd_t handle,
return gnutls_assert_val(ret);
if (ret == 0)
break;
- blocks = ret;
- if (unlikely(dst_size < blocksize * blocks))
- return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
- ret = _gnutls_cipher_encrypt2(&handle->ctx_enc, p,
- blocksize * blocks,
- dst, dst_size);
- if (unlikely(ret < 0))
- return gnutls_assert_val(ret);
- DECR_LEN(dst_size, blocksize * blocks);
- dst += blocksize * blocks;
- total += blocksize * blocks;
- }
- if (iter.block_offset > 0) {
- if (unlikely(dst_size < iter.block_offset))
- return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
+ len = ret;
ret = _gnutls_cipher_encrypt2(&handle->ctx_enc,
- iter.block, iter.block_offset,
+ p, len,
dst, dst_size);
if (unlikely(ret < 0))
return gnutls_assert_val(ret);
- DECR_LEN(dst_size, iter.block_offset);
- dst += iter.block_offset;
- total += iter.block_offset;
+ DECR_LEN(dst_size, len);
+ dst += len;
+ total += len;
}
if (dst_size < tag_size)
@@ -1137,7 +1115,6 @@ gnutls_aead_cipher_encryptv2(gnutls_aead_cipher_hd_t handle,
uint8_t *p;
ssize_t blocksize = handle->ctx_enc.e->blocksize;
struct iov_iter_st iter;
- size_t blocks;
size_t _tag_size;
if (tag_size == NULL || *tag_size == 0)
@@ -1220,15 +1197,7 @@ gnutls_aead_cipher_encryptv2(gnutls_aead_cipher_hd_t handle,
return gnutls_assert_val(ret);
if (ret == 0)
break;
- blocks = ret;
- ret = _gnutls_cipher_auth(&handle->ctx_enc, p,
- blocksize * blocks);
- if (unlikely(ret < 0))
- return gnutls_assert_val(ret);
- }
- if (iter.block_offset > 0) {
- ret = _gnutls_cipher_auth(&handle->ctx_enc,
- iter.block, iter.block_offset);
+ ret = _gnutls_cipher_auth(&handle->ctx_enc, p, ret);
if (unlikely(ret < 0))
return gnutls_assert_val(ret);
}
@@ -1242,17 +1211,7 @@ gnutls_aead_cipher_encryptv2(gnutls_aead_cipher_hd_t handle,
return gnutls_assert_val(ret);
if (ret == 0)
break;
- blocks = ret;
- ret = _gnutls_cipher_encrypt2(&handle->ctx_enc,
- p, blocksize * blocks,
- p, blocksize * blocks);
- if (unlikely(ret < 0))
- return gnutls_assert_val(ret);
- }
- if (iter.block_offset > 0) {
- ret = _gnutls_cipher_encrypt2(&handle->ctx_enc,
- iter.block, iter.block_offset,
- iter.block, iter.block_offset);
+ ret = _gnutls_cipher_encrypt2(&handle->ctx_enc, p, ret, p, ret);
if (unlikely(ret < 0))
return gnutls_assert_val(ret);
}
@@ -1296,7 +1255,6 @@ gnutls_aead_cipher_decryptv2(gnutls_aead_cipher_hd_t handle,
uint8_t *p;
ssize_t blocksize = handle->ctx_enc.e->blocksize;
struct iov_iter_st iter;
- size_t blocks;
uint8_t _tag[MAX_HASH_SIZE];
if (tag_size == 0)
@@ -1370,15 +1328,7 @@ gnutls_aead_cipher_decryptv2(gnutls_aead_cipher_hd_t handle,
return gnutls_assert_val(ret);
if (ret == 0)
break;
- blocks = ret;
- ret = _gnutls_cipher_auth(&handle->ctx_enc, p,
- blocksize * blocks);
- if (unlikely(ret < 0))
- return gnutls_assert_val(ret);
- }
- if (iter.block_offset > 0) {
- ret = _gnutls_cipher_auth(&handle->ctx_enc,
- iter.block, iter.block_offset);
+ ret = _gnutls_cipher_auth(&handle->ctx_enc, p, ret);
if (unlikely(ret < 0))
return gnutls_assert_val(ret);
}
@@ -1392,17 +1342,7 @@ gnutls_aead_cipher_decryptv2(gnutls_aead_cipher_hd_t handle,
return gnutls_assert_val(ret);
if (ret == 0)
break;
- blocks = ret;
- ret = _gnutls_cipher_decrypt2(&handle->ctx_enc,
- p, blocksize * blocks,
- p, blocksize * blocks);
- if (unlikely(ret < 0))
- return gnutls_assert_val(ret);
- }
- if (iter.block_offset > 0) {
- ret = _gnutls_cipher_decrypt2(&handle->ctx_enc,
- iter.block, iter.block_offset,
- iter.block, iter.block_offset);
+ ret = _gnutls_cipher_decrypt2(&handle->ctx_enc, p, ret, p, ret);
if (unlikely(ret < 0))
return gnutls_assert_val(ret);
}
diff --git a/lib/iov.c b/lib/iov.c
index 5dc29c54b..17272886c 100644
--- a/lib/iov.c
+++ b/lib/iov.c
@@ -58,8 +58,8 @@ _gnutls_iov_iter_init(struct iov_iter_st *iter,
* @data: the return location of extracted data
*
* Retrieve block(s) pointed by @iter and advance it to the next
- * position. It returns the number of consecutive blocks in @data.
- * At the end of iteration, 0 is returned.
+ * position. It returns the number of bytes in @data. At the end of
+ * iteration, 0 is returned.
*
* If the data stored in @iter is not multiple of the block size, the
* remaining data is stored in the "block" field of @iter with the
@@ -88,25 +88,30 @@ _gnutls_iov_iter_next(struct iov_iter_st *iter, uint8_t **data)
if ((len % iter->block_size) == 0) {
iter->iov_index++;
iter->iov_offset = 0;
- } else
- iter->iov_offset +=
- len - (len % iter->block_size);
+ } else {
+ len -= (len % iter->block_size);
+ iter->iov_offset += len;
+ }
/* Return the blocks. */
*data = p;
- return len / iter->block_size;
+ return len;
}
/* We can complete one full block to return. */
block_left = iter->block_size - iter->block_offset;
if (len >= block_left) {
memcpy(iter->block + iter->block_offset, p, block_left);
- iter->iov_offset += block_left;
+ if (len == block_left) {
+ iter->iov_index++;
+ iter->iov_offset = 0;
+ } else
+ iter->iov_offset += block_left;
iter->block_offset = 0;
/* Return the filled block. */
*data = iter->block;
- return 1;
+ return iter->block_size;
}
/* Not enough data for a full block, store in temp
@@ -116,5 +121,15 @@ _gnutls_iov_iter_next(struct iov_iter_st *iter, uint8_t **data)
iter->iov_index++;
iter->iov_offset = 0;
}
+
+ if (iter->block_offset > 0) {
+ size_t len = iter->block_offset;
+
+ /* Return the incomplete block. */
+ *data = iter->block;
+ iter->block_offset = 0;
+ return len;
+ }
+
return 0;
}
diff --git a/tests/iov.c b/tests/iov.c
index eda5583a7..3d116b471 100644
--- a/tests/iov.c
+++ b/tests/iov.c
@@ -32,7 +32,6 @@ struct exp_st {
ssize_t ret;
size_t iov_index;
size_t iov_offset;
- size_t block_offset;
};
struct test_st {
@@ -42,7 +41,6 @@ struct test_st {
size_t block_size;
const struct exp_st *exp;
size_t expcnt;
- size_t remaining;
};
static const giovec_t iov16[] = {
@@ -53,40 +51,41 @@ static const giovec_t iov16[] = {
};
static const struct exp_st exp16_64[] = {
- {1, 3, 16, 0},
- {0, 0, 0, 0}
+ {64, 4, 0},
+ {0, 0, 0}
};
static const struct exp_st exp16_32[] = {
- {1, 1, 16, 0},
- {1, 3, 16, 0},
- {0, 0, 0, 0}
+ {32, 2, 0},
+ {32, 4, 0},
+ {0, 0, 0}
};
static const struct exp_st exp16_16[] = {
- {1, 1, 0, 0},
- {1, 2, 0, 0},
- {1, 3, 0, 0},
- {1, 4, 0, 0},
- {0, 0, 0, 0}
+ {16, 1, 0},
+ {16, 2, 0},
+ {16, 3, 0},
+ {16, 4, 0},
+ {0, 0, 0}
};
static const struct exp_st exp16_4[] = {
- {4, 1, 0, 0},
- {4, 2, 0, 0},
- {4, 3, 0, 0},
- {4, 4, 0, 0},
- {0, 0, 0, 0}
+ {16, 1, 0},
+ {16, 2, 0},
+ {16, 3, 0},
+ {16, 4, 0},
+ {0, 0, 0}
};
static const struct exp_st exp16_3[] = {
- {5, 0, 15, 0},
- {1, 1, 2, 0},
- {4, 1, 14, 0},
- {1, 2, 1, 0},
- {5, 3, 0, 0},
- {5, 3, 15, 0},
- {0, 0, 0, 1}
+ {15, 0, 15},
+ {3, 1, 2},
+ {12, 1, 14},
+ {3, 2, 1},
+ {15, 3, 0},
+ {15, 3, 15},
+ {1, 4, 0},
+ {0, 0, 0}
};
static const giovec_t iov8[] = {
@@ -97,22 +96,74 @@ static const giovec_t iov8[] = {
};
static const struct exp_st exp8_64[] = {
- {0, 0, 0, 32}
+ {32, 4, 0},
+ {0, 0, 0}
+};
+
+static const giovec_t iov_odd[] = {
+ {(void *) "0", 1},
+ {(void *) "012", 3},
+ {(void *) "01234", 5},
+ {(void *) "0123456", 7},
+ {(void *) "012345678", 9},
+ {(void *) "01234567890", 11},
+ {(void *) "0123456789012", 13},
+ {(void *) "012345678901234", 15}
+};
+
+static const struct exp_st exp_odd_16[] = {
+ {16, 4, 0},
+ {16, 5, 7},
+ {16, 6, 12},
+ {16, 8, 0},
+ {0, 0, 0}
+};
+
+static const giovec_t iov_skip[] = {
+ {(void *) "0123456789012345", 16},
+ {(void *) "01234567", 8},
+ {(void *) "", 0},
+ {(void *) "", 0},
+ {(void *) "0123456789012345", 16}
+};
+
+static const struct exp_st exp_skip_16[] = {
+ {16, 1, 0},
+ {16, 4, 8},
+ {8, 5, 0},
+ {0, 0, 0}
+};
+
+static const giovec_t iov_empty[] = {
+ {(void *) "", 0},
+ {(void *) "", 0},
+ {(void *) "", 0},
+ {(void *) "", 0}
+};
+
+static const struct exp_st exp_empty_16[] = {
+ {0, 0, 0}
};
static const struct test_st tests[] = {
{ "16/64", iov16, sizeof(iov16)/sizeof(iov16[0]), 64,
- exp16_64, sizeof(exp16_64)/sizeof(exp16_64[0]), 0 },
+ exp16_64, sizeof(exp16_64)/sizeof(exp16_64[0]) },
{ "16/32", iov16, sizeof(iov16)/sizeof(iov16[0]), 32,
- exp16_32, sizeof(exp16_32)/sizeof(exp16_32[0]), 0 },
+ exp16_32, sizeof(exp16_32)/sizeof(exp16_32[0]) },
{ "16/16", iov16, sizeof(iov16)/sizeof(iov16[0]), 16,
- exp16_16, sizeof(exp16_16)/sizeof(exp16_16[0]), 0 },
+ exp16_16, sizeof(exp16_16)/sizeof(exp16_16[0]) },
{ "16/4", iov16, sizeof(iov16)/sizeof(iov16[0]), 4,
- exp16_4, sizeof(exp16_4)/sizeof(exp16_4[0]), 0 },
+ exp16_4, sizeof(exp16_4)/sizeof(exp16_4[0]) },
{ "16/3", iov16, sizeof(iov16)/sizeof(iov16[0]), 3,
- exp16_3, sizeof(exp16_3)/sizeof(exp16_3[0]), 1 },
+ exp16_3, sizeof(exp16_3)/sizeof(exp16_3[0]) },
{ "8/64", iov8, sizeof(iov8)/sizeof(iov8[0]), 64,
- exp8_64, sizeof(exp8_64)/sizeof(exp8_64[0]), 32 }
+ exp8_64, sizeof(exp8_64)/sizeof(exp8_64[0]) },
+ { "odd/16", iov_odd, sizeof(iov_odd)/sizeof(iov_odd[0]), 16,
+ exp_odd_16, sizeof(exp_odd_16)/sizeof(exp_odd_16[0]) },
+ { "skip/16", iov_skip, sizeof(iov_skip)/sizeof(iov_skip[0]), 16,
+ exp_skip_16, sizeof(exp_skip_16)/sizeof(exp_skip_16[0]) },
+ { "empty/16", iov_empty, sizeof(iov_empty)/sizeof(iov_empty[0]), 16,
+ exp_empty_16, sizeof(exp_empty_16)/sizeof(exp_empty_16[0]) },
};
void
@@ -155,16 +206,13 @@ doit (void)
else if (debug)
success("iter.iov_offset: %u == %u\n",
(unsigned) iter.iov_offset, (unsigned) exp[j].iov_offset);
- if (iter.block_offset != exp[j].block_offset)
- fail("iter.block_offset: %u != %u\n",
- (unsigned) iter.block_offset, (unsigned) exp[j].block_offset);
+ if (iter.block_offset != 0)
+ fail("iter.block_offset: %u != 0\n",
+ (unsigned) iter.block_offset);
else if (debug)
- success("iter.block_offset: %u == %u\n",
- (unsigned) iter.block_offset, (unsigned) exp[j].block_offset);
+ success("iter.block_offset: %u == 0\n",
+ (unsigned) iter.block_offset);
}
}
- if (iter.block_offset != tests[i].remaining)
- fail("remaining: %u != %u\n",
- (unsigned) iter.block_offset, (unsigned) tests[i].remaining);
}
}
--
2.21.0
From c684814cc456a9792a9183ce77d32d435f29e6b7 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <dueno@redhat.com>
Date: Tue, 1 Oct 2019 18:14:48 +0200
Subject: [PATCH 2/3] iov: add _gnutls_iov_iter_sync to write back cached data
to iov
Signed-off-by: Daiki Ueno <dueno@redhat.com>
---
lib/iov.c | 59 +++++++++++++++++++++++++++++++++++++++++++++
lib/iov.h | 4 +++-
lib/libgnutls.map | 1 +
tests/iov.c | 61 +++++++++++++++++++++++++++++++++++++++++++----
4 files changed, 119 insertions(+), 6 deletions(-)
diff --git a/lib/iov.c b/lib/iov.c
index 17272886c..1cd8d46dd 100644
--- a/lib/iov.c
+++ b/lib/iov.c
@@ -133,3 +133,62 @@ _gnutls_iov_iter_next(struct iov_iter_st *iter, uint8_t **data)
return 0;
}
+
+/**
+ * _gnutls_iov_iter_sync:
+ * @iter: the iterator
+ * @data: data returned by _gnutls_iov_iter_next
+ * @data_size: size of @data
+ *
+ * Flush the content of temp buffer (if any) to the data buffer.
+ */
+int
+_gnutls_iov_iter_sync(struct iov_iter_st *iter, const uint8_t *data,
+ size_t data_size)
+{
+ size_t iov_index;
+ size_t iov_offset;
+
+ /* We didn't return the cached block. */
+ if (data != iter->block)
+ return 0;
+
+ iov_index = iter->iov_index;
+ iov_offset = iter->iov_offset;
+
+ /* When syncing a cache block we walk backwards because we only have a
+ * pointer to were the block ends in the iovec, walking backwards is
+ * fine as we are always writing a full block, so the whole content
+ * is written in the right places:
+ * iovec: |--0--|---1---|--2--|-3-|
+ * block: |-----------------------|
+ * 1st write |---|
+ * 2nd write |-----
+ * 3rd write |-------
+ * last write |-----
+ */
+ while (data_size > 0) {
+ const giovec_t *iov;
+ uint8_t *p;
+ size_t to_write;
+
+ while (iov_offset == 0) {
+ if (unlikely(iov_index == 0))
+ return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
+
+ iov_index--;
+ iov_offset = iter->iov[iov_index].iov_len;
+ }
+
+ iov = &iter->iov[iov_index];
+ p = iov->iov_base;
+ to_write = MIN(data_size, iov_offset);
+
+ iov_offset -= to_write;
+ data_size -= to_write;
+
+ memcpy(p + iov_offset, &iter->block[data_size], to_write);
+ }
+
+ return 0;
+}
diff --git a/lib/iov.h b/lib/iov.h
index 47fba559a..5b9903460 100644
--- a/lib/iov.h
+++ b/lib/iov.h
@@ -34,7 +34,6 @@ struct iov_iter_st {
uint8_t block[MAX_CIPHER_BLOCK_SIZE]; /* incomplete block for reading */
size_t block_size; /* actual block size of the cipher */
size_t block_offset; /* offset in block */
-
};
int _gnutls_iov_iter_init(struct iov_iter_st *iter,
@@ -43,4 +42,7 @@ int _gnutls_iov_iter_init(struct iov_iter_st *iter,
ssize_t _gnutls_iov_iter_next(struct iov_iter_st *iter, uint8_t **data);
+int _gnutls_iov_iter_sync(struct iov_iter_st *iter, const uint8_t *data,
+ size_t data_size);
+
#endif /* GNUTLS_LIB_IOV_H */
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index f83a21e9b..d6973f72e 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -1394,4 +1394,5 @@ GNUTLS_PRIVATE_3_4 {
# needed by tests/iov:
_gnutls_iov_iter_init;
_gnutls_iov_iter_next;
+ _gnutls_iov_iter_sync;
} GNUTLS_3_4;
diff --git a/tests/iov.c b/tests/iov.c
index 3d116b471..2acd2b5f5 100644
--- a/tests/iov.c
+++ b/tests/iov.c
@@ -44,10 +44,10 @@ struct test_st {
};
static const giovec_t iov16[] = {
- {(void *) "0123456789abcdef", 16},
- {(void *) "0123456789abcdef", 16},
- {(void *) "0123456789abcdef", 16},
- {(void *) "0123456789abcdef", 16}
+ {(void *) "0123456789012345", 16},
+ {(void *) "0123456789012345", 16},
+ {(void *) "0123456789012345", 16},
+ {(void *) "0123456789012345", 16}
};
static const struct exp_st exp16_64[] = {
@@ -166,20 +166,53 @@ static const struct test_st tests[] = {
exp_empty_16, sizeof(exp_empty_16)/sizeof(exp_empty_16[0]) },
};
+static void
+copy(giovec_t *dst, uint8_t *buffer, const giovec_t *src, size_t iovcnt)
+{
+ uint8_t *p = buffer;
+ size_t i;
+
+ for (i = 0; i < iovcnt; i++) {
+ dst[i].iov_base = p;
+ dst[i].iov_len = src[i].iov_len;
+ memcpy(dst[i].iov_base, src[i].iov_base, src[i].iov_len);
+ p += src[i].iov_len;
+ }
+}
+
+static void
+translate(uint8_t *data, size_t len)
+{
+ for (; len > 0; len--) {
+ uint8_t *p = &data[len - 1];
+ if (*p >= '0' && *p <= '9')
+ *p = 'A' + *p - '0';
+ else if (*p >= 'A' && *p <= 'Z')
+ *p = '0' + *p - 'A';
+ }
+}
+
+#define MAX_BUF 1024
+#define MAX_IOV 16
+
void
doit (void)
{
+ uint8_t buffer[MAX_BUF];
size_t i;
for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
+ giovec_t iov[MAX_IOV];
struct iov_iter_st iter;
const struct exp_st *exp = tests[i].exp;
uint8_t *data;
size_t j;
+ copy(iov, buffer, tests[i].iov, tests[i].iovcnt);
+
success("%s\n", tests[i].name);
assert(_gnutls_iov_iter_init(&iter,
- tests[i].iov, tests[i].iovcnt,
+ iov, tests[i].iovcnt,
tests[i].block_size) == 0);
for (j = 0; j < tests[i].expcnt; j++) {
ssize_t ret;
@@ -212,7 +245,25 @@ doit (void)
else if (debug)
success("iter.block_offset: %u == 0\n",
(unsigned) iter.block_offset);
+
+ translate(data, ret);
+
+ ret = _gnutls_iov_iter_sync(&iter, data, ret);
+ if (ret < 0)
+ fail("sync failed\n");
}
}
+
+ for (j = 0; j < tests[i].iovcnt; j++) {
+ translate(iov[j].iov_base, iov[j].iov_len);
+
+ if (memcmp(iov[j].iov_base, tests[i].iov[j].iov_base,
+ iov[j].iov_len) != 0)
+ fail("iov doesn't match: %*s != %*s\n",
+ (int)iov[j].iov_len,
+ (char *)iov[j].iov_base,
+ (int)tests[i].iov[j].iov_len,
+ (char *)tests[i].iov[j].iov_len);
+ }
}
}
--
2.21.0
From 6df0cf1c0ec727fc237a9b429684c8f2ef5d34b7 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <dueno@redhat.com>
Date: Tue, 1 Oct 2019 18:15:19 +0200
Subject: [PATCH 3/3] gnutls_aead_cipher_{en,de}cryptv2: write back cached data
to buffers
Previously, those functions failed to write the output to the buffers
if the buffer length is not multiple of cipher block size. This makes
sure that the cached data is always flushed.
Signed-off-by: Daiki Ueno <dueno@redhat.com>
---
lib/crypto-api.c | 18 ++++++++++++++++--
tests/aead-cipher-vec.c | 14 ++++++++------
2 files changed, 24 insertions(+), 8 deletions(-)
diff --git a/lib/crypto-api.c b/lib/crypto-api.c
index 41e759b74..7308d7e7b 100644
--- a/lib/crypto-api.c
+++ b/lib/crypto-api.c
@@ -1113,6 +1113,7 @@ gnutls_aead_cipher_encryptv2(gnutls_aead_cipher_hd_t handle,
api_aead_cipher_hd_st *h = handle;
ssize_t ret;
uint8_t *p;
+ size_t len;
ssize_t blocksize = handle->ctx_enc.e->blocksize;
struct iov_iter_st iter;
size_t _tag_size;
@@ -1211,7 +1212,13 @@ gnutls_aead_cipher_encryptv2(gnutls_aead_cipher_hd_t handle,
return gnutls_assert_val(ret);
if (ret == 0)
break;
- ret = _gnutls_cipher_encrypt2(&handle->ctx_enc, p, ret, p, ret);
+
+ len = ret;
+ ret = _gnutls_cipher_encrypt2(&handle->ctx_enc, p, len, p, len);
+ if (unlikely(ret < 0))
+ return gnutls_assert_val(ret);
+
+ ret = _gnutls_iov_iter_sync(&iter, p, len);
if (unlikely(ret < 0))
return gnutls_assert_val(ret);
}
@@ -1253,6 +1260,7 @@ gnutls_aead_cipher_decryptv2(gnutls_aead_cipher_hd_t handle,
api_aead_cipher_hd_st *h = handle;
ssize_t ret;
uint8_t *p;
+ size_t len;
ssize_t blocksize = handle->ctx_enc.e->blocksize;
struct iov_iter_st iter;
uint8_t _tag[MAX_HASH_SIZE];
@@ -1342,7 +1350,13 @@ gnutls_aead_cipher_decryptv2(gnutls_aead_cipher_hd_t handle,
return gnutls_assert_val(ret);
if (ret == 0)
break;
- ret = _gnutls_cipher_decrypt2(&handle->ctx_enc, p, ret, p, ret);
+
+ len = ret;
+ ret = _gnutls_cipher_decrypt2(&handle->ctx_enc, p, len, p, len);
+ if (unlikely(ret < 0))
+ return gnutls_assert_val(ret);
+
+ ret = _gnutls_iov_iter_sync(&iter, p, len);
if (unlikely(ret < 0))
return gnutls_assert_val(ret);
}
diff --git a/tests/aead-cipher-vec.c b/tests/aead-cipher-vec.c
index 6c2542cf1..10e3db862 100644
--- a/tests/aead-cipher-vec.c
+++ b/tests/aead-cipher-vec.c
@@ -43,9 +43,9 @@ static void start(const char *name, int algo)
uint8_t key16[64];
uint8_t iv16[32];
uint8_t auth[128];
- uint8_t data[128+64];
+ uint8_t data[64+56+36];
gnutls_datum_t key, iv;
- giovec_t iov[2];
+ giovec_t iov[3];
giovec_t auth_iov[2];
uint8_t tag[64];
size_t tag_size = 0;
@@ -60,13 +60,15 @@ static void start(const char *name, int algo)
memset(iv.data, 0xff, iv.size);
memset(key.data, 0xfe, key.size);
- memset(data, 0xfa, 128);
+ memset(data, 0xfa, sizeof(data));
memset(auth, 0xaa, sizeof(auth));
iov[0].iov_base = data;
iov[0].iov_len = 64;
iov[1].iov_base = data + 64;
- iov[1].iov_len = 64;
+ iov[1].iov_len = 56;
+ iov[2].iov_base = data + 64 + 56;
+ iov[2].iov_len = 36;
auth_iov[0].iov_base = auth;
auth_iov[0].iov_len = 64;
@@ -83,7 +85,7 @@ static void start(const char *name, int algo)
ret = gnutls_aead_cipher_encryptv2(ch,
iv.data, iv.size,
auth_iov, 2,
- iov, 2,
+ iov, 3,
tag, &tag_size);
if (ret < 0)
fail("could not encrypt data: %s\n", gnutls_strerror(ret));
@@ -91,7 +93,7 @@ static void start(const char *name, int algo)
ret = gnutls_aead_cipher_decryptv2(ch,
iv.data, iv.size,
auth_iov, 2,
- iov, 2,
+ iov, 3,
tag, tag_size);
if (ret < 0)
fail("could not decrypt data: %s\n", gnutls_strerror(ret));
--
2.21.0

View File

@ -0,0 +1,204 @@
From 1c2135506825ae80966fe2797613806916b7e3c0 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <dueno@redhat.com>
Date: Wed, 6 Nov 2019 12:07:24 +0100
Subject: [PATCH 1/2] nettle: backport fixes to cfb8_decrypt
cfb8: don't truncate output IV if input is shorter than block size:
https://git.lysator.liu.se/nettle/nettle/commit/f4a9c842621baf5d71aa9cc3989851f44dc46861
Signed-off-by: Daiki Ueno <dueno@redhat.com>
---
lib/nettle/backport/cfb8.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/lib/nettle/backport/cfb8.c b/lib/nettle/backport/cfb8.c
index e9816feb7..1762192f4 100644
--- a/lib/nettle/backport/cfb8.c
+++ b/lib/nettle/backport/cfb8.c
@@ -110,10 +110,12 @@ cfb8_decrypt(const void *ctx, nettle_cipher_func *f,
src += i;
dst += i;
- memcpy(buffer, buffer + block_size, block_size);
- memcpy(buffer + block_size, src,
- length < block_size ? length : block_size);
-
+ if (i == block_size)
+ {
+ memcpy(buffer, buffer + block_size, block_size);
+ memcpy(buffer + block_size, src,
+ length < block_size ? length : block_size);
+ }
}
memcpy(iv, buffer + i, block_size);
--
2.21.0
From cc01347302678719f0bcfb4f3383fe0f1e905ed8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org>
Date: Wed, 6 Nov 2019 13:17:57 +0100
Subject: [PATCH 2/2] crypto-selftests: test CFB8 ciphers with different
chunksizes
Signed-off-by: Guenther Deschner <gd@samba.org>
Signed-off-by: Daiki Ueno <dueno@redhat.com>
---
lib/crypto-selftests.c | 124 +++++++++++++++++++++++++++++++++++++++--
1 file changed, 118 insertions(+), 6 deletions(-)
diff --git a/lib/crypto-selftests.c b/lib/crypto-selftests.c
index 6caf817e8..5f0a4ec8b 100644
--- a/lib/crypto-selftests.c
+++ b/lib/crypto-selftests.c
@@ -710,6 +710,107 @@ static int test_cipher(gnutls_cipher_algorithm_t cipher,
return 0;
}
+static int test_cipher_all_block_sizes(gnutls_cipher_algorithm_t cipher,
+ const struct cipher_vectors_st *vectors,
+ size_t vectors_size, unsigned flags)
+{
+ gnutls_cipher_hd_t hd;
+ int ret;
+ unsigned int i;
+ uint8_t tmp[384];
+ gnutls_datum_t key, iv = {NULL, 0};
+ size_t block;
+ size_t offset;
+
+ for (i = 0; i < vectors_size; i++) {
+ for (block = 1; block <= vectors[i].plaintext_size; block++) {
+ key.data = (void *) vectors[i].key;
+ key.size = vectors[i].key_size;
+
+ iv.data = (void *) vectors[i].iv;
+ iv.size = gnutls_cipher_get_iv_size(cipher);
+
+ if (iv.size != vectors[i].iv_size)
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
+
+ ret = gnutls_cipher_init(&hd, cipher, &key, &iv);
+ if (ret < 0) {
+ _gnutls_debug_log("error initializing: %s\n",
+ gnutls_cipher_get_name(cipher));
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
+ }
+
+ for (offset = 0;
+ offset < vectors[i].plaintext_size;
+ offset += block) {
+ ret =
+ gnutls_cipher_encrypt2(hd,
+ vectors[i].plaintext + offset,
+ MIN(block, vectors[i].plaintext_size - offset),
+ tmp + offset,
+ sizeof(tmp) - offset);
+ if (ret < 0)
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
+ }
+
+ if (memcmp
+ (tmp, vectors[i].ciphertext,
+ vectors[i].plaintext_size) != 0) {
+ _gnutls_debug_log("%s encryption of test vector %d failed with block size %d/%d!\n",
+ gnutls_cipher_get_name(cipher),
+ i, (int)block, (int)vectors[i].plaintext_size);
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
+ }
+
+ gnutls_cipher_deinit(hd);
+ }
+ }
+
+ for (i = 0; i < vectors_size; i++) {
+ for (block = 1; block <= vectors[i].plaintext_size; block++) {
+ key.data = (void *) vectors[i].key;
+ key.size = vectors[i].key_size;
+
+ iv.data = (void *) vectors[i].iv;
+ iv.size = gnutls_cipher_get_iv_size(cipher);
+
+ ret = gnutls_cipher_init(&hd, cipher, &key, &iv);
+ if (ret < 0)
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
+
+ for (offset = 0;
+ offset + block <= vectors[i].plaintext_size;
+ offset += block) {
+ ret =
+ gnutls_cipher_decrypt2(hd,
+ vectors[i].ciphertext + offset,
+ MIN(block, vectors[i].plaintext_size - offset),
+ tmp + offset,
+ sizeof(tmp) - offset);
+ if (ret < 0)
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
+ }
+
+ if (memcmp
+ (tmp, vectors[i].plaintext,
+ vectors[i].plaintext_size) != 0) {
+ _gnutls_debug_log("%s decryption of test vector %d failed with block size %d!\n",
+ gnutls_cipher_get_name(cipher),
+ i, (int)block);
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
+ }
+
+ gnutls_cipher_deinit(hd);
+ }
+ }
+
+ _gnutls_debug_log
+ ("%s self check succeeded\n",
+ gnutls_cipher_get_name(cipher));
+
+ return 0;
+}
+
/* AEAD modes (compat APIs) */
static int test_cipher_aead_compat(gnutls_cipher_algorithm_t cipher,
const struct cipher_aead_vectors_st *vectors,
@@ -1721,6 +1822,14 @@ static int test_mac(gnutls_mac_algorithm_t mac,
if (!(flags & GNUTLS_SELF_TEST_FLAG_ALL) || ret < 0) \
return ret
+#define CASE2(x, func, func2, vectors) case x: \
+ ret = func(x, V(vectors), flags); \
+ if (!(flags & GNUTLS_SELF_TEST_FLAG_ALL) || ret < 0) \
+ return ret; \
+ ret = func2(x, V(vectors), flags); \
+ if (!(flags & GNUTLS_SELF_TEST_FLAG_ALL) || ret < 0) \
+ return ret
+
#define NON_FIPS_CASE(x, func, vectors) case x: \
if (_gnutls_fips_mode_enabled() == 0) { \
ret = func(x, V(vectors), flags); \
@@ -1786,14 +1895,17 @@ int gnutls_cipher_self_test(unsigned flags, gnutls_cipher_algorithm_t cipher)
NON_FIPS_CASE(GNUTLS_CIPHER_CHACHA20_POLY1305, test_cipher_aead,
chacha_poly1305_vectors);
FALLTHROUGH;
- CASE(GNUTLS_CIPHER_AES_128_CFB8, test_cipher,
- aes128_cfb8_vectors);
+ CASE2(GNUTLS_CIPHER_AES_128_CFB8, test_cipher,
+ test_cipher_all_block_sizes,
+ aes128_cfb8_vectors);
FALLTHROUGH;
- CASE(GNUTLS_CIPHER_AES_192_CFB8, test_cipher,
- aes192_cfb8_vectors);
+ CASE2(GNUTLS_CIPHER_AES_192_CFB8, test_cipher,
+ test_cipher_all_block_sizes,
+ aes192_cfb8_vectors);
FALLTHROUGH;
- CASE(GNUTLS_CIPHER_AES_256_CFB8, test_cipher,
- aes256_cfb8_vectors);
+ CASE2(GNUTLS_CIPHER_AES_256_CFB8, test_cipher,
+ test_cipher_all_block_sizes,
+ aes256_cfb8_vectors);
FALLTHROUGH;
CASE(GNUTLS_CIPHER_AES_128_XTS, test_cipher,
aes128_xts_vectors);
--
2.21.0

View File

@ -0,0 +1,265 @@
From fa5147c86941512921282b84819b896a0d4f29bb Mon Sep 17 00:00:00 2001
From: Daiki Ueno <dueno@redhat.com>
Date: Wed, 19 Jun 2019 17:21:16 +0200
Subject: [PATCH] pkcs11: ignore login error when traversing tokens
If a token is a general access device, it is expected that login
attempt to that token returns error:
https://github.com/p11-glue/p11-kit/blob/master/trust/module.c#L852
On the other hand, _pkcs11_traverse_tokens treats the error as fatal
and stops iteration. This behavior prevents object search without
token specifier if such tokens are registered in the system.
Reported by Stanislav Zidek in
https://bugzilla.redhat.com/show_bug.cgi?id=1705478
Signed-off-by: Daiki Ueno <dueno@redhat.com>
---
.gitignore | 1 +
lib/pkcs11.c | 8 +-
tests/Makefile.am | 2 +-
tests/p11-kit-load.sh | 23 ++++++
tests/pkcs11/list-objects.c | 150 ++++++++++++++++++++++++++++++++++++
5 files changed, 182 insertions(+), 2 deletions(-)
create mode 100644 tests/pkcs11/list-objects.c
diff --git a/lib/pkcs11.c b/lib/pkcs11.c
index de5309b29..2ef0e3e02 100644
--- a/lib/pkcs11.c
+++ b/lib/pkcs11.c
@@ -1617,7 +1617,13 @@ _pkcs11_traverse_tokens(find_func_t find_func, void *input,
info, flags);
if (ret < 0) {
gnutls_assert();
- return ret;
+ pkcs11_close_session(&sinfo);
+
+ /* treat the error as fatal only if
+ * the token requires login */
+ if (l_tinfo.flags & CKF_LOGIN_REQUIRED)
+ return ret;
+ continue;
}
ret =
diff --git a/tests/Makefile.am b/tests/Makefile.am
index a67f1549c..7fe954f63 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -496,7 +496,7 @@ dist_check_SCRIPTS += p11-kit-trust.sh testpkcs11.sh certtool-pkcs11.sh
if HAVE_PKCS11_TRUST_STORE
if P11KIT_0_23_11_API
dist_check_SCRIPTS += p11-kit-load.sh
-indirect_tests += pkcs11/list-tokens
+indirect_tests += pkcs11/list-tokens pkcs11/list-objects
endif
endif
diff --git a/tests/p11-kit-load.sh b/tests/p11-kit-load.sh
index 3201a2c5f..419900f6a 100755
--- a/tests/p11-kit-load.sh
+++ b/tests/p11-kit-load.sh
@@ -22,6 +22,7 @@
srcdir="${srcdir:-.}"
builddir="${builddir:-.}"
CERTTOOL="${CERTTOOL:-../src/certtool${EXEEXT}}"
+P11TOOL="${P11TOOL:-../src/p11tool${EXEEXT}}"
DIFF="${DIFF:-diff}"
PKGCONFIG="${PKG_CONFIG:-$(which pkg-config)}"
TMP_SOFTHSM_DIR="./softhsm-load.$$.tmp"
@@ -90,6 +91,12 @@ if test $? != 0; then
exit 1
fi
+GNUTLS_PIN="${PIN}" ${P11TOOL} --login --label GnuTLS-Test-RSA --generate-privkey rsa --provider "${SOFTHSM_MODULE}" pkcs11: --outfile /dev/null
+if test $? != 0; then
+ echo "failed to generate privkey"
+ exit 1
+fi
+
FILTERTOKEN="sed s/token=.*//g"
# Check whether both are listed
@@ -175,6 +182,22 @@ if test "$nr" != 2;then
exit 1
fi
+# Check whether public key and privkey are listed.
+nr=$(GNUTLS_PIN="${PIN}" ${builddir}/pkcs11/list-objects -o ${P11DIR} -t all pkcs11:token=GnuTLS-Test|sort -u|wc -l)
+if test "$nr" != 2;then
+ echo "Error in test 8: did not find all objects"
+ ${builddir}/pkcs11/list-objects -o ${P11DIR} -t all pkcs11:token=GnuTLS-Test
+ exit 1
+fi
+
+# Check whether all privkeys are listed even if trust module is registered.
+nr=$(GNUTLS_PIN="${PIN}" ${builddir}/pkcs11/list-objects -o ${P11DIR} -t privkey pkcs11:|sort -u|wc -l)
+if test "$nr" != 1;then
+ echo "Error in test 9: did not find privkey objects"
+ ${builddir}/pkcs11/list-objects -o ${P11DIR} -t privkey pkcs11:
+ exit 1
+fi
+
rm -f ${P11DIR}/*
rm -rf ${TMP_SOFTHSM_DIR}
diff --git a/tests/pkcs11/list-objects.c b/tests/pkcs11/list-objects.c
new file mode 100644
index 000000000..ab30cd568
--- /dev/null
+++ b/tests/pkcs11/list-objects.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2016-2017 Red Hat, Inc.
+ *
+ * Author: Nikos Mavrogiannopoulos
+ *
+ * This file is part of GnuTLS.
+ *
+ * GnuTLS is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuTLS is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <gnutls/gnutls.h>
+#include <gnutls/x509.h>
+#include <gnutls/abstract.h>
+#include <getopt.h>
+#define P11_KIT_FUTURE_UNSTABLE_API
+#include <p11-kit/p11-kit.h>
+#include "cert-common.h"
+
+/* lists the registered PKCS#11 modules by p11-kit.
+ */
+
+static void tls_log_func(int level, const char *str)
+{
+ fprintf(stderr, "|<%d>| %s", level, str);
+}
+
+static const char *opt_pin;
+
+static
+int pin_func(void* userdata, int attempt, const char* url, const char *label,
+ unsigned flags, char *pin, size_t pin_max)
+{
+ if (attempt == 0) {
+ strcpy(pin, opt_pin);
+ return 0;
+ }
+ return -1;
+}
+
+int main(int argc, char **argv)
+{
+ int ret;
+ unsigned i;
+ int opt;
+ char *url, *mod;
+ unsigned flags;
+ unsigned obj_flags = 0;
+ int attrs = GNUTLS_PKCS11_OBJ_ATTR_ALL;
+ gnutls_pkcs11_obj_t *crt_list;
+ unsigned int crt_list_size = 0;
+ const char *envvar;
+
+ ret = gnutls_global_init();
+ if (ret != 0) {
+ fprintf(stderr, "error at %d: %s\n", __LINE__, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ gnutls_global_set_log_function(tls_log_func);
+
+ while((opt = getopt(argc, argv, "o:t:")) != -1) {
+ switch(opt) {
+ case 'o':
+ mod = strdup(optarg);
+ p11_kit_override_system_files(NULL, NULL, mod, mod, NULL);
+ break;
+ case 't':
+ /* specify the object type to list */
+ if (strcmp(optarg, "all") == 0)
+ attrs = GNUTLS_PKCS11_OBJ_ATTR_ALL;
+ else if (strcmp(optarg, "privkey") == 0)
+ attrs = GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY;
+ else {
+ fprintf(stderr, "Unknown object type %s\n", optarg);
+ exit(1);
+ }
+ break;
+ default:
+ fprintf(stderr, "Unknown option %c\n", (char)opt);
+ exit(1);
+ }
+ }
+
+ if (optind == argc) {
+ fprintf(stderr, "specify URL\n");
+ exit(1);
+ }
+ url = argv[optind];
+
+ envvar = getenv("GNUTLS_PIN");
+ if (envvar && *envvar != '\0') {
+ opt_pin = envvar;
+ obj_flags |= GNUTLS_PKCS11_OBJ_FLAG_LOGIN;
+ gnutls_pkcs11_set_pin_function(pin_func, NULL);
+ }
+
+ ret = gnutls_pkcs11_token_get_flags(url, &flags);
+ if (ret < 0) {
+ flags = 0;
+ }
+
+ ret =
+ gnutls_pkcs11_obj_list_import_url2(&crt_list, &crt_list_size,
+ url, attrs, obj_flags);
+ if (ret != 0) {
+ fprintf(stderr, "error at %d: %s\n", __LINE__, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ for (i = 0; i < crt_list_size; i++) {
+ char *output;
+
+ ret =
+ gnutls_pkcs11_obj_export_url(crt_list[i], 0,
+ &output);
+ if (ret != 0) {
+ fprintf(stderr, "error at %d: %s\n", __LINE__, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ fprintf(stdout, "%s\n", output);
+ gnutls_free(output);
+ gnutls_pkcs11_obj_deinit(crt_list[i]);
+ }
+ gnutls_free(crt_list);
+
+ gnutls_global_deinit();
+}
--
2.21.0

View File

@ -0,0 +1,51 @@
From 1f6bbceeeeb613cf4d790874bdd1e917a7071159 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <dueno@redhat.com>
Date: Mon, 8 Jul 2019 16:54:56 +0200
Subject: [PATCH] ext/session_ticket: avoid calling memcpy on overlapping
memory areas
In _gnutls_encrypt_session_ticket, ticket.encrypted_state is allocated
from ticket_data->data, thus those memory areas may overlap. Using
memcpy here leads to undefined behavior.
Spotted by valgrind run on ppc64le.
==95231== Source and destination overlap in memcpy(0x47ce3a2, 0x47ce3a2, 160)
==95231== at 0x408A840: memcpy (vg_replace_strmem.c:1023)
==95231== by 0x424EE9F: pack_ticket (session_ticket.c:139)
==95231== by 0x424FA4F: _gnutls_encrypt_session_ticket (session_ticket.c:335)
==95231== by 0x4199E3B: generate_session_ticket (session_ticket.c:249)
==95231== by 0x419A333: _gnutls13_send_session_ticket (session_ticket.c:307)
==95231== by 0x40F8817: _gnutls13_handshake_server (handshake-tls13.c:511)
==95231== by 0x4110DEB: handshake_server (handshake.c:3331)
==95231== by 0x410C70B: gnutls_handshake (handshake.c:2727)
==95231== by 0x10009EBF: retry_handshake (serv.c:1306)
==95231== by 0x1000AB67: tcp_server (serv.c:1500)
==95231== by 0x10009E5B: main (serv.c:1297)
==95231==
Signed-off-by: Daiki Ueno <dueno@redhat.com>
---
lib/ext/session_ticket.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/lib/ext/session_ticket.c b/lib/ext/session_ticket.c
index 09e240c2d..98db39ff8 100644
--- a/lib/ext/session_ticket.c
+++ b/lib/ext/session_ticket.c
@@ -136,7 +136,11 @@ pack_ticket(const struct ticket_st *ticket, gnutls_datum_t *ticket_data)
_gnutls_write_uint16(ticket->encrypted_state_len, p);
p += 2;
- memcpy(p, ticket->encrypted_state, ticket->encrypted_state_len);
+ /* We use memmove instead of memcpy here because
+ * ticket->encrypted_state is allocated from
+ * ticket_data->data, and thus both memory areas may overlap.
+ */
+ memmove(p, ticket->encrypted_state, ticket->encrypted_state_len);
p += ticket->encrypted_state_len;
memcpy(p, ticket->mac, TICKET_MAC_SIZE);
--
2.21.0

View File

@ -1,10 +1,19 @@
Version: 3.6.8
Release: 3%{?dist}
Release: 9%{?dist}
Patch1: gnutls-3.2.7-rpath.patch
Patch2: gnutls-3.6.4-no-now-guile.patch
Patch3: gnutls-3.6.5-fix-fips-signature-post.patch
Patch4: gnutls-3.6.8-fips-aes-cbc-kat.patch
Patch5: gnutls-3.6.8-multiple-key-updates.patch
Patch6: gnutls-3.6.8-fips-rng-continuous.patch
Patch7: gnutls-3.6.8-session-ticket-ub.patch
Patch8: gnutls-3.6.8-pkcs11-login-error.patch
Patch9: gnutls-3.6.8-fips-deterministic-ecdsa.patch
Patch10: gnutls-3.6.8-aead-cipher-encryptv2.patch
Patch11: gnutls-3.6.8-fips-rsa-random-selftests.patch
Patch12: gnutls-3.6.8-decr-len.patch
Patch13: gnutls-3.6.8-fix-aead-cipher-encryptv2.patch
Patch14: gnutls-3.6.8-fix-cfb8-decrypt.patch
%bcond_without dane
%if 0%{?rhel}
%bcond_with guile
@ -288,6 +297,27 @@ fi
%endif
%changelog
* Wed Nov 6 2019 Daiki Ueno <dueno@redhat.com> - 3.6.8-9
- Fix CFB8 decryption when repeatedly called (#1757848)
- Fix gnutls_aead_cipher_{en,de}cryptv2 with input not multiple of block size (#1757856)
* Fri Aug 16 2019 Daiki Ueno <dueno@redhat.com> - 3.6.8-8
- Use fallback random function for RSA blinding in FIPS selftests
* Fri Aug 16 2019 Daiki Ueno <dueno@redhat.com> - 3.6.8-7
- Fix deterministic signature creation in selftests
* Fri Aug 16 2019 Daiki Ueno <dueno@redhat.com> - 3.6.8-6
- Treat login error more gracefully when enumerating PKCS#11 tokens (#1705478)
- Use deterministic ECDSA/DSA in FIPS selftests (#1716560)
- Add gnutls_aead_cipher_{encrypt,decrypt}v2 functions (#1684461)
* Fri Aug 9 2019 Daiki Ueno <dueno@redhat.com> - 3.6.8-5
- Avoid UB when encrypting session tickets
* Tue Jul 2 2019 Daiki Ueno <dueno@redhat.com> - 3.6.8-4
- Add RNG continuous test under FIPS
* Fri Jun 14 2019 Daiki Ueno <dueno@redhat.com> - 3.6.8-3
- Follow-up fix on multiple key updates handling (#1673975)