All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v7 1/5] tls: Check buffer bounds in tls_rsa_sign
@ 2016-06-20 23:53 Mat Martineau
  2016-06-20 23:53 ` [PATCH v7 2/5] cipher: Return number of read bytes from asymmetric ops Mat Martineau
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Mat Martineau @ 2016-06-20 23:53 UTC (permalink / raw)
  To: ell

[-- Attachment #1: Type: text/plain, Size: 5126 bytes --]

---
 ell/tls-private.h |  2 +-
 ell/tls.c         | 54 ++++++++++++++++++++++++++++++++++++++----------------
 2 files changed, 39 insertions(+), 17 deletions(-)

diff --git a/ell/tls-private.h b/ell/tls-private.h
index 184f2ae..1a47970 100644
--- a/ell/tls-private.h
+++ b/ell/tls-private.h
@@ -65,7 +65,7 @@ struct tls_key_exchange_algorithm {
 	void (*handle_client_key_exchange)(struct l_tls *tls,
 						const uint8_t *buf, size_t len);
 
-	bool (*sign)(struct l_tls *tls, uint8_t **out,
+	ssize_t (*sign)(struct l_tls *tls, uint8_t *out, size_t len,
 			tls_get_hash_t get_hash);
 	bool (*verify)(struct l_tls *tls, const uint8_t *in, size_t len,
 			tls_get_hash_t get_hash);
diff --git a/ell/tls.c b/ell/tls.c
index 0baddf7..3bd7d7d 100644
--- a/ell/tls.c
+++ b/ell/tls.c
@@ -25,6 +25,7 @@
 #define _GNU_SOURCE
 #include <time.h>
 #include <stdlib.h>
+#include <errno.h>
 
 #include "util.h"
 #include "private.h"
@@ -274,7 +275,7 @@ static bool tls_send_rsa_client_key_xchg(struct l_tls *tls);
 static void tls_handle_rsa_client_key_xchg(struct l_tls *tls,
 						const uint8_t *buf, size_t len);
 
-static bool tls_rsa_sign(struct l_tls *tls, uint8_t **out,
+static ssize_t tls_rsa_sign(struct l_tls *tls, uint8_t *out, size_t len,
 				tls_get_hash_t get_hash);
 static bool tls_rsa_verify(struct l_tls *tls, const uint8_t *in, size_t len,
 				tls_get_hash_t get_hash);
@@ -917,23 +918,25 @@ static bool tls_send_rsa_client_key_xchg(struct l_tls *tls)
 	return true;
 }
 
-static bool tls_rsa_sign(struct l_tls *tls, uint8_t **out,
+static ssize_t tls_rsa_sign(struct l_tls *tls, uint8_t *out, size_t len,
 				tls_get_hash_t get_hash)
 {
 	struct l_asymmetric_cipher *rsa_privkey;
 	uint8_t *privkey;
 	size_t key_size;
-	bool result;
+	ssize_t result;
 	const struct tls_hash_algorithm *hash_type;
 	uint8_t hash[HANDSHAKE_HASH_MAX_SIZE];
 	uint8_t sign_input[HANDSHAKE_HASH_MAX_SIZE * 2 + 32];
 	size_t sign_input_len;
+	bool prepend_hash_type = false;
+	size_t expected_bytes;
 
 	if (!tls->priv_key_path) {
 		tls_disconnect(tls, TLS_ALERT_INTERNAL_ERROR,
 				TLS_ALERT_BAD_CERT);
 
-		return false;
+		return -ENOKEY;
 	}
 
 	privkey = l_pem_load_private_key(tls->priv_key_path,
@@ -943,7 +946,7 @@ static bool tls_rsa_sign(struct l_tls *tls, uint8_t **out,
 		tls_disconnect(tls, TLS_ALERT_INTERNAL_ERROR,
 				TLS_ALERT_BAD_CERT);
 
-		return false;
+		return -ENOKEY;
 	}
 
 	rsa_privkey = l_asymmetric_cipher_new(L_CIPHER_RSA_PKCS1_V1_5,
@@ -953,10 +956,11 @@ static bool tls_rsa_sign(struct l_tls *tls, uint8_t **out,
 	if (!rsa_privkey) {
 		tls_disconnect(tls, TLS_ALERT_INTERNAL_ERROR, 0);
 
-		return false;
+		return -ENOKEY;
 	}
 
 	key_size = l_asymmetric_cipher_get_key_size(rsa_privkey);
+	expected_bytes = key_size + 2;
 
 	if (tls->negotiated_version >= TLS_V12) {
 		hash_type = &tls_handshake_hash_data[tls->signature_hash];
@@ -966,21 +970,34 @@ static bool tls_rsa_sign(struct l_tls *tls, uint8_t **out,
 					sign_input, &sign_input_len,
 					hash, hash_type->length);
 
-		*(*out)++ = hash_type->tls_id;
-		*(*out)++ = 1;	/* RSA_sign */
+		prepend_hash_type = true;
+		expected_bytes += 2;
 	} else {
 		get_hash(tls, 1, sign_input + 0, NULL, NULL);	/* MD5 */
 		get_hash(tls, 2, sign_input + 16, NULL, NULL);	/* SHA1 */
 		sign_input_len = 36;
 	}
 
-	l_put_be16(key_size, *out);
-	result = l_asymmetric_cipher_sign(rsa_privkey, sign_input, *out + 2,
-						sign_input_len, key_size);
-	*out += key_size + 2;
+	result = -EMSGSIZE;
+
+	if (len >= expected_bytes) {
+		if (prepend_hash_type) {
+			*out++ = hash_type->tls_id;
+			*out++ = 1;	/* RSA_sign */
+		}
+
+		l_put_be16(key_size, out);
+		if (l_asymmetric_cipher_sign(rsa_privkey, sign_input,
+						out + 2, sign_input_len,
+						key_size))
+			result = expected_bytes;
+	}
 
 	l_asymmetric_cipher_free(rsa_privkey);
 
+	if (result < 0)
+		tls_disconnect(tls, TLS_ALERT_INTERNAL_ERROR, 0);
+
 	return result;
 }
 
@@ -1137,13 +1154,17 @@ static bool tls_get_handshake_hash_by_id(struct l_tls *tls, uint8_t hash_id,
 static bool tls_send_certificate_verify(struct l_tls *tls)
 {
 	uint8_t buf[2048];
-	uint8_t *ptr = buf + TLS_HANDSHAKE_HEADER_SIZE;
 	int i;
+	ssize_t sign_len;
 
 	/* Fill in the Certificate Verify body */
 
-	if (!tls->pending.cipher_suite->key_xchg->sign(tls, &ptr,
-						tls_get_handshake_hash_by_id))
+	sign_len = tls->pending.cipher_suite->key_xchg->sign(tls,
+					buf + TLS_HANDSHAKE_HEADER_SIZE,
+					2048 - TLS_HANDSHAKE_HEADER_SIZE,
+					tls_get_handshake_hash_by_id);
+
+	if (sign_len < 0)
 		return false;
 
 	/* Stop maintaining handshake message hashes other than SHA256. */
@@ -1152,7 +1173,8 @@ static bool tls_send_certificate_verify(struct l_tls *tls)
 			if (i != HANDSHAKE_HASH_SHA256)
 				tls_drop_handshake_hash(tls, i);
 
-	tls_tx_handshake(tls, TLS_CERTIFICATE_VERIFY, buf, ptr - buf);
+	tls_tx_handshake(tls, TLS_CERTIFICATE_VERIFY, buf,
+				sign_len + TLS_HANDSHAKE_HEADER_SIZE);
 
 	return true;
 }
-- 
2.9.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v7 2/5] cipher: Return number of read bytes from asymmetric ops
  2016-06-20 23:53 [PATCH v7 1/5] tls: Check buffer bounds in tls_rsa_sign Mat Martineau
@ 2016-06-20 23:53 ` Mat Martineau
  2016-06-21  0:11   ` Denis Kenzior
  2016-06-20 23:53 ` [PATCH v7 3/5] unit: Check asymmetric cipher result lengths Mat Martineau
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 7+ messages in thread
From: Mat Martineau @ 2016-06-20 23:53 UTC (permalink / raw)
  To: ell

[-- Attachment #1: Type: text/plain, Size: 9103 bytes --]

When using asymmetric cipher operations, the data written to the
output buffer might be shorter than the full buffer size. The number
of bytes read is now returned from the asymmetric
encrypt/decrypt/sign/verify functions. A negative error code is
returned if the call fails.
---
 ell/cipher.c | 43 +++++++++++++++++++++++--------------------
 ell/cipher.h | 16 ++++++++--------
 ell/tls.c    | 45 +++++++++++++++++++++++----------------------
 3 files changed, 54 insertions(+), 50 deletions(-)

diff --git a/ell/cipher.c b/ell/cipher.c
index 04ef838..d04156d 100644
--- a/ell/cipher.c
+++ b/ell/cipher.c
@@ -192,7 +192,7 @@ LIB_EXPORT void l_cipher_free(struct l_cipher *cipher)
 	l_free(cipher);
 }
 
-static bool operate_cipher(int sk, __u32 operation,
+static ssize_t operate_cipher(int sk, __u32 operation,
 				const void *in, void *out, size_t len_in,
 				size_t len_out)
 {
@@ -200,6 +200,7 @@ static bool operate_cipher(int sk, __u32 operation,
 	struct msghdr msg;
 	struct cmsghdr *c_msg;
 	struct iovec iov;
+	ssize_t result;
 
 	memset(&c_msg_buf, 0, sizeof(c_msg_buf));
 	memset(&msg, 0, sizeof(msg));
@@ -219,13 +220,15 @@ static bool operate_cipher(int sk, __u32 operation,
 	msg.msg_iov = &iov;
 	msg.msg_iovlen = 1;
 
-	if (sendmsg(sk, &msg, 0) < 0)
-		return false;
+	result = sendmsg(sk, &msg, 0);
+	if (result < 0)
+		return -errno;
 
-	if (read(sk, out, len_out) < 0)
-		return false;
+	result = read(sk, out, len_out);
+	if (result < 0)
+		return -errno;
 
-	return true;
+	return result;
 }
 
 LIB_EXPORT bool l_cipher_encrypt(struct l_cipher *cipher,
@@ -238,7 +241,7 @@ LIB_EXPORT bool l_cipher_encrypt(struct l_cipher *cipher,
 		return false;
 
 	return operate_cipher(cipher->encrypt_sk, ALG_OP_ENCRYPT, in, out, len,
-				len);
+				len) >= 0;
 }
 
 LIB_EXPORT bool l_cipher_decrypt(struct l_cipher *cipher,
@@ -251,7 +254,7 @@ LIB_EXPORT bool l_cipher_decrypt(struct l_cipher *cipher,
 		return false;
 
 	return operate_cipher(cipher->decrypt_sk, ALG_OP_DECRYPT, in, out, len,
-				len);
+				len) >= 0;
 }
 
 LIB_EXPORT bool l_cipher_set_iv(struct l_cipher *cipher, const uint8_t *iv,
@@ -454,9 +457,9 @@ LIB_EXPORT int l_asymmetric_cipher_get_key_size(
 	return cipher->key_size;
 }
 
-LIB_EXPORT bool l_asymmetric_cipher_encrypt(struct l_asymmetric_cipher *cipher,
-					const void *in, void *out,
-					size_t len_in, size_t len_out)
+LIB_EXPORT ssize_t l_asymmetric_cipher_encrypt(struct l_asymmetric_cipher *cipher,
+						const void *in, void *out,
+						size_t len_in, size_t len_out)
 {
 	if (unlikely(!cipher))
 		return false;
@@ -468,9 +471,9 @@ LIB_EXPORT bool l_asymmetric_cipher_encrypt(struct l_asymmetric_cipher *cipher,
 				in, out, len_in, len_out);
 }
 
-LIB_EXPORT bool l_asymmetric_cipher_decrypt(struct l_asymmetric_cipher *cipher,
-					const void *in, void *out,
-					size_t len_in, size_t len_out)
+LIB_EXPORT ssize_t l_asymmetric_cipher_decrypt(struct l_asymmetric_cipher *cipher,
+						const void *in, void *out,
+						size_t len_in, size_t len_out)
 {
 	if (unlikely(!cipher))
 		return false;
@@ -482,9 +485,9 @@ LIB_EXPORT bool l_asymmetric_cipher_decrypt(struct l_asymmetric_cipher *cipher,
 				in, out, len_in, len_out);
 }
 
-LIB_EXPORT bool l_asymmetric_cipher_sign(struct l_asymmetric_cipher *cipher,
-					const void *in, void *out,
-					size_t len_in, size_t len_out)
+LIB_EXPORT ssize_t l_asymmetric_cipher_sign(struct l_asymmetric_cipher *cipher,
+						const void *in, void *out,
+						size_t len_in, size_t len_out)
 {
 	if (unlikely(!cipher))
 		return false;
@@ -496,9 +499,9 @@ LIB_EXPORT bool l_asymmetric_cipher_sign(struct l_asymmetric_cipher *cipher,
 				in, out, len_in, len_out);
 }
 
-LIB_EXPORT bool l_asymmetric_cipher_verify(struct l_asymmetric_cipher *cipher,
-					const void *in, void *out,
-					size_t len_in, size_t len_out)
+LIB_EXPORT ssize_t l_asymmetric_cipher_verify(struct l_asymmetric_cipher *cipher,
+						const void *in, void *out,
+						size_t len_in, size_t len_out)
 {
 	if (unlikely(!cipher))
 		return false;
diff --git a/ell/cipher.h b/ell/cipher.h
index b958804..45e51c7 100644
--- a/ell/cipher.h
+++ b/ell/cipher.h
@@ -65,21 +65,21 @@ void l_asymmetric_cipher_free(struct l_asymmetric_cipher *cipher);
 
 int l_asymmetric_cipher_get_key_size(struct l_asymmetric_cipher *cipher);
 
-bool l_asymmetric_cipher_encrypt(struct l_asymmetric_cipher *cipher,
+ssize_t l_asymmetric_cipher_encrypt(struct l_asymmetric_cipher *cipher,
 					const void *in, void *out,
 					size_t len_in, size_t len_out);
 
-bool l_asymmetric_cipher_decrypt(struct l_asymmetric_cipher *cipher,
+ssize_t l_asymmetric_cipher_decrypt(struct l_asymmetric_cipher *cipher,
 					const void *in, void *out,
 					size_t len_in, size_t len_out);
 
-bool l_asymmetric_cipher_sign(struct l_asymmetric_cipher *cipher,
-				const void *in, void *out,
-				size_t len_in, size_t len_out);
+ssize_t l_asymmetric_cipher_sign(struct l_asymmetric_cipher *cipher,
+					const void *in, void *out,
+					size_t len_in, size_t len_out);
 
-bool l_asymmetric_cipher_verify(struct l_asymmetric_cipher *cipher,
-				const void *in, void *out,
-				size_t len_in, size_t len_out);
+ssize_t l_asymmetric_cipher_verify(struct l_asymmetric_cipher *cipher,
+					const void *in, void *out,
+					size_t len_in, size_t len_out);
 
 #ifdef __cplusplus
 }
diff --git a/ell/tls.c b/ell/tls.c
index 3bd7d7d..18e5fae 100644
--- a/ell/tls.c
+++ b/ell/tls.c
@@ -862,7 +862,7 @@ static bool tls_send_rsa_client_key_xchg(struct l_tls *tls)
 	uint8_t pre_master_secret[48];
 	struct l_asymmetric_cipher *rsa_server_pubkey;
 	int key_size;
-	bool result;
+	ssize_t bytes_encrypted;
 
 	if (!tls->peer_pubkey) {
 		tls_disconnect(tls, TLS_ALERT_INTERNAL_ERROR, 0);
@@ -897,14 +897,14 @@ static bool tls_send_rsa_client_key_xchg(struct l_tls *tls)
 	}
 
 	l_put_be16(key_size, ptr);
-	result = l_asymmetric_cipher_encrypt(rsa_server_pubkey,
-						pre_master_secret, ptr + 2,
-						48, key_size);
+	bytes_encrypted = l_asymmetric_cipher_encrypt(rsa_server_pubkey,
+							pre_master_secret,
+							ptr + 2, 48, key_size);
 	ptr += key_size + 2;
 
 	l_asymmetric_cipher_free(rsa_server_pubkey);
 
-	if (!result) {
+	if (bytes_encrypted != key_size) {
 		tls_disconnect(tls, TLS_ALERT_INTERNAL_ERROR, 0);
 
 		return false;
@@ -987,9 +987,11 @@ static ssize_t tls_rsa_sign(struct l_tls *tls, uint8_t *out, size_t len,
 		}
 
 		l_put_be16(key_size, out);
-		if (l_asymmetric_cipher_sign(rsa_privkey, sign_input,
-						out + 2, sign_input_len,
-						key_size))
+		result = l_asymmetric_cipher_sign(rsa_privkey, sign_input,
+							out + 2, sign_input_len,
+							key_size);
+
+		if (result == (ssize_t) key_size)
 			result = expected_bytes;
 	}
 
@@ -1006,7 +1008,7 @@ static bool tls_rsa_verify(struct l_tls *tls, const uint8_t *in, size_t len,
 {
 	struct l_asymmetric_cipher *rsa_client_pubkey;
 	size_t key_size;
-	bool result;
+	ssize_t verify_bytes;
 	uint8_t hash[HANDSHAKE_HASH_MAX_SIZE];
 	size_t hash_len;
 	enum l_checksum_type hash_type;
@@ -1089,18 +1091,16 @@ static bool tls_rsa_verify(struct l_tls *tls, const uint8_t *in, size_t len,
 		 */
 	}
 
-	if (expected_len > key_size)
-		goto err_free_rsa;
-
-	digest_info = alloca(key_size);
+	digest_info = alloca(expected_len);
 
-	result = l_asymmetric_cipher_verify(rsa_client_pubkey, in + 4,
-						digest_info,
-						key_size, key_size);
+	verify_bytes = l_asymmetric_cipher_verify(rsa_client_pubkey, in + 4,
+							digest_info, key_size,
+							expected_len);
 
 	l_asymmetric_cipher_free(rsa_client_pubkey);
 
-	if (!result || memcmp(digest_info, expected, expected_len)) {
+	if (verify_bytes != (ssize_t)expected_len ||
+		memcmp(digest_info, expected, expected_len)) {
 		tls_disconnect(tls, TLS_ALERT_DECRYPT_ERROR, 0);
 
 		return false;
@@ -1762,7 +1762,7 @@ static void tls_handle_rsa_client_key_xchg(struct l_tls *tls,
 	struct l_asymmetric_cipher *rsa_server_privkey;
 	uint8_t *privkey;
 	size_t key_size;
-	bool result;
+	ssize_t bytes_decrypted;
 
 	if (!tls->priv_key_path) {
 		tls_disconnect(tls, TLS_ALERT_INTERNAL_ERROR,
@@ -1812,9 +1812,10 @@ static void tls_handle_rsa_client_key_xchg(struct l_tls *tls,
 		return;
 	}
 
-	result = l_asymmetric_cipher_decrypt(rsa_server_privkey, buf + 2,
-						pre_master_secret,
-						key_size, 48);
+	bytes_decrypted = l_asymmetric_cipher_decrypt(rsa_server_privkey,
+							buf + 2,
+							pre_master_secret,
+							key_size, 48);
 	l_asymmetric_cipher_free(rsa_server_privkey);
 
 	/*
@@ -1832,7 +1833,7 @@ static void tls_handle_rsa_client_key_xchg(struct l_tls *tls,
 	pre_master_secret[0] = tls->client_version >> 8;
 	pre_master_secret[1] = tls->client_version >> 0;
 
-	if (!result)
+	if (bytes_decrypted != 48)
 		memcpy(pre_master_secret + 2, random_secret, 46);
 
 	tls_generate_master_secret(tls, pre_master_secret, 48);
-- 
2.9.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v7 3/5] unit: Check asymmetric cipher result lengths
  2016-06-20 23:53 [PATCH v7 1/5] tls: Check buffer bounds in tls_rsa_sign Mat Martineau
  2016-06-20 23:53 ` [PATCH v7 2/5] cipher: Return number of read bytes from asymmetric ops Mat Martineau
@ 2016-06-20 23:53 ` Mat Martineau
  2016-06-20 23:53 ` [PATCH v7 4/5] unit: Check decryption against known ciphertext Mat Martineau
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Mat Martineau @ 2016-06-20 23:53 UTC (permalink / raw)
  To: ell

[-- Attachment #1: Type: text/plain, Size: 992 bytes --]

---
 unit/test-cipher.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/unit/test-cipher.c b/unit/test-cipher.c
index 78d1fcb..8c27d03 100644
--- a/unit/test-cipher.c
+++ b/unit/test-cipher.c
@@ -184,16 +184,20 @@ static void test_rsa(const void *data)
 {
 	struct l_asymmetric_cipher *cipher;
 	char buf[128];
+	ssize_t encrypted, decrypted;
 
 	cipher = l_asymmetric_cipher_new(L_CIPHER_RSA_PKCS1_V1_5,
 						rsa_priv_key,
 						sizeof(rsa_priv_key), false);
 	assert(cipher);
-	assert(l_asymmetric_cipher_encrypt(cipher, FIXED_STR, buf, 100, 128));
+	encrypted = l_asymmetric_cipher_encrypt(cipher, FIXED_STR, buf,
+						100, 128);
+	assert(encrypted == 128);
 
 	assert(memcmp(FIXED_STR, buf, 100));
 
-	assert(l_asymmetric_cipher_decrypt(cipher, buf, buf, 128, 128));
+	decrypted = l_asymmetric_cipher_decrypt(cipher, buf, buf, 128, 128);
+	assert(decrypted == 100);
 
 	assert(!memcmp(FIXED_STR, buf, 100));
 
-- 
2.9.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v7 4/5] unit: Check decryption against known ciphertext
  2016-06-20 23:53 [PATCH v7 1/5] tls: Check buffer bounds in tls_rsa_sign Mat Martineau
  2016-06-20 23:53 ` [PATCH v7 2/5] cipher: Return number of read bytes from asymmetric ops Mat Martineau
  2016-06-20 23:53 ` [PATCH v7 3/5] unit: Check asymmetric cipher result lengths Mat Martineau
@ 2016-06-20 23:53 ` Mat Martineau
  2016-06-20 23:53 ` [PATCH v7 5/5] cipher: Use only one socket for asymmetric cipher Mat Martineau
  2016-06-21  0:02 ` [PATCH v7 1/5] tls: Check buffer bounds in tls_rsa_sign Denis Kenzior
  4 siblings, 0 replies; 7+ messages in thread
From: Mat Martineau @ 2016-06-20 23:53 UTC (permalink / raw)
  To: ell

[-- Attachment #1: Type: text/plain, Size: 2499 bytes --]

Include known-good ciphertext and make sure it can be correctly
decrypted. Also confirm that corrupted ciphertext triggers a
decryption error.
---
 unit/test-cipher.c | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/unit/test-cipher.c b/unit/test-cipher.c
index 8c27d03..12a922a 100644
--- a/unit/test-cipher.c
+++ b/unit/test-cipher.c
@@ -180,6 +180,29 @@ static uint8_t rsa_priv_key[] = {
 	0x05, 0x3e, 0x55, 0x14, 0xd9, 0xe4, 0xa4, 0x7f, 0xb7, 0x4f
 };
 
+/* Reference ciphertext:
+ * $ openssl rsautl -in fixed_str -inkey privkey.der -keyform DER -encrypt \
+ * > -pkcs -out ciphertext
+ * $ xxd -i ciphertext
+ *
+ * where fixed_str is a file containing the first 100 characters of
+ * FIXED_STR (above) and privkey.der contains the binary data from the
+ * rsa_priv_key array.
+ */
+static uint8_t ciphertext[128] = {
+	0x50, 0x86, 0x87, 0x72, 0x37, 0xc1, 0xc7, 0x99, 0xa9, 0xff, 0x56, 0x92,
+	0x9b, 0x8a, 0xf6, 0x31, 0x9b, 0x11, 0x2c, 0x27, 0x1c, 0xa9, 0x07, 0x9b,
+	0xac, 0xb9, 0x31, 0xcd, 0xc1, 0x10, 0x90, 0xd7, 0x3c, 0xa1, 0x43, 0xa1,
+	0xdb, 0xb2, 0x67, 0x48, 0x28, 0xac, 0x0e, 0xbd, 0xd4, 0x62, 0x6b, 0xbd,
+	0x81, 0xf9, 0x5b, 0xd0, 0x29, 0xe5, 0xc8, 0x9a, 0x71, 0x69, 0xd1, 0x61,
+	0x72, 0x95, 0xa5, 0x10, 0x83, 0xee, 0xb4, 0x6d, 0x79, 0xf8, 0xae, 0xe1,
+	0x49, 0xdd, 0x5b, 0x1f, 0x4d, 0x2e, 0xd7, 0xa9, 0xf0, 0xf0, 0x81, 0x01,
+	0x38, 0x58, 0x78, 0x0f, 0x89, 0x3d, 0x60, 0xdb, 0x99, 0x19, 0xb0, 0x14,
+	0x9d, 0xf7, 0xc8, 0x6e, 0xc3, 0x69, 0xdd, 0xb2, 0xcc, 0x07, 0x32, 0x3b,
+	0x88, 0xd3, 0xfa, 0x72, 0xe9, 0xaa, 0x66, 0xc5, 0xd3, 0x4a, 0xff, 0x87,
+	0x6a, 0x78, 0x05, 0x2d, 0x16, 0x7c, 0x98, 0x58
+};
+
 static void test_rsa(const void *data)
 {
 	struct l_asymmetric_cipher *cipher;
@@ -198,9 +221,22 @@ static void test_rsa(const void *data)
 
 	decrypted = l_asymmetric_cipher_decrypt(cipher, buf, buf, 128, 128);
 	assert(decrypted == 100);
+	assert(!memcmp(FIXED_STR, buf, 100));
 
+	/* Decrypt reference ciphertext */
+	memset(buf, 0, 128);
+	decrypted = l_asymmetric_cipher_decrypt(cipher, ciphertext, buf,
+						128, 128);
+	assert(decrypted == 100);
 	assert(!memcmp(FIXED_STR, buf, 100));
 
+	/* Decrypt corrupted ciphertext */
+	ciphertext[0] = ciphertext[0] ^ (uint8_t)0xFF;
+	memset(buf, 0, 128);
+	decrypted = l_asymmetric_cipher_decrypt(cipher, ciphertext, buf,
+						128, 128);
+	assert(decrypted < 0);
+
 	l_asymmetric_cipher_free(cipher);
 }
 
-- 
2.9.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v7 5/5] cipher: Use only one socket for asymmetric cipher
  2016-06-20 23:53 [PATCH v7 1/5] tls: Check buffer bounds in tls_rsa_sign Mat Martineau
                   ` (2 preceding siblings ...)
  2016-06-20 23:53 ` [PATCH v7 4/5] unit: Check decryption against known ciphertext Mat Martineau
@ 2016-06-20 23:53 ` Mat Martineau
  2016-06-21  0:02 ` [PATCH v7 1/5] tls: Check buffer bounds in tls_rsa_sign Denis Kenzior
  4 siblings, 0 replies; 7+ messages in thread
From: Mat Martineau @ 2016-06-20 23:53 UTC (permalink / raw)
  To: ell

[-- Attachment #1: Type: text/plain, Size: 3355 bytes --]

---
 ell/cipher.c | 40 +++++++++++++++-------------------------
 1 file changed, 15 insertions(+), 25 deletions(-)

diff --git a/ell/cipher.c b/ell/cipher.c
index d04156d..daa2c2b 100644
--- a/ell/cipher.c
+++ b/ell/cipher.c
@@ -294,7 +294,8 @@ LIB_EXPORT bool l_cipher_set_iv(struct l_cipher *cipher, const uint8_t *iv,
 }
 
 struct l_asymmetric_cipher {
-	struct l_cipher cipher;
+	int type;
+	int sk;
 	int key_size;
 };
 
@@ -407,7 +408,7 @@ LIB_EXPORT struct l_asymmetric_cipher *l_asymmetric_cipher_new(
 		return NULL;
 
 	cipher = l_new(struct l_asymmetric_cipher, 1);
-	cipher->cipher.type = type;
+	cipher->type = type;
 
 	switch (type) {
 	case L_CIPHER_RSA_PKCS1_V1_5:
@@ -418,23 +419,13 @@ LIB_EXPORT struct l_asymmetric_cipher *l_asymmetric_cipher_new(
 		break;
 	}
 
-	cipher->cipher.encrypt_sk = create_alg("akcipher", alg_name,
-						key, key_length, public_key);
-	if (cipher->cipher.encrypt_sk < 0)
+	cipher->sk = create_alg("akcipher", alg_name, key, key_length,
+				public_key);
+	if (cipher->sk < 0)
 		goto error_free;
 
-	if (public_key) {
-		cipher->cipher.decrypt_sk = create_alg("akcipher", alg_name,
-							key, key_length,
-							public_key);
-		if (cipher->cipher.decrypt_sk < 0)
-			goto error_close;
-	}
-
 	return cipher;
 
-error_close:
-	close(cipher->cipher.encrypt_sk);
 error_free:
 	l_free(cipher);
 	return NULL;
@@ -445,8 +436,7 @@ LIB_EXPORT void l_asymmetric_cipher_free(struct l_asymmetric_cipher *cipher)
 	if (unlikely(!cipher))
 		return;
 
-	close(cipher->cipher.encrypt_sk);
-	close(cipher->cipher.decrypt_sk);
+	close(cipher->sk);
 
 	l_free(cipher);
 }
@@ -467,8 +457,8 @@ LIB_EXPORT ssize_t l_asymmetric_cipher_encrypt(struct l_asymmetric_cipher *ciphe
 	if (unlikely(!in) || unlikely(!out))
 		return false;
 
-	return operate_cipher(cipher->cipher.encrypt_sk, ALG_OP_ENCRYPT,
-				in, out, len_in, len_out);
+	return operate_cipher(cipher->sk, ALG_OP_ENCRYPT, in, out, len_in,
+				len_out);
 }
 
 LIB_EXPORT ssize_t l_asymmetric_cipher_decrypt(struct l_asymmetric_cipher *cipher,
@@ -481,8 +471,8 @@ LIB_EXPORT ssize_t l_asymmetric_cipher_decrypt(struct l_asymmetric_cipher *ciphe
 	if (unlikely(!in) || unlikely(!out))
 		return false;
 
-	return operate_cipher(cipher->cipher.decrypt_sk, ALG_OP_DECRYPT,
-				in, out, len_in, len_out);
+	return operate_cipher(cipher->sk, ALG_OP_DECRYPT, in, out, len_in,
+				len_out);
 }
 
 LIB_EXPORT ssize_t l_asymmetric_cipher_sign(struct l_asymmetric_cipher *cipher,
@@ -495,8 +485,8 @@ LIB_EXPORT ssize_t l_asymmetric_cipher_sign(struct l_asymmetric_cipher *cipher,
 	if (unlikely(!in) || unlikely(!out))
 		return false;
 
-	return operate_cipher(cipher->cipher.decrypt_sk, ALG_OP_SIGN,
-				in, out, len_in, len_out);
+	return operate_cipher(cipher->sk, ALG_OP_SIGN, in, out, len_in,
+				len_out);
 }
 
 LIB_EXPORT ssize_t l_asymmetric_cipher_verify(struct l_asymmetric_cipher *cipher,
@@ -509,6 +499,6 @@ LIB_EXPORT ssize_t l_asymmetric_cipher_verify(struct l_asymmetric_cipher *cipher
 	if (unlikely(!in) || unlikely(!out))
 		return false;
 
-	return operate_cipher(cipher->cipher.encrypt_sk, ALG_OP_VERIFY,
-				in, out, len_in, len_out);
+	return operate_cipher(cipher->sk, ALG_OP_VERIFY, in, out, len_in,
+				len_out);
 }
-- 
2.9.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v7 1/5] tls: Check buffer bounds in tls_rsa_sign
  2016-06-20 23:53 [PATCH v7 1/5] tls: Check buffer bounds in tls_rsa_sign Mat Martineau
                   ` (3 preceding siblings ...)
  2016-06-20 23:53 ` [PATCH v7 5/5] cipher: Use only one socket for asymmetric cipher Mat Martineau
@ 2016-06-21  0:02 ` Denis Kenzior
  4 siblings, 0 replies; 7+ messages in thread
From: Denis Kenzior @ 2016-06-21  0:02 UTC (permalink / raw)
  To: ell

[-- Attachment #1: Type: text/plain, Size: 279 bytes --]

Hi Mat,

On 06/20/2016 06:53 PM, Mat Martineau wrote:
> ---
>   ell/tls-private.h |  2 +-
>   ell/tls.c         | 54 ++++++++++++++++++++++++++++++++++++++----------------
>   2 files changed, 39 insertions(+), 17 deletions(-)
>

Applied, thanks.

Regards,
-Denis


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v7 2/5] cipher: Return number of read bytes from asymmetric ops
  2016-06-20 23:53 ` [PATCH v7 2/5] cipher: Return number of read bytes from asymmetric ops Mat Martineau
@ 2016-06-21  0:11   ` Denis Kenzior
  0 siblings, 0 replies; 7+ messages in thread
From: Denis Kenzior @ 2016-06-21  0:11 UTC (permalink / raw)
  To: ell

[-- Attachment #1: Type: text/plain, Size: 644 bytes --]

Hi Mat,

On 06/20/2016 06:53 PM, Mat Martineau wrote:
> When using asymmetric cipher operations, the data written to the
> output buffer might be shorter than the full buffer size. The number
> of bytes read is now returned from the asymmetric
> encrypt/decrypt/sign/verify functions. A negative error code is
> returned if the call fails.
> ---
>   ell/cipher.c | 43 +++++++++++++++++++++++--------------------
>   ell/cipher.h | 16 ++++++++--------
>   ell/tls.c    | 45 +++++++++++++++++++++++----------------------
>   3 files changed, 54 insertions(+), 50 deletions(-)
>

Patches 2-5 applied, thanks.

Regards,
-Denis


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2016-06-21  0:11 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-20 23:53 [PATCH v7 1/5] tls: Check buffer bounds in tls_rsa_sign Mat Martineau
2016-06-20 23:53 ` [PATCH v7 2/5] cipher: Return number of read bytes from asymmetric ops Mat Martineau
2016-06-21  0:11   ` Denis Kenzior
2016-06-20 23:53 ` [PATCH v7 3/5] unit: Check asymmetric cipher result lengths Mat Martineau
2016-06-20 23:53 ` [PATCH v7 4/5] unit: Check decryption against known ciphertext Mat Martineau
2016-06-20 23:53 ` [PATCH v7 5/5] cipher: Use only one socket for asymmetric cipher Mat Martineau
2016-06-21  0:02 ` [PATCH v7 1/5] tls: Check buffer bounds in tls_rsa_sign Denis Kenzior

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.