Refactor GoogleKeymaster to move openssl RSA key-generation operations
to RsaOperation.
Change-Id: Id6c66bd431cf3f8895113108027920ffafef578b
diff --git a/google_keymaster.cpp b/google_keymaster.cpp
index d841b25..890dc7d 100644
--- a/google_keymaster.cpp
+++ b/google_keymaster.cpp
@@ -19,9 +19,6 @@
#include <cstddef>
-#include <openssl/err.h>
-#include <openssl/evp.h>
-#include <openssl/rsa.h>
#include <openssl/rand.h>
#include <UniquePtr.h>
@@ -49,50 +46,15 @@
const int RSA_DEFAULT_KEY_SIZE = 2048;
const int RSA_DEFAULT_EXPONENT = 65537;
-struct BIGNUM_Delete {
- void operator()(BIGNUM* p) const {
- BN_free(p);
- }
-};
-typedef UniquePtr<BIGNUM, BIGNUM_Delete> Unique_BIGNUM;
-
-struct RSA_Delete {
- void operator()(RSA* p) const {
- RSA_free(p);
- }
-};
-typedef UniquePtr<RSA, RSA_Delete> Unique_RSA;
-
-struct EVP_PKEY_Delete {
- void operator()(EVP_PKEY* p) const {
- EVP_PKEY_free(p);
- }
-};
-typedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;
-
struct AE_CTX_Delete {
- void operator()(ae_ctx* ctx) const {
- ae_free(ctx);
- }
+ void operator()(ae_ctx* ctx) const { ae_free(ctx); }
};
typedef UniquePtr<ae_ctx, AE_CTX_Delete> Unique_ae_ctx;
struct ByteArray_Delete {
- void operator()(void* p) const {
- delete[] reinterpret_cast<uint8_t*>(p);
- }
+ void operator()(void* p) const { delete[] reinterpret_cast<uint8_t*>(p); }
};
-/**
- * Many OpenSSL APIs take ownership of an argument on success but don't free the argument on
- * failure. This means we need to tell our scoped pointers when we've transferred ownership, without
- * triggering a warning by not using the result of release().
- */
-template <typename T, typename Delete_T>
-inline void release_because_ownership_transferred(UniquePtr<T, Delete_T>& p) {
- T* val __attribute__((unused)) = p.release();
-}
-
keymaster_algorithm_t supported_algorithms[] = {
KM_ALGORITHM_RSA,
};
@@ -193,15 +155,6 @@
}
}
-template <typename Message>
-void store_bignum(Message* message, void (Message::*set)(const void* value, size_t size),
- BIGNUM* bignum) {
- size_t bufsize = BN_num_bytes(bignum);
- UniquePtr<uint8_t[]> buf(new uint8_t[bufsize]);
- int bytes_written = BN_bn2bin(bignum, buf.get());
- (message->*set)(buf.get(), bytes_written);
-}
-
void GoogleKeymaster::GenerateKey(const GenerateKeyRequest& request,
GenerateKeyResponse* response) {
if (response == NULL)
@@ -328,42 +281,16 @@
if (!key_auths.GetTagValue(TAG_KEY_SIZE, &key_size))
AddAuthorization(Authorization(TAG_KEY_SIZE, key_size), response);
- Unique_BIGNUM exponent(BN_new());
- Unique_RSA rsa_key(RSA_new());
- Unique_EVP_PKEY pkey(EVP_PKEY_new());
- if (rsa_key.get() == NULL || pkey.get() == NULL) {
- response->error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
+ UniquePtr<uint8_t[]> key_data;
+ size_t key_data_size;
+ keymaster_error_t error =
+ RsaOperation::Generate(public_exponent, key_size, &key_data, &key_data_size);
+ if (error != KM_ERROR_OK) {
+ response->error = error;
return false;
}
- if (!BN_set_word(exponent.get(), public_exponent) ||
- !RSA_generate_key_ex(rsa_key.get(), key_size, exponent.get(), NULL /* callback */)) {
- response->error = KM_ERROR_UNKNOWN_ERROR;
- return false;
- }
-
- if (!EVP_PKEY_assign_RSA(pkey.get(), rsa_key.get())) {
- response->error = KM_ERROR_UNKNOWN_ERROR;
- return false;
- } else {
- release_because_ownership_transferred(rsa_key);
- }
-
- int der_length = i2d_PrivateKey(pkey.get(), NULL);
- if (der_length <= 0) {
- response->error = KM_ERROR_UNKNOWN_ERROR;
- return false;
- }
- UniquePtr<uint8_t[]> der_data(new uint8_t[der_length]);
- if (der_data.get() == NULL) {
- response->error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
- return false;
- }
-
- uint8_t* tmp = der_data.get();
- i2d_PrivateKey(pkey.get(), &tmp);
-
- return CreateKeyBlob(response, *hidden_auths, der_data.get(), der_length);
+ return CreateKeyBlob(response, *hidden_auths, key_data.get(), key_data_size);
}
bool GoogleKeymaster::CreateKeyBlob(GenerateKeyResponse* response,
@@ -490,7 +417,7 @@
UniquePtr<Operation> op(operation);
if (RAND_bytes(reinterpret_cast<uint8_t*>(op_handle), sizeof(*op_handle)) == 0)
return KM_ERROR_UNKNOWN_ERROR;
- if (*op_handle == 0){
+ if (*op_handle == 0) {
// Statistically this is vanishingly unlikely, which means if it ever happens in practice,
// it indicates a broken RNG.
return KM_ERROR_UNKNOWN_ERROR;