All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 1/4] unit: Rename asymmetric key type to L_KEY_RSA
@ 2016-08-01 21:25 Mat Martineau
  2016-08-01 21:25 ` [PATCH v3 2/4] checksum: Add L_CHECKSUM_NONE, needed for key crypto Mat Martineau
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Mat Martineau @ 2016-08-01 21:25 UTC (permalink / raw)
  To: ell

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

---
 unit/test-key.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/unit/test-key.c b/unit/test-key.c
index d52ae1b..7f5124f 100644
--- a/unit/test-key.c
+++ b/unit/test-key.c
@@ -375,9 +375,9 @@ static void test_trusted_keyring(const void *data)
 					&certlen);
 	assert(cert);
 
-	cakey = l_key_new(L_KEY_ASYMMETRIC, cacert, cacertlen);
+	cakey = l_key_new(L_KEY_RSA, cacert, cacertlen);
 	assert(cakey);
-	key = l_key_new(L_KEY_ASYMMETRIC, cert, certlen);
+	key = l_key_new(L_KEY_RSA, cert, certlen);
 	assert(key);
 
 	trust = l_keyring_new(L_KEYRING_SIMPLE, NULL);
-- 
2.9.2


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

* [PATCH v3 2/4] checksum: Add L_CHECKSUM_NONE, needed for key crypto
  2016-08-01 21:25 [PATCH v3 1/4] unit: Rename asymmetric key type to L_KEY_RSA Mat Martineau
@ 2016-08-01 21:25 ` Mat Martineau
  2016-08-01 21:25 ` [PATCH v3 3/4] key: Add key-based asymmetric crypto operations Mat Martineau
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Mat Martineau @ 2016-08-01 21:25 UTC (permalink / raw)
  To: ell

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

---
 ell/checksum.c | 8 ++++++--
 ell/checksum.h | 1 +
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/ell/checksum.c b/ell/checksum.c
index 7b0e3ee..68be73f 100644
--- a/ell/checksum.c
+++ b/ell/checksum.c
@@ -124,9 +124,9 @@ LIB_EXPORT struct l_checksum *l_checksum_new(enum l_checksum_type type)
 	if (!is_valid_type(type))
 		return NULL;
 
-	checksum = l_new(struct l_checksum, 1);
-
 	switch (type) {
+	case L_CHECKSUM_NONE:
+		return NULL;
 	case L_CHECKSUM_MD5:
 		name = "md5";
 		break;
@@ -144,6 +144,8 @@ LIB_EXPORT struct l_checksum *l_checksum_new(enum l_checksum_type type)
 		break;
 	}
 
+	checksum = l_new(struct l_checksum, 1);
+
 	fd = create_alg(name);
 	if (fd < 0)
 		goto error;
@@ -202,6 +204,8 @@ struct l_checksum *l_checksum_new_hmac(enum l_checksum_type type,
 		return NULL;
 
 	switch (type) {
+	case L_CHECKSUM_NONE:
+		return NULL;
 	case L_CHECKSUM_MD5:
 		name = "hmac(md5)";
 		break;
diff --git a/ell/checksum.h b/ell/checksum.h
index 34401a6..e6eceb9 100644
--- a/ell/checksum.h
+++ b/ell/checksum.h
@@ -32,6 +32,7 @@ extern "C" {
 struct l_checksum;
 
 enum l_checksum_type {
+	L_CHECKSUM_NONE,
 	L_CHECKSUM_MD5,
 	L_CHECKSUM_SHA1,
 	L_CHECKSUM_SHA256,
-- 
2.9.2


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

* [PATCH v3 3/4] key: Add key-based asymmetric crypto operations
  2016-08-01 21:25 [PATCH v3 1/4] unit: Rename asymmetric key type to L_KEY_RSA Mat Martineau
  2016-08-01 21:25 ` [PATCH v3 2/4] checksum: Add L_CHECKSUM_NONE, needed for key crypto Mat Martineau
@ 2016-08-01 21:25 ` Mat Martineau
  2016-08-01 21:25 ` [PATCH v3 4/4] unit: Add tests for key-based asymmetric crypto Mat Martineau
  2016-08-01 21:40 ` [PATCH v3 1/4] unit: Rename asymmetric key type to L_KEY_RSA Denis Kenzior
  3 siblings, 0 replies; 5+ messages in thread
From: Mat Martineau @ 2016-08-01 21:25 UTC (permalink / raw)
  To: ell

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

The kernel has asymmetric crypto methods available using the keyctl API
which make use of the kernel keyrings. The main advantage of this API
over AF_ALG is that typical asymmetric operations involve fewer system
calls.
---
 ell/key.c | 216 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 ell/key.h |  23 +++++++
 2 files changed, 239 insertions(+)

diff --git a/ell/key.c b/ell/key.c
index 7dad4a7..669d257 100644
--- a/ell/key.c
+++ b/ell/key.c
@@ -34,6 +34,7 @@
 #include "private.h"
 #include "util.h"
 #include "key.h"
+#include "string.h"
 
 #ifndef KEYCTL_DH_COMPUTE
 #define KEYCTL_DH_COMPUTE 23
@@ -45,6 +46,40 @@ struct keyctl_dh_params {
 };
 #endif
 
+#ifndef KEYCTL_PKEY_QUERY
+#define KEYCTL_PKEY_QUERY	24
+#define KEYCTL_PKEY_ENCRYPT	25
+#define KEYCTL_PKEY_DECRYPT	26
+#define KEYCTL_PKEY_SIGN	27
+#define KEYCTL_PKEY_VERIFY	28
+
+#define KEYCTL_SUPPORTS_ENCRYPT	0x01
+#define KEYCTL_SUPPORTS_DECRYPT	0x02
+#define KEYCTL_SUPPORTS_SIGN	0x04
+#define KEYCTL_SUPPORTS_VERIFY	0x08
+
+struct keyctl_pkey_query {
+	uint32_t supported_ops;
+	uint32_t key_size;
+	uint16_t max_data_size;
+	uint16_t max_sig_size;
+	uint16_t max_enc_size;
+	uint16_t max_dec_size;
+
+	uint32_t __spare[10];
+};
+
+struct keyctl_pkey_params {
+	int32_t key_id;
+	uint32_t in_len;
+	union {
+		uint32_t out_len;
+		uint32_t in2_len;
+	};
+	uint32_t __spare[7];
+};
+#endif
+
 static int32_t internal_keyring;
 
 struct l_key {
@@ -118,6 +153,43 @@ static long kernel_unlink_key(int32_t key_serial, int32_t ring_serial)
 	return result >= 0 ? result : -errno;
 }
 
+static char *format_key_info(const char *encoding, const char *hash)
+{
+	struct l_string *info;
+
+	if (!encoding && !hash)
+		return NULL;
+
+	info = l_string_new(0);
+
+	if (encoding)
+		l_string_append_printf(info, "enc=%s ", encoding);
+
+	if (hash)
+		l_string_append_printf(info, "hash=%s", hash);
+
+	return l_string_free(info, false);
+}
+
+static long kernel_query_key(int32_t key_serial, const char *encoding,
+				const char *hash, size_t *size, bool *public)
+{
+	long result;
+	struct keyctl_pkey_query query;
+	char *info = format_key_info(encoding, hash);
+
+	result = syscall(__NR_keyctl, KEYCTL_PKEY_QUERY, key_serial, 0,
+				info ?: "", &query);
+	if (result == 0) {
+		*size = query.key_size;
+		*public = ((query.supported_ops & KEYCTL_SUPPORTS_ENCRYPT) &&
+			!(query.supported_ops & KEYCTL_SUPPORTS_DECRYPT));
+	}
+	l_free(info);
+
+	return result >= 0 ? result : -errno;
+}
+
 static long kernel_dh_compute(int32_t private, int32_t prime, int32_t base,
 			      void *payload, size_t len)
 {
@@ -133,6 +205,40 @@ static long kernel_dh_compute(int32_t private, int32_t prime, int32_t base,
 	return result >= 0 ? result : -errno;
 }
 
+static long kernel_key_eds(int op, int32_t serial, const char *encoding,
+				const char *hash, const void *in, void *out,
+				size_t len_in, size_t len_out)
+{
+	long result;
+	struct keyctl_pkey_params params = { .key_id = serial,
+					     .in_len = len_in,
+					     .out_len = len_out };
+	char *info = format_key_info(encoding, hash);
+
+	result = syscall(__NR_keyctl, op, &params, info ?: "", in, out);
+	l_free(info);
+
+	return result >= 0 ? result : -errno;
+}
+
+static long kernel_key_verify(int32_t serial, const char *encoding,
+				const char *hash, const void *data,
+				const void *sig, size_t len_data,
+				size_t len_sig)
+{
+	long result;
+	struct keyctl_pkey_params params = { .key_id = serial,
+					     .in_len = len_data,
+					     .in2_len = len_sig };
+	char *info = format_key_info(encoding, hash);
+
+	result = syscall(__NR_keyctl, KEYCTL_PKEY_VERIFY, &params, info ?: "",
+				data, sig);
+	l_free(info);
+
+	return result >= 0 ? result : -errno;
+}
+
 static bool setup_internal_keyring(void)
 {
 	internal_keyring = kernel_add_key("keyring", "ell-internal", NULL, 0,
@@ -228,6 +334,54 @@ LIB_EXPORT ssize_t l_key_get_payload_size(struct l_key *key)
 	return kernel_read_key(key->serial, NULL, 0);
 }
 
+static const char *lookup_cipher(enum l_asymmetric_cipher_type cipher)
+{
+	const char* ret = NULL;
+
+	switch (cipher) {
+	case L_CIPHER_RSA_PKCS1_V1_5:
+		ret = "pkcs1";
+		break;
+	}
+
+	return ret;
+}
+
+static const char *lookup_checksum(enum l_checksum_type checksum)
+{
+	const char* ret = NULL;
+
+	switch (checksum) {
+	case L_CHECKSUM_NONE:
+		break;
+	case L_CHECKSUM_MD5:
+		ret = "md5";
+		break;
+	case L_CHECKSUM_SHA1:
+		ret = "sha1";
+		break;
+	case L_CHECKSUM_SHA256:
+		ret = "sha256";
+		break;
+	case L_CHECKSUM_SHA384:
+		ret = "sha384";
+		break;
+	case L_CHECKSUM_SHA512:
+		ret = "sha512";
+		break;
+	}
+
+	return ret;
+}
+
+bool l_key_get_info(struct l_key *key, enum l_asymmetric_cipher_type cipher,
+			enum l_checksum_type hash, size_t *bits,
+			bool *public)
+{
+	return !kernel_query_key(key->serial, lookup_cipher(cipher),
+					lookup_checksum(hash), bits, public);
+}
+
 static bool compute_common(struct l_key *base,
 			   struct l_key *private,
 			   struct l_key *prime,
@@ -263,6 +417,68 @@ LIB_EXPORT bool l_key_compute_dh_secret(struct l_key *other_public,
 	return compute_common(other_public, private, prime, payload, len);
 }
 
+/* Common code for encrypt/decrypt/sign */
+static ssize_t eds_common(struct l_key *key,
+				enum l_asymmetric_cipher_type cipher,
+				enum l_checksum_type checksum, const void *in,
+				void *out, size_t len_in, size_t len_out,
+				int op)
+{
+	if (unlikely(!key))
+		return -EINVAL;
+
+	return kernel_key_eds(op, key->serial, lookup_cipher(cipher),
+				lookup_checksum(checksum), in, out, len_in,
+				len_out);
+}
+
+LIB_EXPORT ssize_t l_key_encrypt(struct l_key *key,
+					enum l_asymmetric_cipher_type cipher,
+					enum l_checksum_type checksum,
+					const void *in, void *out,
+					size_t len_in, size_t len_out)
+{
+	return eds_common(key, cipher, checksum, in, out, len_in, len_out,
+				KEYCTL_PKEY_ENCRYPT);
+}
+
+LIB_EXPORT ssize_t l_key_decrypt(struct l_key *key,
+					enum l_asymmetric_cipher_type cipher,
+					enum l_checksum_type checksum,
+					const void *in, void *out,
+					size_t len_in, size_t len_out)
+{
+	return eds_common(key, cipher, checksum, in, out, len_in, len_out,
+				KEYCTL_PKEY_DECRYPT);
+}
+
+LIB_EXPORT ssize_t l_key_sign(struct l_key *key,
+				enum l_asymmetric_cipher_type cipher,
+				enum l_checksum_type checksum, const void *in,
+				void *out, size_t len_in, size_t len_out)
+{
+	return eds_common(key, cipher, checksum, in, out, len_in, len_out,
+				KEYCTL_PKEY_SIGN);
+}
+
+LIB_EXPORT bool l_key_verify(struct l_key *key,
+				enum l_asymmetric_cipher_type cipher,
+				enum l_checksum_type checksum, const void *data,
+				const void *sig, size_t len_data,
+				size_t len_sig)
+{
+	long result;
+
+	if (unlikely(!key))
+		return false;
+
+	result = kernel_key_verify(key->serial, lookup_cipher(cipher),
+					lookup_checksum(checksum), data, sig,
+					len_data, len_sig);
+
+	return result == 0;
+}
+
 LIB_EXPORT struct l_keyring *l_keyring_new(enum l_keyring_type type,
 						const struct l_keyring *trusted)
 {
diff --git a/ell/key.h b/ell/key.h
index a0b4b64..9cc69ff 100644
--- a/ell/key.h
+++ b/ell/key.h
@@ -30,6 +30,9 @@ extern "C" {
 #include <stddef.h>
 #include <stdbool.h>
 
+#include <ell/checksum.h>
+#include <ell/cipher.h>
+
 struct l_key;
 struct l_keyring;
 
@@ -54,12 +57,32 @@ bool l_key_extract(struct l_key *key, void *payload, size_t *len);
 
 ssize_t l_key_get_payload_size(struct l_key *key);
 
+bool l_key_get_info(struct l_key *key, enum l_asymmetric_cipher_type cipher,
+			enum l_checksum_type checksum, size_t *bits,
+			bool *public);
+
 bool l_key_compute_dh_public(struct l_key *generator, struct l_key *private,
 			     struct l_key *prime, void *payload, size_t *len);
 
 bool l_key_compute_dh_secret(struct l_key *other_public, struct l_key *private,
 			     struct l_key *prime, void *payload, size_t *len);
 
+ssize_t l_key_encrypt(struct l_key *key, enum l_asymmetric_cipher_type cipher,
+			enum l_checksum_type checksum, const void *in,
+			void *out, size_t len_in, size_t len_out);
+
+ssize_t l_key_decrypt(struct l_key *key, enum l_asymmetric_cipher_type cipher,
+			enum l_checksum_type checksum, const void *in,
+			void *out, size_t len_in, size_t len_out);
+
+ssize_t l_key_sign(struct l_key *key, enum l_asymmetric_cipher_type cipher,
+			enum l_checksum_type checksum, const void *in,
+			void *out, size_t len_in, size_t len_out);
+
+bool l_key_verify(struct l_key *key, enum l_asymmetric_cipher_type cipher,
+			enum l_checksum_type checksum, const void *data,
+			const void *sig, size_t len_data, size_t len_sig);
+
 struct l_keyring *l_keyring_new(enum l_keyring_type type,
 				const struct l_keyring *trust);
 
-- 
2.9.2


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

* [PATCH v3 4/4] unit: Add tests for key-based asymmetric crypto
  2016-08-01 21:25 [PATCH v3 1/4] unit: Rename asymmetric key type to L_KEY_RSA Mat Martineau
  2016-08-01 21:25 ` [PATCH v3 2/4] checksum: Add L_CHECKSUM_NONE, needed for key crypto Mat Martineau
  2016-08-01 21:25 ` [PATCH v3 3/4] key: Add key-based asymmetric crypto operations Mat Martineau
@ 2016-08-01 21:25 ` Mat Martineau
  2016-08-01 21:40 ` [PATCH v3 1/4] unit: Rename asymmetric key type to L_KEY_RSA Denis Kenzior
  3 siblings, 0 replies; 5+ messages in thread
From: Mat Martineau @ 2016-08-01 21:25 UTC (permalink / raw)
  To: ell

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

---
 unit/cert-client-key-pkcs8.pem |  28 ++++++
 unit/gencerts.sh               |   1 +
 unit/test-key.c                | 194 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 223 insertions(+)
 create mode 100644 unit/cert-client-key-pkcs8.pem

diff --git a/unit/cert-client-key-pkcs8.pem b/unit/cert-client-key-pkcs8.pem
new file mode 100644
index 0000000..738b825
--- /dev/null
+++ b/unit/cert-client-key-pkcs8.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDhOQ/5VIWkwt8S
+9vNbbWT0VEV5Siai8HBxl0ErkJusMGFrQIS8jCxB668hNKAoSncN3lezZ/yDg8b5
+NUvLiLinx1rjXeal/8ruwowlr8optgkiRxduK0BZm/Xj6HXTmZwzDACM+zwt9uSV
+YW6/y0gS26oWdLJh8tRysq88xx8ylOGHEx/9/tx+DB2cJzWX23xuaoUWRjbrv/Lf
+gFlXBKHD0RmGac1iTaugAM6IwB0kjscYrHATIrkPgXaHz8PV4cKUvhbLZK7xfCfR
+X2Y+VNxTpvxIDkJ/Hn561C9t9T6gdUfTyCmL//d/Kd4gzCItBE4iouXHnVlfJtj3
+MpD3TTijAgMBAAECggEBAIbg9YAL7j1NtupUmkkWqm7oSPLqRVkvRSfBvXWplJD6
+KF1itht0lsyjqK3qJj/62HGlxj/a9o6MTIzSLiImLu/Lo9KmWYrwNUfnmqa3MArq
+yW2NxapknJUNoaRrgqTGSZUIiwvjKZcdVKdhQkH6K5+fja0FFg8yrahC+k8bsMNI
+5mw8NwRdR3SvHJWHCLfKCQ31tju7On/4C6jr0siUCc2//W+SO5c+FHDY1bma02cp
+jXTEiFpw91YcyKxiADIaH9/qfxWdefxqYg1WlUeXF3jYt5xYnYr34qKW1gOZ3jy1
+QJ3esn382ZTml3TFZWy+g9tkYyOSgmDwQZbLk/ppBAECgYEA8RzLBFwP018ieMBv
+khDtwcKk6ZihkWZxEPQPuUljWzzAHn/f3dXOcrfmflAKeoDEeYDimDYDizTLDPC4
+zmWkMJHNadcM5H065BbGVFQWXo47ltccfIlB/1vzG8aywfJ/yNfHvH87wbH2eg6N
+yOr+96ZjLJszQ+Rv189BbXDzTcMCgYEA7yEbUL/A1J0l2kLoYyS0vfVa7AyBVOFW
+vPgfkF7HdNpIiFWlukMr+DWOolaoZp5iHqQXFwJsL8qCcrbZuHbaNHAI/5vDE9xG
+fh8KzrfBrjIPIyNm6EWpsBo5unXK+wTeqIAGKdzDo5Q3zEE6G5DkkHItKA7yjPOM
+gz/b/MR3W6ECgYBBv3dA3hXWrreIs/j4nLMoxfoQVPWh34xvcg4jmXaFd6Bv8LDM
+HjRopestgIgK9bgd5d5kYT5AJIpGIhJS/fZy5B9egCzc1aVMc0Vr024yJJjtPgVf
+lFIx3xIA/gLazlS4INcveIaEABJVIEjbg/E4+N9MV5n4Jn+1GqgdvtIp3wKBgQC0
+C3lFkxrc+nVFoJrYCwsK+3E5yTCXeBKWtTsOuE307WUvQU1GsMyqVajPEfA5U4cN
+Cv9Xk7thQFh3hrTm7pXcZX5g9iYrDe8FhtncSv7I6Wf8TOtudwUMUrKkcYwi88ex
+lrMNUer7ft2ELJhTqQRuvYjCYH6/IaDqMWqxJju4AQKBgQDPjOh75ykQc93SsYpt
+Tb4gQKLeqOb57pofT8D44DccatfEgk31D4fBIIQu6XKopQmCtQyX9DUDjOWFTxuo
+IMPysN6Fh1quCbC6Xt5xfKoaJG5yQYKeKtLhknwEW9SUifU2xVrOcPikLs7Iwmmp
+BkDLsu/YKwRFSfrbYZXbTlU8tQ==
+-----END PRIVATE KEY-----
diff --git a/unit/gencerts.sh b/unit/gencerts.sh
index fb305d7..cfa6486 100755
--- a/unit/gencerts.sh
+++ b/unit/gencerts.sh
@@ -12,6 +12,7 @@ openssl verify -CAfile cert-ca.pem cert-server.pem
 
 echo -e "\n*** Client Certificate ***"
 openssl genrsa -out cert-client-key.pem
+openssl pkcs8 -topk8 -nocrypt -in cert-client-key.pem -out cert-client-key-pkcs8.pem
 openssl req -new -extensions cert_ext -config ./gencerts.cnf -subj '/O=Bar Example Organization/CN=Bar Example Organization/emailAddress=bar(a)mail.example' -key cert-client-key.pem -out cert-client.csr
 openssl x509 -req -extensions cert_ext -extfile ./gencerts.cnf -in cert-client.csr -CA cert-ca.pem -CAkey cert-ca-key.pem -CAcreateserial -sha256 -days 10000 -out cert-client.pem
 openssl verify -CAfile cert-ca.pem cert-client.pem
diff --git a/unit/test-key.c b/unit/test-key.c
index 7f5124f..df75df9 100644
--- a/unit/test-key.c
+++ b/unit/test-key.c
@@ -33,6 +33,12 @@
 #define KEY2_STR "This key is longer than 32 bytes, just to be different."
 #define KEY2_LEN (strlen(KEY2_STR))
 
+static const char *plaintext =
+	"The quick brown fox jumps over the lazy dog. "	\
+	"Jackdaws love my big sphinx of quartz. "	\
+	"Pack my box with five dozen liquor jugs. "	\
+	"How razorback-jumping frogs can level six piqued gymnasts!";
+
 static void test_unsupported(const void *data)
 {
 	struct l_key *key;
@@ -400,6 +406,192 @@ static void test_trusted_keyring(const void *data)
 	l_free(cert);
 }
 
+/* Reference ciphertext:
+ * $ openssl rsautl -in reference_plaintext -inkey cert-client.pem -encrypt \
+ * > -pkcs -out reference_ciphertext
+ * $ xxd -i reference_ciphertext
+ *
+ * where reference_plaintext is a file containing the 183 characters of
+ * plaintext[] (above).
+ */
+static uint8_t reference_ciphertext[256] = {
+	0x45, 0x1a, 0xa1, 0x49, 0x4f, 0x61, 0xf6, 0x96, 0x23, 0x77, 0x0c, 0x33,
+	0x56, 0x07, 0xe6, 0x0f, 0xd6, 0x7b, 0x90, 0xd0, 0x4f, 0xc7, 0x9f, 0x34,
+	0xd4, 0x99, 0x55, 0x74, 0xd9, 0x68, 0x35, 0x3f, 0xd5, 0xbd, 0x7a, 0xec,
+	0xd3, 0xd1, 0x7e, 0xe3, 0xf0, 0xd6, 0x72, 0x7f, 0xb7, 0x20, 0x10, 0x53,
+	0x1c, 0xaa, 0x2b, 0xf6, 0x82, 0x66, 0xdf, 0xfe, 0x71, 0x62, 0x4e, 0x97,
+	0xdb, 0x83, 0xff, 0xc2, 0xab, 0x79, 0x69, 0xc7, 0xde, 0x77, 0x18, 0x55,
+	0x0c, 0xea, 0x01, 0x4e, 0xeb, 0x8b, 0x13, 0xa3, 0xef, 0xc4, 0x29, 0xa6,
+	0x51, 0x16, 0x3f, 0xa5, 0xe9, 0x91, 0x91, 0x26, 0x45, 0x98, 0x1f, 0x0b,
+	0x34, 0x6e, 0x4a, 0x61, 0xc4, 0xf3, 0x85, 0x78, 0x6b, 0xdf, 0x38, 0x9b,
+	0xeb, 0x6d, 0xc2, 0xed, 0xdf, 0xa9, 0xe6, 0xbb, 0x81, 0x84, 0xd9, 0x4a,
+	0x42, 0xa6, 0x3b, 0xa9, 0x5b, 0xae, 0xee, 0xaa, 0x6a, 0x3a, 0xc0, 0xcb,
+	0x48, 0x5c, 0x61, 0xa0, 0xe2, 0x4c, 0x06, 0x15, 0x7a, 0x8e, 0xe7, 0x47,
+	0x9c, 0x03, 0x86, 0x70, 0x00, 0xa1, 0xa8, 0x68, 0x9e, 0x7e, 0xc7, 0x81,
+	0x38, 0xb3, 0x00, 0xd4, 0xa9, 0xc2, 0x56, 0xf7, 0xf4, 0x3b, 0x9b, 0xb1,
+	0x27, 0xcd, 0xed, 0x2e, 0xf3, 0xa8, 0x9b, 0x08, 0x5e, 0x8a, 0xf3, 0x29,
+	0x67, 0xa4, 0x93, 0xc5, 0x68, 0xa5, 0x26, 0x1b, 0x3b, 0x1d, 0xc7, 0x78,
+	0x32, 0xd9, 0x81, 0x65, 0x8e, 0x17, 0xb3, 0x17, 0x30, 0x12, 0xe3, 0x78,
+	0x23, 0xd9, 0x02, 0x3b, 0xf9, 0x7b, 0x8d, 0x12, 0x4c, 0xff, 0xa0, 0xd2,
+	0x0f, 0x59, 0xb9, 0x75, 0xbd, 0x7f, 0xbb, 0x13, 0x8c, 0x6f, 0xbd, 0x00,
+	0x67, 0xf3, 0xa0, 0x43, 0x05, 0x5d, 0xb7, 0x64, 0xe3, 0xae, 0x81, 0xe1,
+	0x78, 0x5e, 0x81, 0xc5, 0x20, 0xc0, 0xdb, 0xba, 0xd0, 0xbe, 0x1f, 0xc5,
+	0x6a, 0xe4, 0x31, 0x46
+};
+
+/* Reference signature:
+ * $ openssl dgst -sha256 -sign cert-client-key.pem -out reference_signature \
+ * > good_plaintext
+ * $ xxd -i reference_signature
+ *
+ * where reference_plaintext is a file containing the 183 characters of
+ * plaintext[] (above).
+ */
+
+uint8_t reference_signature[256] = {
+	0x39, 0xaf, 0x0d, 0x23, 0x33, 0xcc, 0x48, 0xed, 0xc3, 0x15, 0x9e, 0xb9,
+	0xd3, 0x53, 0xe0, 0x0c, 0xea, 0x45, 0x65, 0xa7, 0x82, 0x8f, 0x4b, 0xfc,
+	0x5e, 0xd3, 0xc9, 0x10, 0xf5, 0xc6, 0x56, 0x3a, 0x0e, 0x60, 0xde, 0x01,
+	0xac, 0xb6, 0xf8, 0xc7, 0xe3, 0x60, 0xd1, 0xec, 0x4f, 0x38, 0x36, 0x42,
+	0xab, 0xf5, 0x90, 0xd6, 0xd8, 0x8b, 0x8a, 0x1c, 0x1a, 0xda, 0xec, 0x10,
+	0xd2, 0xec, 0x8a, 0x77, 0x9f, 0xcf, 0x25, 0x48, 0x13, 0xdf, 0xd0, 0xb1,
+	0xaf, 0x12, 0x55, 0xa0, 0x1a, 0xda, 0x8a, 0x60, 0xbf, 0x10, 0xcf, 0x02,
+	0xae, 0x3e, 0x7c, 0x01, 0x3f, 0x9d, 0xf4, 0xfb, 0x4b, 0x2c, 0x99, 0x7d,
+	0x0e, 0x06, 0xd5, 0x1e, 0x94, 0x38, 0x08, 0x18, 0x62, 0xb1, 0x73, 0x49,
+	0xae, 0x9f, 0x0e, 0x3b, 0x40, 0x48, 0x7f, 0x73, 0x73, 0xe0, 0x5c, 0xdf,
+	0xed, 0xb0, 0xf5, 0x9a, 0xbe, 0xa0, 0xff, 0x3f, 0x70, 0xe6, 0xe4, 0xf4,
+	0x99, 0x1a, 0x79, 0x1d, 0x76, 0x38, 0x8a, 0xae, 0x04, 0xba, 0x9a, 0xf7,
+	0x5e, 0x58, 0x5f, 0x4f, 0x86, 0x4b, 0x89, 0x2f, 0x6c, 0xf7, 0xf0, 0x42,
+	0x5e, 0x2f, 0x01, 0x6f, 0xb4, 0x7e, 0x7e, 0xa8, 0xeb, 0xa4, 0x7b, 0x03,
+	0x63, 0x61, 0x26, 0x1d, 0xc1, 0xba, 0xfa, 0xf3, 0xa9, 0xa4, 0xb1, 0x7e,
+	0x0a, 0x2f, 0x22, 0x30, 0x48, 0x16, 0xfb, 0x25, 0x13, 0x67, 0x86, 0x98,
+	0x39, 0x88, 0x31, 0x78, 0xb4, 0xfb, 0xe3, 0xa0, 0x2e, 0x5c, 0x97, 0xdd,
+	0xfa, 0xe1, 0xd8, 0x3e, 0xd2, 0x9f, 0x33, 0xa4, 0x65, 0xc8, 0x34, 0xa5,
+	0xe7, 0x57, 0x9a, 0xae, 0x97, 0x93, 0x17, 0xa4, 0x72, 0x85, 0x83, 0xc9,
+	0x64, 0x62, 0x58, 0xbf, 0x3b, 0xb4, 0xb8, 0x1f, 0x5c, 0xd5, 0x9a, 0x3f,
+	0x3a, 0xf8, 0xe1, 0x2d, 0x6a, 0xf3, 0x0c, 0x20, 0x6e, 0x87, 0xa6, 0xc8,
+	0xf4, 0x8e, 0x18, 0x07
+};
+
+static void test_key_crypto(const void *data)
+{
+	uint8_t *cert;
+	size_t certlen;
+	uint8_t *pubcert;
+	size_t pubcertlen;
+	struct l_key *key;
+	struct l_key *pubkey;
+	bool is_public;
+	size_t keybits;
+	bool success;
+	uint8_t ciphertext[256];
+	uint8_t decrypted[256];
+	uint8_t msghash[32];
+	ssize_t len;
+	struct l_checksum *checksum;
+	int hash = L_CHECKSUM_SHA256;
+	int rsa = L_CIPHER_RSA_PKCS1_V1_5;
+
+	cert = l_pem_load_private_key(TESTDATADIR "/cert-client-key-pkcs8.pem",
+					NULL, &certlen);
+	assert(cert);
+	pubcert = l_pem_load_certificate(TESTDATADIR "/cert-client.pem",
+						&pubcertlen);
+	assert(pubcert);
+
+	key = l_key_new(L_KEY_RSA, cert, certlen);
+	assert(key);
+	pubkey = l_key_new(L_KEY_RSA, pubcert, pubcertlen);
+	assert(pubkey);
+
+	success = l_key_get_info(key, rsa, hash, &keybits, &is_public);
+	assert(success);
+	assert(keybits == 2048);
+	assert(!is_public);
+
+	success = l_key_get_info(key, rsa, L_CHECKSUM_NONE, &keybits,
+					&is_public);
+	assert(success);
+	assert(keybits == 2048);
+	assert(!is_public);
+
+	success = l_key_get_info(pubkey, rsa, hash, &keybits, &is_public);
+	assert(success);
+	assert(keybits == 2048);
+	assert(is_public);
+
+	memset(ciphertext, 0, sizeof(ciphertext));
+	memset(decrypted, 0, sizeof(decrypted));
+
+	len = l_key_encrypt(pubkey, rsa, hash, plaintext, ciphertext,
+				strlen(plaintext), sizeof(ciphertext));
+	assert(len == sizeof(ciphertext));
+
+	/* Can't decrypt with public key */
+	len = l_key_decrypt(pubkey, rsa, hash, ciphertext, decrypted,
+				sizeof(ciphertext), sizeof(decrypted));
+	assert(len < 0);
+
+	len = l_key_decrypt(key, rsa, hash, ciphertext, decrypted,
+				sizeof(ciphertext), sizeof(decrypted));
+	assert(len == (ssize_t)strlen(plaintext));
+	assert(strcmp(plaintext, (char *)decrypted) == 0);
+
+	/* Decrypt reference ciphertext */
+	memset(decrypted, 0, sizeof(decrypted));
+	len = l_key_decrypt(key, rsa, hash, reference_ciphertext, decrypted,
+				sizeof(reference_ciphertext),
+				sizeof(decrypted));
+	assert(len == (ssize_t)strlen(plaintext));
+	assert(strcmp(plaintext, (char *)decrypted) == 0);
+
+	/* Decrypt corrupted ciphertext */
+	memset(decrypted, 0, sizeof(decrypted));
+	reference_ciphertext[0] = reference_ciphertext[0] ^ (uint8_t)0xFF;
+	len = l_key_decrypt(key, rsa, hash, reference_ciphertext, decrypted,
+				sizeof(reference_ciphertext),
+				sizeof(decrypted));
+	assert(len < 0);
+
+	checksum = l_checksum_new(L_CHECKSUM_SHA256);
+	assert(checksum);
+	l_checksum_update(checksum, plaintext, strlen(plaintext));
+	l_checksum_get_digest(checksum, msghash, sizeof(msghash));
+	l_checksum_free(checksum);
+
+	/* Can't sign with public key */
+	len = l_key_sign(pubkey, rsa, hash, msghash, ciphertext,
+				sizeof(msghash), sizeof(ciphertext));
+	assert(len < 0);
+
+	len = l_key_sign(key, rsa, hash, msghash, ciphertext, sizeof(msghash),
+				sizeof(ciphertext));
+	assert(len == sizeof(ciphertext));
+
+	success = l_key_verify(pubkey, rsa, hash, msghash, ciphertext,
+				sizeof(msghash), sizeof(ciphertext));
+	assert(success);
+
+	success = l_key_verify(key, rsa, hash, msghash, ciphertext,
+				sizeof(msghash), sizeof(ciphertext));
+	assert(success);
+
+	success = l_key_verify(pubkey, rsa, hash, msghash, reference_signature,
+				sizeof(msghash), sizeof(reference_signature));
+	assert(success);
+
+	/* Corrupt signature */
+	msghash[10] = msghash[10] ^ (uint8_t)0xFF;
+	success = l_key_verify(key, rsa, hash, msghash, ciphertext,
+				sizeof(msghash), sizeof(ciphertext));
+	assert(!success);
+
+	l_key_free(key);
+	l_key_free(pubkey);
+	l_free(cert);
+	l_free(pubcert);
+}
+
 int main(int argc, char *argv[])
 {
 	l_test_init(&argc, &argv);
@@ -414,5 +606,7 @@ int main(int argc, char *argv[])
 	l_test_add("simple keyring", test_simple_keyring, NULL);
 	l_test_add("trusted keyring", test_trusted_keyring, NULL);
 
+	l_test_add("key crypto", test_key_crypto, NULL);
+
 	return l_test_run();
 }
-- 
2.9.2


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

* Re: [PATCH v3 1/4] unit: Rename asymmetric key type to L_KEY_RSA
  2016-08-01 21:25 [PATCH v3 1/4] unit: Rename asymmetric key type to L_KEY_RSA Mat Martineau
                   ` (2 preceding siblings ...)
  2016-08-01 21:25 ` [PATCH v3 4/4] unit: Add tests for key-based asymmetric crypto Mat Martineau
@ 2016-08-01 21:40 ` Denis Kenzior
  3 siblings, 0 replies; 5+ messages in thread
From: Denis Kenzior @ 2016-08-01 21:40 UTC (permalink / raw)
  To: ell

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

Hi Mat,

On 08/01/2016 04:25 PM, Mat Martineau wrote:
> ---
>   unit/test-key.c | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
>

All four applied, thanks.

Regards,
-Denis


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

end of thread, other threads:[~2016-08-01 21:40 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-01 21:25 [PATCH v3 1/4] unit: Rename asymmetric key type to L_KEY_RSA Mat Martineau
2016-08-01 21:25 ` [PATCH v3 2/4] checksum: Add L_CHECKSUM_NONE, needed for key crypto Mat Martineau
2016-08-01 21:25 ` [PATCH v3 3/4] key: Add key-based asymmetric crypto operations Mat Martineau
2016-08-01 21:25 ` [PATCH v3 4/4] unit: Add tests for key-based asymmetric crypto Mat Martineau
2016-08-01 21:40 ` [PATCH v3 1/4] unit: Rename asymmetric key type to L_KEY_RSA 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.