static void * bench_openssl_rsa_init (unsigned size) { struct openssl_rsa_ctx *ctx = make_openssl_rsa_ctx (size); RSA_blinding_off(ctx->key); return ctx; }
int RSA_blinding_on(RSA *rsa, BN_CTX *ctx) { int ret=0; if (rsa->blinding != NULL) RSA_blinding_off(rsa); rsa->blinding = RSA_setup_blinding(rsa, ctx); if (rsa->blinding == NULL) goto err; rsa->flags |= RSA_FLAG_BLINDING; rsa->flags &= ~RSA_FLAG_NO_BLINDING; ret=1; err: return(ret); }
static EVP_PKEY* keystore_loadkey(ENGINE* e, const char* key_id, UI_METHOD *ui_method, void *callback_data) { ALOGV("keystore_loadkey(%p, \"%s\", %p, %p)", e, key_id, ui_method, callback_data); Keystore_Reply reply; if (keystore_cmd(CommandCodes[GET_PUBKEY], &reply, 1, strlen(key_id), key_id) != NO_ERROR) { ALOGV("Cannot get public key for %s", key_id); return NULL; } const unsigned char* tmp = reinterpret_cast<const unsigned char*>(reply.get()); Unique_EVP_PKEY pkey(d2i_PUBKEY(NULL, &tmp, reply.length())); if (pkey.get() == NULL) { ALOGW("Cannot convert pubkey"); return NULL; } switch (EVP_PKEY_type(pkey->type)) { case EVP_PKEY_RSA: { Unique_RSA rsa(EVP_PKEY_get1_RSA(pkey.get())); if (!RSA_set_ex_data(rsa.get(), rsa_key_handle, reinterpret_cast<void*>(strdup(key_id)))) { ALOGW("Could not set ex_data for loaded RSA key"); return NULL; } RSA_set_method(rsa.get(), &keystore_rsa_meth); RSA_blinding_off(rsa.get()); /* * This should probably be an OpenSSL API, but EVP_PKEY_free calls * ENGINE_finish(), so we need to call ENGINE_init() here. */ ENGINE_init(e); rsa->engine = e; rsa->flags |= RSA_FLAG_EXT_PKEY; break; } default: ALOGE("Unsupported key type %d", EVP_PKEY_type(pkey->type)); return NULL; } return pkey.release(); }
/* reusable init */ void RSASigner::signerInit( const Context &context, bool isSigning) { StLock<Mutex> _(gMutex()); setIsSigning(isSigning); keyFromContext(context); /* optional padding attribute */ uint32 padding; bool padPresent = context.getInt(CSSM_ATTRIBUTE_PADDING, padding); if(padPresent) { /* padding specified in context, convert to openssl style */ switch(padding) { case CSSM_PADDING_NONE: mPadding = RSA_NO_PADDING; break; case CSSM_PADDING_PKCS1: mPadding = RSA_PKCS1_PADDING; break; default: CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PADDING); } } /* optional blinding attribute */ uint32 blinding = context.getInt(CSSM_ATTRIBUTE_RSA_BLINDING); if(blinding) { if(RSA_blinding_on(mRsaKey, NULL) <= 0) { /* actually no legit failures */ CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR); } } else { RSA_blinding_off(mRsaKey); } setInitFlag(true); }
int check_validity_of_cert( const char *cFile, const unsigned char *md5_md, unsigned char *sfileMsg, const int sfsize, const char* caPath ) { int retval = 0; X509 *cert; X509_STORE *store; X509_LOOKUP *lookup; X509_STORE_CTX *ctx = 0; EVP_PKEY *pubKey; BIO *bio; bio = BIO_new(BIO_s_file()); BIO_read_filename(bio, cFile); if (NULL == (cert = PEM_read_bio_X509(bio, NULL, 0, NULL))) { BIO_vfree(bio); return 0; } // verify certificate store = X509_STORE_new(); lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir()); X509_LOOKUP_add_dir(lookup, (char *)caPath, X509_FILETYPE_PEM); if ((ctx = X509_STORE_CTX_new()) != 0) { if (X509_STORE_CTX_init(ctx, store, cert, 0) == 1) retval = X509_verify_cert(ctx); X509_STORE_CTX_free(ctx); } X509_STORE_free(store); if (retval != 1) { fprintf(stderr,"ERROR: Cannot verify certificate ('%s')\n", cFile); return 0; } pubKey = X509_get_pubkey(cert); if (!pubKey) { X509_free(cert); BIO_vfree(bio); return 0; } if (pubKey->type == EVP_PKEY_RSA) { BN_CTX *c = BN_CTX_new(); if (!c) { X509_free(cert); EVP_PKEY_free(pubKey); BIO_vfree(bio); return 0; } if (!RSA_blinding_on(pubKey->pkey.rsa, c)) { X509_free(cert); EVP_PKEY_free(pubKey); BIO_vfree(bio); BN_CTX_free(c); return 0; } retval = RSA_verify(NID_md5, md5_md, MD5_DIGEST_LENGTH, sfileMsg, sfsize, pubKey->pkey.rsa); RSA_blinding_off(pubKey->pkey.rsa); BN_CTX_free(c); } if (pubKey->type == EVP_PKEY_DSA) { fprintf(stderr, "ERROR: DSA keys are not supported.\n"); return 0; } EVP_PKEY_free(pubKey); X509_free(cert); BIO_vfree(bio); return retval; }
/* called by CSPFullPluginSession */ void RSA_CryptContext::init(const Context &context, bool encoding /*= true*/) { StLock<Mutex> _(gMutex()); if(mInitFlag && !opStarted()) { /* reusing - e.g. query followed by encrypt */ return; } /* optional mode to use alternate key class (e.g., decrypt with public key) */ CSSM_KEYCLASS keyClass; switch (context.getInt(CSSM_ATTRIBUTE_MODE)) { case CSSM_ALGMODE_PUBLIC_KEY: keyClass = CSSM_KEYCLASS_PUBLIC_KEY; break; case CSSM_ALGMODE_PRIVATE_KEY: keyClass = CSSM_KEYCLASS_PRIVATE_KEY; break; case CSSM_ALGMODE_NONE: /* default, not present in context: infer from op type */ keyClass = encoding ? CSSM_KEYCLASS_PUBLIC_KEY : CSSM_KEYCLASS_PRIVATE_KEY; break; default: CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_MODE); } /* fetch key from context */ if(mRsaKey == NULL) { assert(!opStarted()); CSSM_DATA label = {0, NULL}; mRsaKey = contextToRsaKey(context, session(), keyClass, encoding ? CSSM_KEYUSE_ENCRYPT : CSSM_KEYUSE_DECRYPT, mAllocdRsaKey, label); if(label.Data) { mLabel.copy(label); mOaep = true; free(label.Data); } } else { assert(opStarted()); } unsigned cipherBlockSize = RSA_size(mRsaKey); unsigned plainBlockSize; /* padding - not present means value zero, CSSM_PADDING_NONE */ uint32 padding = context.getInt(CSSM_ATTRIBUTE_PADDING); switch(padding) { case CSSM_PADDING_NONE: mPadding = RSA_NO_PADDING; plainBlockSize = cipherBlockSize; break; case CSSM_PADDING_PKCS1: mPadding = RSA_PKCS1_PADDING; plainBlockSize = cipherBlockSize - 11; break; case CSSM_PADDING_APPLE_SSLv2: rsaCryptDebug("RSA_CryptContext::init using CSSM_PADDING_APPLE_SSLv2"); mPadding = RSA_SSLV23_PADDING; plainBlockSize = cipherBlockSize - 11; break; default: rsaCryptDebug("RSA_CryptContext::init bad padding (0x%x)", (unsigned)padding); CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PADDING); } /* optional blinding attribute */ uint32 blinding = context.getInt(CSSM_ATTRIBUTE_RSA_BLINDING); if(blinding) { if(RSA_blinding_on(mRsaKey, NULL) <= 0) { /* actually no legit failures */ CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR); } } else { RSA_blinding_off(mRsaKey); } /* finally, have BlockCryptor set up its stuff. */ setup(encoding ? plainBlockSize : cipherBlockSize, // blockSizeIn encoding ? cipherBlockSize : plainBlockSize, // blockSizeOut false, // pkcs5Pad false, // needsFinal BCM_ECB, NULL); // IV mInitFlag = true; }
// Signing functions bool OSSLRSA::sign(PrivateKey* privateKey, const ByteString& dataToSign, ByteString& signature, const AsymMech::Type mechanism, const void* param /* = NULL */, const size_t paramLen /* = 0 */) { if (mechanism == AsymMech::RSA_PKCS) { // Separate implementation for RSA PKCS #1 signing without hash computation // Check if the private key is the right type if (!privateKey->isOfType(OSSLRSAPrivateKey::type)) { ERROR_MSG("Invalid key type supplied"); return false; } // In case of PKCS #1 signing the length of the input data may not exceed 40% of the // modulus size OSSLRSAPrivateKey* osslKey = (OSSLRSAPrivateKey*) privateKey; size_t allowedLen = osslKey->getN().size() - 11; if (dataToSign.size() > allowedLen) { ERROR_MSG("Data to sign exceeds maximum for PKCS #1 signature"); return false; } // Perform the signature operation signature.resize(osslKey->getN().size()); RSA* rsa = osslKey->getOSSLKey(); if (!RSA_blinding_on(rsa, NULL)) { ERROR_MSG("Failed to turn on blinding for OpenSSL RSA key"); return false; } int sigLen = RSA_private_encrypt(dataToSign.size(), (unsigned char*) dataToSign.const_byte_str(), &signature[0], rsa, RSA_PKCS1_PADDING); RSA_blinding_off(rsa); if (sigLen == -1) { ERROR_MSG("An error occurred while performing a PKCS #1 signature"); return false; } signature.resize(sigLen); return true; } else if (mechanism == AsymMech::RSA) { // Separate implementation for raw RSA signing // Check if the private key is the right type if (!privateKey->isOfType(OSSLRSAPrivateKey::type)) { ERROR_MSG("Invalid key type supplied"); return false; } // In case of raw RSA, the length of the input data must match the length of the modulus OSSLRSAPrivateKey* osslKey = (OSSLRSAPrivateKey*) privateKey; if (dataToSign.size() != osslKey->getN().size()) { ERROR_MSG("Size of data to sign does not match the modulus size"); return false; } // Perform the signature operation signature.resize(osslKey->getN().size()); RSA* rsa = osslKey->getOSSLKey(); if (!RSA_blinding_on(rsa, NULL)) { ERROR_MSG("Failed to turn on blinding for OpenSSL RSA key"); return false; } int sigLen = RSA_private_encrypt(dataToSign.size(), (unsigned char*) dataToSign.const_byte_str(), &signature[0], rsa, RSA_NO_PADDING); RSA_blinding_off(rsa); if (sigLen == -1) { ERROR_MSG("An error occurred while performing a raw RSA signature"); return false; } signature.resize(sigLen); return true; } else { // Call default implementation return AsymmetricAlgorithm::sign(privateKey, dataToSign, signature, mechanism, param, paramLen); } }
bool OSSLRSA::signFinal(ByteString& signature) { // Save necessary state before calling super class signFinal OSSLRSAPrivateKey* pk = (OSSLRSAPrivateKey*) currentPrivateKey; AsymMech::Type mechanism = currentMechanism; if (!AsymmetricAlgorithm::signFinal(signature)) { return false; } ByteString firstHash, secondHash; bool bFirstResult = pCurrentHash->hashFinal(firstHash); bool bSecondResult = (pSecondHash != NULL) ? pSecondHash->hashFinal(secondHash) : true; delete pCurrentHash; pCurrentHash = NULL; if (pSecondHash != NULL) { delete pSecondHash; pSecondHash = NULL; } if (!bFirstResult || !bSecondResult) { return false; } ByteString digest = firstHash + secondHash; // Resize the data block for the signature to the modulus size of the key signature.resize(pk->getN().size()); // Determine the signature NID type int type = 0; bool isPSS = false; const EVP_MD* hash = NULL; switch (mechanism) { case AsymMech::RSA_MD5_PKCS: type = NID_md5; break; case AsymMech::RSA_SHA1_PKCS: type = NID_sha1; break; case AsymMech::RSA_SHA224_PKCS: type = NID_sha224; break; case AsymMech::RSA_SHA256_PKCS: type = NID_sha256; break; case AsymMech::RSA_SHA384_PKCS: type = NID_sha384; break; case AsymMech::RSA_SHA512_PKCS: type = NID_sha512; break; case AsymMech::RSA_SHA1_PKCS_PSS: isPSS = true; hash = EVP_sha1(); break; case AsymMech::RSA_SHA224_PKCS_PSS: isPSS = true; hash = EVP_sha224(); break; case AsymMech::RSA_SHA256_PKCS_PSS: isPSS = true; hash = EVP_sha256(); break; case AsymMech::RSA_SHA384_PKCS_PSS: isPSS = true; hash = EVP_sha384(); break; case AsymMech::RSA_SHA512_PKCS_PSS: isPSS = true; hash = EVP_sha512(); break; case AsymMech::RSA_SSL: type = NID_md5_sha1; break; default: break; } // Perform the signature operation unsigned int sigLen = signature.size(); RSA* rsa = pk->getOSSLKey(); if (!RSA_blinding_on(rsa, NULL)) { ERROR_MSG("Failed to turn blinding on for OpenSSL RSA key"); return false; } bool rv; if (isPSS) { ByteString em; em.resize(pk->getN().size()); rv = (RSA_padding_add_PKCS1_PSS(pk->getOSSLKey(), &em[0], &digest[0], hash, sLen) == 1); if (!rv) { ERROR_MSG("RSA PSS padding failed (0x%08X)", ERR_get_error()); } else { int result = RSA_private_encrypt(em.size(), &em[0], &signature[0], pk->getOSSLKey(), RSA_NO_PADDING); if (result >= 0) { sigLen = result; rv = true; } else { rv = false; ERROR_MSG("RSA private encrypt failed (0x%08X)", ERR_get_error()); } } } else { rv = (RSA_sign(type, &digest[0], digest.size(), &signature[0], &sigLen, pk->getOSSLKey()) == 1); } RSA_blinding_off(rsa); signature.resize(sigLen); return rv; }
inline void rsa_key::disable_blinding() const { RSA_blinding_off(ptr().get()); }