summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorNicola Tuveri <nic.tuv@gmail.com>2020-09-28 08:37:13 +0300
committerNicola Tuveri <nic.tuv@gmail.com>2020-10-14 18:42:59 +0300
commit5b70206cb316024c6dc30ce54f585ce5cf001a56 (patch)
tree088b9e9b1c2d3c728185bed2f06844076ddd781f /test
parent8b17fbaf46ae8a1319be5975ad8da3e0f4932e77 (diff)
[test][tls-provider] Implement KEM algorithm
Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/13018)
Diffstat (limited to 'test')
-rw-r--r--test/tls-provider.c203
1 files changed, 181 insertions, 22 deletions
diff --git a/test/tls-provider.c b/test/tls-provider.c
index d890e9a04b..bcbcd710ce 100644
--- a/test/tls-provider.c
+++ b/test/tls-provider.c
@@ -41,7 +41,53 @@ typedef struct xorkey_st {
int haspubkey;
} XORKEY;
-/* We define a dummy TLS group called "xorgroup" for test purposes */
+
+/* Key Management for the dummy XOR KEX and KEM algorithms */
+
+static OSSL_FUNC_keymgmt_new_fn xor_newdata;
+static OSSL_FUNC_keymgmt_free_fn xor_freedata;
+static OSSL_FUNC_keymgmt_has_fn xor_has;
+static OSSL_FUNC_keymgmt_copy_fn xor_copy;
+static OSSL_FUNC_keymgmt_gen_init_fn xor_gen_init;
+static OSSL_FUNC_keymgmt_gen_set_params_fn xor_gen_set_params;
+static OSSL_FUNC_keymgmt_gen_settable_params_fn xor_gen_settable_params;
+static OSSL_FUNC_keymgmt_gen_fn xor_gen;
+static OSSL_FUNC_keymgmt_gen_cleanup_fn xor_gen_cleanup;
+static OSSL_FUNC_keymgmt_get_params_fn xor_get_params;
+static OSSL_FUNC_keymgmt_gettable_params_fn xor_gettable_params;
+static OSSL_FUNC_keymgmt_set_params_fn xor_set_params;
+static OSSL_FUNC_keymgmt_settable_params_fn xor_settable_params;
+
+/*
+ * Dummy "XOR" Key Exchange algorithm. We just xor the private and public keys
+ * together. Don't use this!
+ */
+
+static OSSL_FUNC_keyexch_newctx_fn xor_newctx;
+static OSSL_FUNC_keyexch_init_fn xor_init;
+static OSSL_FUNC_keyexch_set_peer_fn xor_set_peer;
+static OSSL_FUNC_keyexch_derive_fn xor_derive;
+static OSSL_FUNC_keyexch_freectx_fn xor_freectx;
+static OSSL_FUNC_keyexch_dupctx_fn xor_dupctx;
+
+/*
+ * Dummy "XOR" Key Encapsulation Method. We just build a KEM over the xor KEX.
+ * Don't use this!
+ */
+
+static OSSL_FUNC_kem_newctx_fn xor_newctx;
+static OSSL_FUNC_kem_freectx_fn xor_freectx;
+static OSSL_FUNC_kem_dupctx_fn xor_dupctx;
+static OSSL_FUNC_kem_encapsulate_init_fn xor_init;
+static OSSL_FUNC_kem_encapsulate_fn xor_encapsulate;
+static OSSL_FUNC_kem_decapsulate_init_fn xor_init;
+static OSSL_FUNC_kem_decapsulate_fn xor_decapsulate;
+
+
+/*
+ * We define 2 dummy TLS groups called "xorgroup" and "xorkemgroup" for test
+ * purposes
+ */
struct tls_group_st {
unsigned int group_id; /* for "tls-group-id", see provider-base(7) */
unsigned int secbits;
@@ -133,16 +179,10 @@ static int tls_prov_get_capabilities(void *provctx, const char *capability,
* together. Don't use this!
*/
-static OSSL_FUNC_keyexch_newctx_fn xor_newctx;
-static OSSL_FUNC_keyexch_init_fn xor_init;
-static OSSL_FUNC_keyexch_set_peer_fn xor_set_peer;
-static OSSL_FUNC_keyexch_derive_fn xor_derive;
-static OSSL_FUNC_keyexch_freectx_fn xor_freectx;
-static OSSL_FUNC_keyexch_dupctx_fn xor_dupctx;
-
typedef struct {
XORKEY *key;
XORKEY *peerkey;
+ void *provctx;
} PROV_XOR_CTX;
static void *xor_newctx(void *provctx)
@@ -152,6 +192,8 @@ static void *xor_newctx(void *provctx)
if (pxorctx == NULL)
return NULL;
+ pxorctx->provctx = provctx;
+
return pxorctx;
}
@@ -235,21 +277,136 @@ static const OSSL_ALGORITHM tls_prov_keyexch[] = {
{ NULL, NULL, NULL }
};
-/* Key Management for the dummy XOR key exchange algorithm */
+/*
+ * Dummy "XOR" Key Encapsulation Method. We just build a KEM over the xor KEX.
+ * Don't use this!
+ */
-static OSSL_FUNC_keymgmt_new_fn xor_newdata;
-static OSSL_FUNC_keymgmt_free_fn xor_freedata;
-static OSSL_FUNC_keymgmt_has_fn xor_has;
-static OSSL_FUNC_keymgmt_copy_fn xor_copy;
-static OSSL_FUNC_keymgmt_gen_init_fn xor_gen_init;
-static OSSL_FUNC_keymgmt_gen_set_params_fn xor_gen_set_params;
-static OSSL_FUNC_keymgmt_gen_settable_params_fn xor_gen_settable_params;
-static OSSL_FUNC_keymgmt_gen_fn xor_gen;
-static OSSL_FUNC_keymgmt_gen_cleanup_fn xor_gen_cleanup;
-static OSSL_FUNC_keymgmt_get_params_fn xor_get_params;
-static OSSL_FUNC_keymgmt_gettable_params_fn xor_gettable_params;
-static OSSL_FUNC_keymgmt_set_params_fn xor_set_params;
-static OSSL_FUNC_keymgmt_settable_params_fn xor_settable_params;
+static int xor_encapsulate(void *vpxorctx,
+ unsigned char *ct, size_t *ctlen,
+ unsigned char *ss, size_t *sslen)
+{
+ /*
+ * We are building this around a KEX:
+ *
+ * 1. we generate ephemeral keypair
+ * 2. we encode our ephemeral pubkey as the outgoing ct
+ * 3. we derive using our ephemeral privkey in combination with the peer
+ * pubkey from the ctx; the result is our ss.
+ */
+ int rv = 0;
+ void *genctx = NULL, *derivectx = NULL;
+ XORKEY *ourkey = NULL;
+ PROV_XOR_CTX *pxorctx = vpxorctx;
+
+ if (ct == NULL || ss == NULL) {
+ /* Just return sizes */
+
+ if (ctlen == NULL && sslen == NULL)
+ return 0;
+ if (ctlen != NULL)
+ *ctlen = XOR_KEY_SIZE;
+ if (sslen != NULL)
+ *sslen = XOR_KEY_SIZE;
+ return 1;
+ }
+
+ /* 1. Generate keypair */
+ genctx = xor_gen_init(pxorctx->provctx, OSSL_KEYMGMT_SELECT_KEYPAIR);
+ if (genctx == NULL)
+ goto end;
+ ourkey = xor_gen(genctx, NULL, NULL);
+ if (ourkey == NULL)
+ goto end;
+
+ /* 2. Encode ephemeral pubkey as ct */
+ memcpy(ct, ourkey->pubkey, XOR_KEY_SIZE);
+ *ctlen = XOR_KEY_SIZE;
+
+ /* 3. Derive ss via KEX */
+ derivectx = xor_newctx(pxorctx->provctx);
+ if (derivectx == NULL
+ || !xor_init(derivectx, ourkey)
+ || !xor_set_peer(derivectx, pxorctx->key)
+ || !xor_derive(derivectx, ss, sslen, XOR_KEY_SIZE))
+ goto end;
+
+ rv = 1;
+
+ end:
+ xor_gen_cleanup(genctx);
+ xor_freedata(ourkey);
+ xor_freectx(derivectx);
+ return rv;
+}
+
+static int xor_decapsulate(void *vpxorctx,
+ unsigned char *ss, size_t *sslen,
+ const unsigned char *ct, size_t ctlen)
+{
+ /*
+ * We are building this around a KEX:
+ *
+ * - ct is our peer's pubkey
+ * - decapsulate is just derive.
+ */
+ int rv = 0;
+ void *derivectx = NULL;
+ XORKEY *peerkey = NULL;
+ PROV_XOR_CTX *pxorctx = vpxorctx;
+
+ if (ss == NULL) {
+ /* Just return size */
+ if (sslen == NULL)
+ return 0;
+ *sslen = XOR_KEY_SIZE;
+ return 1;
+ }
+
+ if (ctlen != XOR_KEY_SIZE)
+ return 0;
+ peerkey = xor_newdata(pxorctx->provctx);
+ if (peerkey == NULL)
+ goto end;
+ memcpy(peerkey->pubkey, ct, XOR_KEY_SIZE);
+
+ /* Derive ss via KEX */
+ derivectx = xor_newctx(pxorctx->provctx);
+ if (derivectx == NULL
+ || !xor_init(derivectx, pxorctx->key)
+ || !xor_set_peer(derivectx, peerkey)
+ || !xor_derive(derivectx, ss, sslen, XOR_KEY_SIZE))
+ goto end;
+
+ rv = 1;
+
+ end:
+ xor_freedata(peerkey);
+ xor_freectx(derivectx);
+ return rv;
+}
+
+static const OSSL_DISPATCH xor_kem_functions[] = {
+ { OSSL_FUNC_KEM_NEWCTX, (void (*)(void))xor_newctx },
+ { OSSL_FUNC_KEM_FREECTX, (void (*)(void))xor_freectx },
+ { OSSL_FUNC_KEM_DUPCTX, (void (*)(void))xor_dupctx },
+ { OSSL_FUNC_KEM_ENCAPSULATE_INIT, (void (*)(void))xor_init },
+ { OSSL_FUNC_KEM_ENCAPSULATE, (void (*)(void))xor_encapsulate },
+ { OSSL_FUNC_KEM_DECAPSULATE_INIT, (void (*)(void))xor_init },
+ { OSSL_FUNC_KEM_DECAPSULATE, (void (*)(void))xor_decapsulate },
+ { 0, NULL }
+};
+
+static const OSSL_ALGORITHM tls_prov_kem[] = {
+ /*
+ * Obviously this is not FIPS approved, but in order to test in conjuction
+ * with the FIPS provider we pretend that it is.
+ */
+ { "XOR", "provider=tls-provider,fips=yes", xor_kem_functions },
+ { NULL, NULL, NULL }
+};
+
+/* Key Management for the dummy XOR key exchange algorithm */
static void *xor_newdata(void *provctx)
{
@@ -483,6 +640,8 @@ static const OSSL_ALGORITHM *tls_prov_query(void *provctx, int operation_id,
return tls_prov_keymgmt;
case OSSL_OP_KEYEXCH:
return tls_prov_keyexch;
+ case OSSL_OP_KEM:
+ return tls_prov_kem;
}
return NULL;
}