Fix RSA crypto.
GitOrigin-RevId: 8fd7350881e12ea81b05ab31c8756ff9f0a9305e
This commit is contained in:
parent
0d69e77689
commit
f615889953
@ -239,7 +239,6 @@ int pq_factorize(Slice pq_str, string *p_str, string *q_str) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*** AES ***/
|
||||
static void aes_ige_xcrypt(const UInt256 &aes_key, UInt256 *aes_iv, Slice from, MutableSlice to, bool encrypt_flag) {
|
||||
AES_KEY key;
|
||||
int err;
|
||||
@ -388,7 +387,6 @@ void sha256_final(Sha256State *state, MutableSlice output) {
|
||||
state->impl.reset();
|
||||
}
|
||||
|
||||
/*** md5 ***/
|
||||
void md5(Slice input, MutableSlice output) {
|
||||
CHECK(output.size() >= MD5_DIGEST_LENGTH);
|
||||
auto result = MD5(input.ubegin(), input.size(), output.ubegin());
|
||||
@ -440,6 +438,103 @@ void hmac_sha256(Slice key, Slice message, MutableSlice dest) {
|
||||
CHECK(len == dest.size());
|
||||
}
|
||||
|
||||
static int get_evp_pkey_type(EVP_PKEY *pkey) {
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
return EVP_PKEY_type(pkey->type);
|
||||
#else
|
||||
return EVP_PKEY_base_id(pkey);
|
||||
#endif
|
||||
}
|
||||
|
||||
Result<BufferSlice> rsa_encrypt_pkcs1_oaep(Slice public_key, Slice data) {
|
||||
BIO *mem_bio = BIO_new_mem_buf(const_cast<void *>(static_cast<const void *>(public_key.data())),
|
||||
narrow_cast<int>(public_key.size()));
|
||||
SCOPE_EXIT {
|
||||
BIO_vfree(mem_bio);
|
||||
};
|
||||
|
||||
EVP_PKEY *pkey = PEM_read_bio_PUBKEY(mem_bio, nullptr, nullptr, nullptr);
|
||||
if (!pkey) {
|
||||
return Status::Error("Cannot read public key");
|
||||
}
|
||||
SCOPE_EXIT {
|
||||
EVP_PKEY_free(pkey);
|
||||
};
|
||||
if (get_evp_pkey_type(pkey) != EVP_PKEY_RSA) {
|
||||
return Status::Error("Wrong key type, expected RSA");
|
||||
}
|
||||
|
||||
EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, nullptr);
|
||||
if (!ctx) {
|
||||
return Status::Error("Cannot create EVP_PKEY_CTX");
|
||||
}
|
||||
SCOPE_EXIT {
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
};
|
||||
|
||||
if (EVP_PKEY_encrypt_init(ctx) <= 0) {
|
||||
return Status::Error("Cannot init EVP_PKEY_CTX");
|
||||
}
|
||||
if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0) {
|
||||
return Status::Error("Cannot set RSA_PKCS1_OAEP padding in EVP_PKEY_CTX");
|
||||
}
|
||||
|
||||
size_t outlen;
|
||||
if (EVP_PKEY_encrypt(ctx, nullptr, &outlen, data.ubegin(), data.size()) <= 0) {
|
||||
return Status::Error("Cannot calculate encrypted length");
|
||||
}
|
||||
BufferSlice res(outlen);
|
||||
if (EVP_PKEY_encrypt(ctx, res.as_slice().ubegin(), &outlen, data.ubegin(), data.size()) <= 0) {
|
||||
// ERR_print_errors_fp(stderr);
|
||||
return Status::Error("Cannot encrypt");
|
||||
}
|
||||
return std::move(res);
|
||||
}
|
||||
|
||||
Result<BufferSlice> rsa_decrypt_pkcs1_oaep(Slice private_key, Slice data) {
|
||||
BIO *mem_bio = BIO_new_mem_buf(const_cast<void *>(static_cast<const void *>(private_key.data())),
|
||||
narrow_cast<int>(private_key.size()));
|
||||
SCOPE_EXIT {
|
||||
BIO_vfree(mem_bio);
|
||||
};
|
||||
|
||||
EVP_PKEY *pkey = PEM_read_bio_PrivateKey(mem_bio, nullptr, nullptr, nullptr);
|
||||
if (!pkey) {
|
||||
return Status::Error("Cannot read private key");
|
||||
}
|
||||
SCOPE_EXIT {
|
||||
EVP_PKEY_free(pkey);
|
||||
};
|
||||
if (get_evp_pkey_type(pkey) != EVP_PKEY_RSA) {
|
||||
return Status::Error("Wrong key type, expected RSA");
|
||||
}
|
||||
|
||||
EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, nullptr);
|
||||
if (!ctx) {
|
||||
return Status::Error("Cannot create EVP_PKEY_CTX");
|
||||
}
|
||||
SCOPE_EXIT {
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
};
|
||||
|
||||
if (EVP_PKEY_decrypt_init(ctx) <= 0) {
|
||||
return Status::Error("Cannot init EVP_PKEY_CTX");
|
||||
}
|
||||
if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0) {
|
||||
return Status::Error("Cannot set RSA_PKCS1_OAEP padding in EVP_PKEY_CTX");
|
||||
}
|
||||
|
||||
size_t outlen;
|
||||
if (EVP_PKEY_decrypt(ctx, nullptr, &outlen, data.ubegin(), data.size()) <= 0) {
|
||||
return Status::Error("Cannot calculate decrypted length");
|
||||
}
|
||||
BufferSlice res(outlen);
|
||||
if (EVP_PKEY_decrypt(ctx, res.as_slice().ubegin(), &outlen, data.ubegin(), data.size()) <= 0) {
|
||||
return Status::Error("Cannot decrypt");
|
||||
}
|
||||
return std::move(res);
|
||||
}
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
namespace {
|
||||
std::vector<RwMutex> &openssl_mutexes() {
|
||||
@ -557,101 +652,4 @@ uint64 crc64(Slice data) {
|
||||
return crc64_partial(data, static_cast<uint64>(-1)) ^ static_cast<uint64>(-1);
|
||||
}
|
||||
|
||||
static int get_evp_pkey_type(EVP_PKEY *pkey) {
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
return EVP_PKEY_type(pkey->type);
|
||||
#else
|
||||
return EVP_PKEY_base_id(pkey);
|
||||
#endif
|
||||
}
|
||||
|
||||
Result<BufferSlice> rsa_encrypt_pkcs1_oaep(Slice public_key, Slice data) {
|
||||
BIO *mem_bio = BIO_new_mem_buf(const_cast<void *>(static_cast<const void *>(public_key.data())),
|
||||
narrow_cast<int>(public_key.size()));
|
||||
SCOPE_EXIT {
|
||||
BIO_vfree(mem_bio);
|
||||
};
|
||||
|
||||
EVP_PKEY *pkey = PEM_read_bio_PUBKEY(mem_bio, nullptr, nullptr, nullptr);
|
||||
if (!pkey) {
|
||||
return Status::Error("Cannot read public key");
|
||||
}
|
||||
SCOPE_EXIT {
|
||||
EVP_PKEY_free(pkey);
|
||||
};
|
||||
if (get_evp_pkey_type(pkey) != EVP_PKEY_RSA) {
|
||||
return Status::Error("Wrong key type, expected RSA");
|
||||
}
|
||||
|
||||
EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, nullptr);
|
||||
if (!ctx) {
|
||||
return Status::Error("Cannot create EVP_PKEY_CTX");
|
||||
}
|
||||
SCOPE_EXIT {
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
};
|
||||
|
||||
if (EVP_PKEY_encrypt_init(ctx) <= 0) {
|
||||
return Status::Error("Cannot init EVP_PKEY_CTX");
|
||||
}
|
||||
if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0) {
|
||||
return Status::Error("Cannot set RSA_PKCS1_OAEP padding in EVP_PKEY_CTX");
|
||||
}
|
||||
|
||||
size_t outlen;
|
||||
if (EVP_PKEY_encrypt(ctx, nullptr, &outlen, data.ubegin(), data.size()) <= 0) {
|
||||
return Status::Error("Cannot calculate encrypted length");
|
||||
}
|
||||
BufferSlice res(outlen);
|
||||
if (EVP_PKEY_encrypt(ctx, res.as_slice().ubegin(), &outlen, data.ubegin(), data.size()) <= 0) {
|
||||
// ERR_print_errors_fp(stderr);
|
||||
return Status::Error("Cannot encrypt");
|
||||
}
|
||||
return std::move(res);
|
||||
}
|
||||
|
||||
Result<BufferSlice> rsa_decrypt_pkcs1_oaep(Slice private_key, Slice data) {
|
||||
BIO *mem_bio = BIO_new_mem_buf(const_cast<void *>(static_cast<const void *>(private_key.data())),
|
||||
narrow_cast<int>(private_key.size()));
|
||||
SCOPE_EXIT {
|
||||
BIO_vfree(mem_bio);
|
||||
};
|
||||
|
||||
EVP_PKEY *pkey = PEM_read_bio_PrivateKey(mem_bio, nullptr, nullptr, nullptr);
|
||||
if (!pkey) {
|
||||
return Status::Error("Cannot read private key");
|
||||
}
|
||||
SCOPE_EXIT {
|
||||
EVP_PKEY_free(pkey);
|
||||
};
|
||||
if (get_evp_pkey_type(pkey) != EVP_PKEY_RSA) {
|
||||
return Status::Error("Wrong key type, expected RSA");
|
||||
}
|
||||
|
||||
EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, nullptr);
|
||||
if (!ctx) {
|
||||
return Status::Error("Cannot create EVP_PKEY_CTX");
|
||||
}
|
||||
SCOPE_EXIT {
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
};
|
||||
|
||||
if (EVP_PKEY_decrypt_init(ctx) <= 0) {
|
||||
return Status::Error("Cannot init EVP_PKEY_CTX");
|
||||
}
|
||||
if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0) {
|
||||
return Status::Error("Cannot set RSA_PKCS1_OAEP padding in EVP_PKEY_CTX");
|
||||
}
|
||||
|
||||
size_t outlen;
|
||||
if (EVP_PKEY_decrypt(ctx, nullptr, &outlen, data.ubegin(), data.size()) <= 0) {
|
||||
return Status::Error("Cannot calculate decrypted length");
|
||||
}
|
||||
BufferSlice res(outlen);
|
||||
if (EVP_PKEY_decrypt(ctx, res.as_slice().ubegin(), &outlen, data.ubegin(), data.size()) <= 0) {
|
||||
return Status::Error("Cannot decrypt");
|
||||
}
|
||||
return std::move(res);
|
||||
}
|
||||
|
||||
} // namespace td
|
||||
|
Loading…
Reference in New Issue
Block a user