__attribute__((visibility("default"))) int openssl_verify_data( const keymaster0_device_t*, const void* params, const uint8_t* keyBlob, const size_t keyBlobLength, const uint8_t* signedData, const size_t signedDataLength, const uint8_t* signature, const size_t signatureLength) { if (signedData == NULL || signature == NULL) { ALOGW("data or signature buffers == NULL"); return -1; } Unique_EVP_PKEY pkey(unwrap_key(keyBlob, keyBlobLength)); if (pkey.get() == NULL) { return -1; } int type = EVP_PKEY_type(pkey->type); if (type == EVP_PKEY_DSA) { const keymaster_dsa_sign_params_t* sign_params = reinterpret_cast<const keymaster_dsa_sign_params_t*>(params); return verify_dsa(pkey.get(), const_cast<keymaster_dsa_sign_params_t*>(sign_params), signedData, signedDataLength, signature, signatureLength); } else if (type == EVP_PKEY_RSA) { const keymaster_rsa_sign_params_t* sign_params = reinterpret_cast<const keymaster_rsa_sign_params_t*>(params); return verify_rsa(pkey.get(), const_cast<keymaster_rsa_sign_params_t*>(sign_params), signedData, signedDataLength, signature, signatureLength); } else if (type == EVP_PKEY_EC) { const keymaster_ec_sign_params_t* sign_params = reinterpret_cast<const keymaster_ec_sign_params_t*>(params); return verify_ec(pkey.get(), const_cast<keymaster_ec_sign_params_t*>(sign_params), signedData, signedDataLength, signature, signatureLength); } else { ALOGW("Unsupported key type %d", type); return -1; } }
static int openssl_sign_data(const keymaster_device_t* dev, const void* params, const uint8_t* keyBlob, const size_t keyBlobLength, const uint8_t* data, const size_t dataLength, uint8_t** signedData, size_t* signedDataLength) { int result = -1; EVP_MD_CTX ctx; size_t maxSize; if (data == NULL) { ALOGW("input data to sign == NULL"); return -1; } else if (signedData == NULL || signedDataLength == NULL) { ALOGW("output signature buffer == NULL"); return -1; } Unique_EVP_PKEY pkey(unwrap_key(keyBlob, keyBlobLength)); if (pkey.get() == NULL) { return -1; } if (EVP_PKEY_type(pkey->type) != EVP_PKEY_RSA) { ALOGW("Cannot handle non-RSA keys yet"); return -1; } keymaster_rsa_sign_params_t* sign_params = (keymaster_rsa_sign_params_t*) params; if (sign_params->digest_type != DIGEST_NONE) { ALOGW("Cannot handle digest type %d", sign_params->digest_type); return -1; } else if (sign_params->padding_type != PADDING_NONE) { ALOGW("Cannot handle padding type %d", sign_params->padding_type); return -1; } Unique_RSA rsa(EVP_PKEY_get1_RSA(pkey.get())); if (rsa.get() == NULL) { logOpenSSLError("openssl_sign_data"); return -1; } UniquePtr<uint8_t> signedDataPtr(reinterpret_cast<uint8_t*>(malloc(dataLength))); if (signedDataPtr.get() == NULL) { logOpenSSLError("openssl_sign_data"); return -1; } unsigned char* tmp = reinterpret_cast<unsigned char*>(signedDataPtr.get()); if (RSA_private_encrypt(dataLength, data, tmp, rsa.get(), RSA_NO_PADDING) <= 0) { logOpenSSLError("openssl_sign_data"); return -1; } *signedDataLength = dataLength; *signedData = signedDataPtr.release(); return 0; }
static int openssl_verify_data(const keymaster_device_t* dev, const void* params, const uint8_t* keyBlob, const size_t keyBlobLength, const uint8_t* signedData, const size_t signedDataLength, const uint8_t* signature, const size_t signatureLength) { if (signedData == NULL || signature == NULL) { ALOGW("data or signature buffers == NULL"); return -1; } Unique_EVP_PKEY pkey(unwrap_key(keyBlob, keyBlobLength)); if (pkey.get() == NULL) { return -1; } if (EVP_PKEY_type(pkey->type) != EVP_PKEY_RSA) { ALOGW("Cannot handle non-RSA keys yet"); return -1; } keymaster_rsa_sign_params_t* sign_params = (keymaster_rsa_sign_params_t*) params; if (sign_params->digest_type != DIGEST_NONE) { ALOGW("Cannot handle digest type %d", sign_params->digest_type); return -1; } else if (sign_params->padding_type != PADDING_NONE) { ALOGW("Cannot handle padding type %d", sign_params->padding_type); return -1; } else if (signatureLength != signedDataLength) { ALOGW("signed data length must be signature length"); return -1; } Unique_RSA rsa(EVP_PKEY_get1_RSA(pkey.get())); if (rsa.get() == NULL) { logOpenSSLError("openssl_verify_data"); return -1; } UniquePtr<uint8_t> dataPtr(reinterpret_cast<uint8_t*>(malloc(signedDataLength))); if (dataPtr.get() == NULL) { logOpenSSLError("openssl_verify_data"); return -1; } unsigned char* tmp = reinterpret_cast<unsigned char*>(dataPtr.get()); if (!RSA_public_decrypt(signatureLength, signature, tmp, rsa.get(), RSA_NO_PADDING)) { logOpenSSLError("openssl_verify_data"); return -1; } int result = 0; for (size_t i = 0; i < signedDataLength; i++) { result |= tmp[i] ^ signedData[i]; } return result == 0 ? 0 : -1; }
__attribute__((visibility("default"))) int openssl_get_keypair_public(const keymaster0_device_t*, const uint8_t* key_blob, const size_t key_blob_length, uint8_t** x509_data, size_t* x509_data_length) { if (x509_data == NULL || x509_data_length == NULL) { ALOGW("output public key buffer == NULL"); return -1; } Unique_EVP_PKEY pkey(unwrap_key(key_blob, key_blob_length)); if (pkey.get() == NULL) { return -1; } int len = i2d_PUBKEY(pkey.get(), NULL); if (len <= 0) { logOpenSSLError("openssl_get_keypair_public"); return -1; } UniquePtr<uint8_t, Malloc_Free> key(static_cast<uint8_t*>(malloc(len))); if (key.get() == NULL) { ALOGE("Could not allocate memory for public key data"); return -1; } unsigned char* tmp = reinterpret_cast<unsigned char*>(key.get()); if (i2d_PUBKEY(pkey.get(), &tmp) != len) { logOpenSSLError("openssl_get_keypair_public"); return -1; } ALOGV("Length of x509 data is %d", len); *x509_data_length = len; *x509_data = key.release(); return 0; }
int main(int argc, char * const argv[]) { int err = 0, r, c, long_optind = 0; int action_count = 0; int do_initialize = 0; int do_import_dkek_share = 0; int do_create_dkek_share = 0; int do_wrap_key = 0; int do_unwrap_key = 0; sc_path_t path; sc_file_t *file = NULL; const char *opt_so_pin = NULL; const char *opt_pin = NULL; const char *opt_filename = NULL; char *opt_password = NULL; int opt_retry_counter = 3; int opt_dkek_shares = -1; int opt_key_reference = -1; int opt_password_shares_threshold = -1; int opt_password_shares_total = -1; int opt_force = 0; int opt_iter = 10000000; sc_context_param_t ctx_param; setbuf(stderr, NULL); setbuf(stdout, NULL); while (1) { c = getopt_long(argc, argv, "XC:I:W:U:s:i:fr:wv", options, &long_optind); if (c == -1) break; if (c == '?') util_print_usage_and_die(app_name, options, option_help, NULL); switch (c) { case 'X': do_initialize = 1; action_count++; break; case 'C': do_create_dkek_share = 1; opt_filename = optarg; action_count++; break; case 'I': do_import_dkek_share = 1; opt_filename = optarg; action_count++; break; case 'W': do_wrap_key = 1; opt_filename = optarg; action_count++; break; case 'U': do_unwrap_key = 1; opt_filename = optarg; action_count++; break; case OPT_PASSWORD: opt_password = optarg; break; case OPT_SO_PIN: opt_so_pin = optarg; break; case OPT_PIN: opt_pin = optarg; break; case OPT_RETRY: opt_retry_counter = atol(optarg); break; case OPT_PASSWORD_SHARES_THRESHOLD: opt_password_shares_threshold = atol(optarg); break; case OPT_PASSWORD_SHARES_TOTAL: opt_password_shares_total = atol(optarg); break; case 's': opt_dkek_shares = atol(optarg); break; case 'f': opt_force = 1; break; case 'i': opt_key_reference = atol(optarg); break; case 'r': opt_reader = optarg; break; case 'v': verbose++; break; case 'w': opt_wait = 1; break; } } CRYPTO_malloc_init(); ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); memset(&ctx_param, 0, sizeof(sc_context_param_t)); ctx_param.app_name = app_name; r = sc_context_create(&ctx, &ctx_param); if (r != SC_SUCCESS) { fprintf(stderr, "Failed to establish context: %s\n", sc_strerror(r)); return 1; } /* Only change if not in opensc.conf */ if (verbose > 1 && ctx->debug == 0) { ctx->debug = verbose; sc_ctx_log_to_file(ctx, "stderr"); } err = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose); if (r != SC_SUCCESS) { fprintf(stderr, "Failed to connect to card: %s\n", sc_strerror(r)); goto end; } sc_path_set(&path, SC_PATH_TYPE_DF_NAME, sc_hsm_aid.value, sc_hsm_aid.len, 0, 0); r = sc_select_file(card, &path, &file); if (r != SC_SUCCESS) { fprintf(stderr, "Failed to select application: %s\n", sc_strerror(r)); goto end; } if (do_initialize) { initialize(card, opt_so_pin, opt_pin, opt_retry_counter, opt_dkek_shares); } if (do_create_dkek_share) { create_dkek_share(card, opt_filename, opt_iter, opt_password, opt_password_shares_threshold, opt_password_shares_total); } if (do_import_dkek_share) { import_dkek_share(card, opt_filename, opt_iter, opt_password, opt_password_shares_total); } if (do_wrap_key) { wrap_key(card, opt_key_reference, opt_filename, opt_pin); } if (do_unwrap_key) { unwrap_key(card, opt_key_reference, opt_filename, opt_pin, opt_force); } if (action_count == 0) { print_info(card, file); } end: if (card) { sc_unlock(card); sc_disconnect_card(card); } if (ctx) sc_release_context(ctx); ERR_print_errors_fp(stderr); return err; }