* [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, ¶ms, 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, ¶ms, 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.