Define OSSL_CAPABILITY_TLS_GROUP_IS_KEM
authorNicola Tuveri <nic.tuv@gmail.com>
Sun, 27 Sep 2020 23:16:29 +0000 (02:16 +0300)
committerNicola Tuveri <nic.tuv@gmail.com>
Wed, 14 Oct 2020 15:42:59 +0000 (18:42 +0300)
Note that with this commit the optional parameter is introduced, but
libssl still ignores it.

Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/13018)

doc/man7/provider-base.pod
include/openssl/core_names.h
ssl/ssl_local.h
ssl/t1_lib.c
test/tls-provider.c

index efec869e25f88e42fd554ec79fd6d221bdb867fe..b92f117d86e05cb3d48bd5a10c9a2d2b501994f0 100644 (file)
@@ -364,15 +364,17 @@ Applications can query the capabilities to discover those services.
 
 The "TLS-GROUP" capability can be queried by libssl to discover the list of
 TLS groups that a provider can support. Each group supported can be used for
-key exchange during a TLS handshake. TLS clients can advertise the list of
-TLS groups they support in the supported_groups extension, and TLS servers can
-select a group from the offered list that they also support. In this way a
-provider can add to the list of groups that libssl already supports with
-additional ones.
+I<key exchange> (KEX) or I<key encapsulation method> (KEM) during a TLS
+handshake.
+TLS clients can advertise the list of TLS groups they support in the
+supported_groups extension, and TLS servers can select a group from the offered
+list that they also support. In this way a provider can add to the list of
+groups that libssl already supports with additional ones.
 
 Each TLS group that a provider supports should be described via the callback
 passed in through the provider_get_capabilities function. Each group should have
-the following details supplied (all are mandatory):
+the following details supplied (all are mandatory, except
+B<OSSL_CAPABILITY_TLS_GROUP_IS_KEM>):
 
 =over 4
 
@@ -393,7 +395,9 @@ The TLS group id value as given in the IANA TLS Supported Groups registry.
 =item "tls-group-alg" (B<OSSL_CAPABILITY_TLS_GROUP_ALG>) <utf8 string>
 
 The name of a Key Management algorithm that the provider offers and that should
-be used with this group. Keys created should be able to support key exchange.
+be used with this group. Keys created should be able to support I<key exchange>
+or I<key encapsulation method> (KEM), as implied by the optional
+B<OSSL_CAPABILITY_TLS_GROUP_IS_KEM> flag.
 The algorithm must support key and parameter generation as well as the
 key/parameter generation parameter, B<OSSL_PKEY_PARAM_GROUP_NAME>. The group
 name given via "tls-group-name-internal" above will be passed via
@@ -405,6 +409,29 @@ The number of bits of security offered by keys in this group. The number of bits
 should be comparable with the ones given in table 2 and 3 of the NIST SP800-57
 document.
 
+=item "tls-group-is-kem" (B<OSSL_CAPABILITY_TLS_GROUP_IS_KEM>) <unsigned integer>
+
+Boolean flag to describe if the group should be used in I<key exchange> (KEX)
+mode (0, default) or in I<key encapsulation method> (KEM) mode (1).
+
+This parameter is optional: if not specified, KEX mode is assumed as the default
+mode for the group.
+
+In KEX mode, in a typical Diffie-Hellman fashion, both sides execute I<keygen>
+then I<derive> against the peer public key. To operate in KEX mode, the group
+implementation must support the provider functions as described in
+L<provider-keyexch(7)>.
+
+In KEM mode, the client executes I<keygen> and sends its public key, the server
+executes I<encapsulate> using the client's public key and sends back the
+resulting I<ciphertext>, finally the client executes I<decapsulate> to retrieve
+the same I<shared secret> generated by the server's I<encapsulate>. To operate
+in KEM mode, the group implementation must support the provider functions as
+described in L<provider-kem(7)>.
+
+Both in KEX and KEM mode, the resulting I<shared secret> is then used according
+to the protocol specification.
+
 =item "tls-min-tls" (B<OSSL_CAPABILITY_TLS_GROUP_MIN_TLS>) <integer>
 
 =item "tls-max-tls" (B<OSSL_CAPABILITY_TLS_GROUP_MAX_TLS>) <integer>
index c9f2bfab5e1abdfb47ba46f73849587ae0a69244..4a4bd36cbed31f1e338ce55474cb090c486e91b8 100644 (file)
@@ -492,6 +492,7 @@ extern "C" {
 #define OSSL_CAPABILITY_TLS_GROUP_ID                "tls-group-id"
 #define OSSL_CAPABILITY_TLS_GROUP_ALG               "tls-group-alg"
 #define OSSL_CAPABILITY_TLS_GROUP_SECURITY_BITS     "tls-group-sec-bits"
+#define OSSL_CAPABILITY_TLS_GROUP_IS_KEM            "tls-group-is-kem"
 #define OSSL_CAPABILITY_TLS_GROUP_MIN_TLS           "tls-min-tls"
 #define OSSL_CAPABILITY_TLS_GROUP_MAX_TLS           "tls-max-tls"
 #define OSSL_CAPABILITY_TLS_GROUP_MIN_DTLS          "tls-min-dtls"
index fd4eacdc388b99c48ca059c4196993eb8fa9fca6..e81470a82cc10e66b4d0bac866f37cf6f1e325b6 100644 (file)
@@ -818,6 +818,7 @@ typedef struct tls_group_info_st {
     int maxtls;              /* Maximum TLS version (or 0 for undefined) */
     int mindtls;             /* Minimum DTLS version, -1 unsupported */
     int maxdtls;             /* Maximum DTLS version (or 0 for undefined) */
+    char is_kem;             /* Mode for this Group: 0 is KEX, 1 is KEM */
 } TLS_GROUP_INFO;
 
 /* flags values */
index 927154fd988c465bd8fa2eafc4be4945ba482957..8005f4ee328e8694ecfc2f33304c09cd7eecdb85 100644 (file)
@@ -249,6 +249,7 @@ static int add_provider_groups(const OSSL_PARAM params[], void *data)
     TLS_GROUP_INFO *ginf = NULL;
     EVP_KEYMGMT *keymgmt;
     unsigned int gid;
+    unsigned int is_kem = 0;
     int ret = 0;
 
     if (ctx->group_list_max_len == ctx->group_list_len) {
@@ -321,6 +322,13 @@ static int add_provider_groups(const OSSL_PARAM params[], void *data)
         goto err;
     }
 
+    p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_IS_KEM);
+    if (p != NULL && (!OSSL_PARAM_get_uint(p, &is_kem) || is_kem > 1)) {
+        SSLerr(0, ERR_R_PASSED_INVALID_ARGUMENT);
+        goto err;
+    }
+    ginf->is_kem = 1 & is_kem;
+
     p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_MIN_TLS);
     if (p == NULL || !OSSL_PARAM_get_int(p, &ginf->mintls)) {
         SSLerr(0, ERR_R_PASSED_INVALID_ARGUMENT);
index c8a378d3beeba946522d2c88c3b141adf9e34e7a..d890e9a04b6924ddb3d61954a9f04b404e270933 100644 (file)
@@ -49,6 +49,7 @@ struct tls_group_st {
     unsigned int maxtls;
     unsigned int mindtls;
     unsigned int maxdtls;
+    unsigned int is_kem; /* boolean */
 };
 
 #define XORGROUP_NAME "xorgroup"
@@ -59,7 +60,8 @@ static struct tls_group_st xor_group = {
     TLS1_3_VERSION,     /* mintls */
     0,                  /* maxtls */
     -1,                 /* mindtls */
-    -1                  /* maxdtls */
+    -1,                 /* maxdtls */
+    0                   /* is_kem */
 };
 
 #define XORKEMGROUP_NAME "xorkemgroup"
@@ -70,7 +72,8 @@ static struct tls_group_st xor_kemgroup = {
     TLS1_3_VERSION,     /* mintls */
     0,                  /* maxtls */
     -1,                 /* mindtls */
-    -1                  /* maxdtls */
+    -1,                 /* maxdtls */
+    1                   /* is_kem */
 };
 
 #define ALGORITHM "XOR"
@@ -90,6 +93,7 @@ static const OSSL_PARAM xor_group_params[] = {
     OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MAX_TLS, &xor_group.maxtls),
     OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MIN_DTLS, &xor_group.mindtls),
     OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MAX_DTLS, &xor_group.maxdtls),
+    OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_GROUP_IS_KEM, &xor_group.is_kem),
     OSSL_PARAM_END
 };
 
@@ -108,6 +112,7 @@ static const OSSL_PARAM xor_kemgroup_params[] = {
     OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MAX_TLS, &xor_kemgroup.maxtls),
     OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MIN_DTLS, &xor_kemgroup.mindtls),
     OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MAX_DTLS, &xor_kemgroup.maxdtls),
+    OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_GROUP_IS_KEM, &xor_kemgroup.is_kem),
     OSSL_PARAM_END
 };