]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
OpenSSL 3.0: Determine the prime length for an EC key group using EVP_PKEY
authorJouni Malinen <j@w1.fi>
Sun, 13 Mar 2022 08:40:06 +0000 (10:40 +0200)
committerJouni Malinen <j@w1.fi>
Sun, 13 Mar 2022 09:26:55 +0000 (11:26 +0200)
EVP_PKEY_get0_EC_KEY() and EC_KEY_get0_group() were deprecated in
OpenSSL 3.0. Add a version of this by determining the group without
fetching the EC_KEY itself from an EVP_PKEY.

Signed-off-by: Jouni Malinen <j@w1.fi>
src/crypto/crypto_openssl.c

index a0bb8c6cb9b40cdd55193743c62857208771b0e4..4b4b57d07717f28b20763fbdf944e8bf03ed9197 100644 (file)
@@ -2786,12 +2786,53 @@ struct wpabuf * crypto_ec_key_sign(struct crypto_ec_key *key, const u8 *data,
 }
 
 
-struct wpabuf * crypto_ec_key_sign_r_s(struct crypto_ec_key *key,
-                                      const u8 *data, size_t len)
+static int openssl_evp_pkey_ec_prime_len(struct crypto_ec_key *key)
 {
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+       char gname[50];
+       int nid;
+       EC_GROUP *group;
+       BIGNUM *prime = NULL;
+       int prime_len = -1;
+
+       if (EVP_PKEY_get_group_name((EVP_PKEY *) key, gname, sizeof(gname),
+                                   NULL) != 1)
+               return -1;
+       nid = OBJ_txt2nid(gname);
+       group = EC_GROUP_new_by_curve_name(nid);
+       prime = BN_new();
+       if (!group || !prime)
+               return -1;
+       if (EC_GROUP_get_curve(group, prime, NULL, NULL, NULL) == 1)
+               prime_len = BN_num_bytes(prime);
+       EC_GROUP_free(group);
+       BN_free(prime);
+       return prime_len;
+#else
        const EC_GROUP *group;
        const EC_KEY *eckey;
        BIGNUM *prime = NULL;
+       int prime_len = -1;
+
+       eckey = EVP_PKEY_get0_EC_KEY((EVP_PKEY *) key);
+       if (!eckey)
+               goto fail;
+       group = EC_KEY_get0_group(eckey);
+       prime = BN_new();
+       if (!prime || !group ||
+           !EC_GROUP_get_curve(group, prime, NULL, NULL, NULL))
+               goto fail;
+       prime_len = BN_num_bytes(prime);
+fail:
+       BN_free(prime);
+       return prime_len;
+#endif
+}
+
+
+struct wpabuf * crypto_ec_key_sign_r_s(struct crypto_ec_key *key,
+                                      const u8 *data, size_t len)
+{
        ECDSA_SIG *sig = NULL;
        const BIGNUM *r, *s;
        u8 *r_buf, *s_buf;
@@ -2799,20 +2840,15 @@ struct wpabuf * crypto_ec_key_sign_r_s(struct crypto_ec_key *key,
        const unsigned char *p;
        int prime_len;
 
+       prime_len = openssl_evp_pkey_ec_prime_len(key);
+       if (prime_len < 0)
+               return NULL;
+
        buf = crypto_ec_key_sign(key, data, len);
        if (!buf)
                return NULL;
 
        /* Extract (r,s) from Ecdsa-Sig-Value */
-       eckey = EVP_PKEY_get0_EC_KEY((EVP_PKEY *) key);
-       if (!eckey)
-               goto fail;
-       group = EC_KEY_get0_group(eckey);
-       prime = BN_new();
-       if (!prime || !group ||
-           !EC_GROUP_get_curve(group, prime, NULL, NULL, NULL))
-               goto fail;
-       prime_len = BN_num_bytes(prime);
 
        p = wpabuf_head(buf);
        sig = d2i_ECDSA_SIG(NULL, &p, wpabuf_len(buf));
@@ -2831,7 +2867,6 @@ struct wpabuf * crypto_ec_key_sign_r_s(struct crypto_ec_key *key,
                goto fail;
 
 out:
-       BN_free(prime);
        ECDSA_SIG_free(sig);
        return buf;
 fail: