]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
OpenSSL: RSA-OAEP-SHA-256 encryption/decryption
authorJouni Malinen <quic_jouni@quicinc.com>
Sat, 30 Apr 2022 10:34:00 +0000 (13:34 +0300)
committerJouni Malinen <j@w1.fi>
Sun, 1 May 2022 13:25:06 +0000 (16:25 +0300)
Add new crypto wrappers for performing RSA-OAEP-SHA-256 encryption and
decryption. These are needed for IMSI privacy.

Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
hostapd/Android.mk
hostapd/Makefile
src/crypto/crypto.h
src/crypto/crypto_openssl.c
wpa_supplicant/Android.mk
wpa_supplicant/Makefile

index 885dae7f6db08b28890bdf67f2f859f4a74514d4..953031577574ec4c1839a98d394e6c664f3a5d1e 100644 (file)
@@ -659,6 +659,7 @@ L_CFLAGS += -DCONFIG_TLSV12
 endif
 
 ifeq ($(CONFIG_TLS), openssl)
+L_CFLAGS += -DCRYPTO_RSA_OAEP_SHA256
 ifdef TLS_FUNCS
 OBJS += src/crypto/tls_openssl.c
 OBJS += src/crypto/tls_openssl_ocsp.c
index 9967e270cfc24808fff7042b8d8bacbf25e1b6ae..3325937ffb37adb8cff001387e44242fcd0e9e9f 100644 (file)
@@ -714,6 +714,7 @@ endif
 endif
 
 ifeq ($(CONFIG_TLS), openssl)
+CFLAGS += -DCRYPTO_RSA_OAEP_SHA256
 CONFIG_CRYPTO=openssl
 ifdef TLS_FUNCS
 OBJS += ../src/crypto/tls_openssl.o
index 41019659789543a8ea3e4647101ceba238ee5510..e4f3eb3e619fcc391879774c3532afc8ebdc2db9 100644 (file)
@@ -1275,6 +1275,40 @@ struct wpabuf * crypto_csr_sign(struct crypto_csr *csr,
                                struct crypto_ec_key *key,
                                enum crypto_hash_alg algo);
 
+struct crypto_rsa_key;
+
+/**
+ * crypto_rsa_key_read - Read an RSA key
+ * @file: File from which to read (PEM encoded, can be X.509v3 certificate)
+ * @private_key: Whether to read the private key instead of public key
+ * Returns: RSA key or %NULL on failure
+ */
+struct crypto_rsa_key * crypto_rsa_key_read(const char *file, bool private_key);
+
+/**
+ * crypto_rsa_oaep_sha256_encrypt - RSA-OAEP-SHA-256 encryption
+ * @key: RSA key from crypto_rsa_key_read()
+ * @in: Plaintext input data
+ * Returns: Encrypted output data or %NULL on failure
+ */
+struct wpabuf * crypto_rsa_oaep_sha256_encrypt(struct crypto_rsa_key *key,
+                                              const struct wpabuf *in);
+
+/**
+ * crypto_rsa_oaep_sha256_decrypt - RSA-OAEP-SHA-256 decryption
+ * @key: RSA key from crypto_rsa_key_read()
+ * @in: Encrypted input data
+ * Returns: Decrypted output data or %NULL on failure
+ */
+struct wpabuf * crypto_rsa_oaep_sha256_decrypt(struct crypto_rsa_key *key,
+                                              const struct wpabuf *in);
+
+/**
+ * crypto_rsa_key_free - Free an RSA key
+ * @key: RSA key from crypto_rsa_key_read()
+ */
+void crypto_rsa_key_free(struct crypto_rsa_key *key);
+
 /**
  * crypto_unload - Unload crypto resources
  *
index cd3d3e245b78ee33456733b4140ed57d25bcd1e4..fbda869c1b1918a12d72a36a43a4b4d5d9e2acac 100644 (file)
 #include <openssl/dh.h>
 #include <openssl/hmac.h>
 #include <openssl/rand.h>
+#include <openssl/pem.h>
 #ifdef CONFIG_ECC
 #include <openssl/ec.h>
 #include <openssl/x509.h>
-#include <openssl/pem.h>
 #endif /* CONFIG_ECC */
 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
 #include <openssl/provider.h>
@@ -3939,6 +3939,125 @@ struct wpabuf * crypto_csr_sign(struct crypto_csr *csr,
 #endif /* CONFIG_ECC */
 
 
+static EVP_PKEY * crypto_rsa_key_read_public(FILE *f)
+{
+       EVP_PKEY *pkey;
+       X509 *x509;
+
+       pkey = PEM_read_PUBKEY(f, NULL, NULL, NULL);
+       if (pkey)
+               return pkey;
+
+       rewind(f);
+       x509 = PEM_read_X509(f, NULL, NULL, NULL);
+       if (!x509)
+               return NULL;
+
+       pkey = X509_get_pubkey(x509);
+       X509_free(x509);
+
+       if (!pkey)
+               return NULL;
+       if (EVP_PKEY_base_id(pkey) != EVP_PKEY_RSA) {
+               EVP_PKEY_free(pkey);
+               return NULL;
+       }
+
+       return pkey;
+}
+
+
+struct crypto_rsa_key * crypto_rsa_key_read(const char *file, bool private_key)
+{
+       FILE *f;
+       EVP_PKEY *pkey;
+
+       f = fopen(file, "r");
+       if (!f)
+               return NULL;
+       if (private_key)
+               pkey = PEM_read_PrivateKey(f, NULL, NULL, NULL);
+       else
+               pkey = crypto_rsa_key_read_public(f);
+       fclose(f);
+       return (struct crypto_rsa_key *) pkey;
+}
+
+
+#ifndef OPENSSL_NO_SHA256
+
+struct wpabuf * crypto_rsa_oaep_sha256_encrypt(struct crypto_rsa_key *key,
+                                              const struct wpabuf *in)
+{
+       EVP_PKEY *pkey = (EVP_PKEY *) key;
+       EVP_PKEY_CTX *pkctx;
+       struct wpabuf *res = NULL;
+       size_t outlen;
+
+       pkctx = EVP_PKEY_CTX_new(pkey, NULL);
+       if (!pkctx)
+               goto fail;
+
+       if (EVP_PKEY_encrypt_init(pkctx) != 1 ||
+           EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_OAEP_PADDING) <= 0 ||
+           EVP_PKEY_CTX_set_rsa_oaep_md(pkctx, EVP_sha256()) <= 0 ||
+           EVP_PKEY_encrypt(pkctx, NULL, &outlen, wpabuf_head(in),
+                            wpabuf_len(in)) != 1 ||
+           !(res = wpabuf_alloc(outlen)) ||
+           EVP_PKEY_encrypt(pkctx, wpabuf_put(res, 0), &outlen,
+                            wpabuf_head(in), wpabuf_len(in)) != 1) {
+               wpabuf_free(res);
+               res = NULL;
+               goto fail;
+       }
+       wpabuf_put(res, outlen);
+
+fail:
+       EVP_PKEY_CTX_free(pkctx);
+       return res;
+}
+
+
+struct wpabuf * crypto_rsa_oaep_sha256_decrypt(struct crypto_rsa_key *key,
+                                              const struct wpabuf *in)
+{
+       EVP_PKEY *pkey = (EVP_PKEY *) key;
+       EVP_PKEY_CTX *pkctx;
+       struct wpabuf *res = NULL;
+       size_t outlen;
+
+       pkctx = EVP_PKEY_CTX_new(pkey, NULL);
+       if (!pkctx)
+               goto fail;
+
+       if (EVP_PKEY_decrypt_init(pkctx) != 1 ||
+           EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_OAEP_PADDING) <= 0 ||
+           EVP_PKEY_CTX_set_rsa_oaep_md(pkctx, EVP_sha256()) <= 0 ||
+           EVP_PKEY_decrypt(pkctx, NULL, &outlen, wpabuf_head(in),
+                            wpabuf_len(in)) != 1 ||
+           !(res = wpabuf_alloc(outlen)) ||
+           EVP_PKEY_decrypt(pkctx, wpabuf_put(res, 0), &outlen,
+                            wpabuf_head(in), wpabuf_len(in)) != 1) {
+               wpabuf_free(res);
+               res = NULL;
+               goto fail;
+       }
+       wpabuf_put(res, outlen);
+
+fail:
+       EVP_PKEY_CTX_free(pkctx);
+       return res;
+}
+
+#endif /* OPENSSL_NO_SHA256 */
+
+
+void crypto_rsa_key_free(struct crypto_rsa_key *key)
+{
+       EVP_PKEY_free((EVP_PKEY *) key);
+}
+
+
 void crypto_unload(void)
 {
        openssl_unload_legacy_provider();
index 5d68ffa1d5e44cdae159cf76e8ee71994622a146..34d37fdcc5b3f5039a88aa320f5fbbd2a562cd8d 100644 (file)
@@ -1071,6 +1071,7 @@ L_CFLAGS += -DCONFIG_TLSV12
 endif
 
 ifeq ($(CONFIG_TLS), openssl)
+L_CFLAGS += -DCRYPTO_RSA_OAEP_SHA256
 ifdef TLS_FUNCS
 L_CFLAGS += -DEAP_TLS_OPENSSL
 OBJS += src/crypto/tls_openssl.c
index ead9205ff1ac188a014954c83a948ac301cf2ccd..d12b485a83bd9846ebc1ba0e28afc7ababd555a3 100644 (file)
@@ -1121,6 +1121,7 @@ LIBS_p += -lwolfssl -lm
 endif
 
 ifeq ($(CONFIG_TLS), openssl)
+CFLAGS += -DCRYPTO_RSA_OAEP_SHA256
 ifdef TLS_FUNCS
 CFLAGS += -DEAP_TLS_OPENSSL
 OBJS += ../src/crypto/tls_openssl.o