Skip to content

Commit

Permalink
Use new EncMaterial class for encryption/decryption.
Browse files Browse the repository at this point in the history
  • Loading branch information
ni4 committed Dec 25, 2024
1 parent b28b5cf commit 7187325
Show file tree
Hide file tree
Showing 10 changed files with 244 additions and 186 deletions.
15 changes: 4 additions & 11 deletions src/lib/crypto/ecdh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,11 +163,7 @@ validate_key(rnp::RNG &rng, const ec::Key &key, bool secret)
}

rnp_result_t
encrypt_pkcs5(rnp::RNG & rng,
Encrypted & out,
const rnp::secure_bytes & in,
const ec::Key & key,
const std::vector<uint8_t> &fp)
encrypt_pkcs5(rnp::RNG &rng, Encrypted &out, const rnp::secure_bytes &in, const ec::Key &key)
{
if (in.size() > MAX_SESSION_KEY_SIZE) {
return RNP_ERROR_BAD_PARAMETERS;
Expand All @@ -193,7 +189,7 @@ encrypt_pkcs5(rnp::RNG & rng,
// See 13.5 of RFC 4880 for definition of other_info size
const size_t kek_len = pgp_key_size(key.key_wrap_alg);
auto other_info =
kdf_other_info_serialize(*curve_desc, fp, key.kdf_hash_alg, key.key_wrap_alg);
kdf_other_info_serialize(*curve_desc, out.fp, key.kdf_hash_alg, key.key_wrap_alg);
assert(other_info.size() == curve_desc->OID.size() + 46);

rnp::botan::Privkey eph_prv_key;
Expand Down Expand Up @@ -253,10 +249,7 @@ encrypt_pkcs5(rnp::RNG & rng,
}

rnp_result_t
decrypt_pkcs5(rnp::secure_bytes & out,
const Encrypted & in,
const ec::Key & key,
const std::vector<uint8_t> &fp)
decrypt_pkcs5(rnp::secure_bytes &out, const Encrypted &in, const ec::Key &key)
{
if (!key.x.bytes()) {
return RNP_ERROR_BAD_PARAMETERS;
Expand All @@ -277,7 +270,7 @@ decrypt_pkcs5(rnp::secure_bytes & out,
}

// See 13.5 of RFC 4880 for definition of other_info_size
auto other_info = kdf_other_info_serialize(*curve_desc, fp, kdf_hash, wrap_alg);
auto other_info = kdf_other_info_serialize(*curve_desc, in.fp, kdf_hash, wrap_alg);
assert(other_info.size() == curve_desc->OID.size() + 46);

rnp::botan::Privkey prv_key;
Expand Down
15 changes: 5 additions & 10 deletions src/lib/crypto/ecdh.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,19 +70,17 @@ bool set_params(ec::Key &key, pgp_curve_t curve_id);
* as specified in RFC 3394
* @param in data to be encrypted
* @param key public key to be used for encryption
* @param fp fingerprint of the encrypting key
*
* @return RNP_SUCCESS on success and output parameters are populated
* @return RNP_ERROR_NOT_SUPPORTED unknown curve
* @return RNP_ERROR_BAD_PARAMETERS unexpected input provided
* @return RNP_ERROR_SHORT_BUFFER `wrapped_key_len' to small to store result
* @return RNP_ERROR_GENERIC implementation error
*/
rnp_result_t encrypt_pkcs5(rnp::RNG & rng,
Encrypted & out,
const rnp::secure_bytes & in,
const ec::Key & key,
const std::vector<uint8_t> &fp);
rnp_result_t encrypt_pkcs5(rnp::RNG & rng,
Encrypted & out,
const rnp::secure_bytes &in,
const ec::Key & key);

/*
* Decrypts session key with a KEK agreed during ECDH as specified in
Expand All @@ -104,10 +102,7 @@ rnp_result_t encrypt_pkcs5(rnp::RNG & rng,
* @return RNP_ERROR_SHORT_BUFFER `session_key_len' to small to store result
* @return RNP_ERROR_GENERIC decryption failed or implementation error
*/
rnp_result_t decrypt_pkcs5(rnp::secure_bytes & out,
const Encrypted & in,
const ec::Key & key,
const std::vector<uint8_t> &fp);
rnp_result_t decrypt_pkcs5(rnp::secure_bytes &out, const Encrypted &in, const ec::Key &key);
} // namespace ecdh
} // namespace pgp

Expand Down
15 changes: 4 additions & 11 deletions src/lib/crypto/ecdh_ossl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,11 +248,7 @@ ecdh_kek_len(pgp_symm_alg_t wrap_alg)
}

rnp_result_t
encrypt_pkcs5(rnp::RNG & rng,
Encrypted & out,
const rnp::secure_bytes & in,
const ec::Key & key,
const std::vector<uint8_t> &fp)
encrypt_pkcs5(rnp::RNG &rng, Encrypted &out, const rnp::secure_bytes &in, const ec::Key &key)
{
if (in.size() > MAX_SESSION_KEY_SIZE) {
return RNP_ERROR_BAD_PARAMETERS;
Expand Down Expand Up @@ -298,7 +294,7 @@ encrypt_pkcs5(rnp::RNG & rng,
}
/* here we got x value in sec, deriving kek */
rnp::secure_bytes kek(keklen, 0);
auto ret = derive_kek(sec, key, fp, kek);
auto ret = derive_kek(sec, key, out.fp, kek);
if (ret) {
/* LCOV_EXCL_START */
RNP_LOG("Failed to derive KEK.");
Expand Down Expand Up @@ -329,10 +325,7 @@ encrypt_pkcs5(rnp::RNG & rng,
}

rnp_result_t
decrypt_pkcs5(rnp::secure_bytes & out,
const Encrypted & in,
const ec::Key & key,
const std::vector<uint8_t> &fp)
decrypt_pkcs5(rnp::secure_bytes &out, const Encrypted &in, const ec::Key &key)
{
if (!key.x.bytes()) {
return RNP_ERROR_BAD_PARAMETERS;
Expand Down Expand Up @@ -368,7 +361,7 @@ decrypt_pkcs5(rnp::secure_bytes & out,
}
/* here we got x value in sec, deriving kek */
rnp::secure_bytes kek(keklen, 0);
auto ret = derive_kek(sec, key, fp, kek);
auto ret = derive_kek(sec, key, in.fp, kek);
if (ret) {
/* LCOV_EXCL_START */
RNP_LOG("Failed to derive KEK.");
Expand Down
156 changes: 102 additions & 54 deletions src/lib/key_material.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -322,17 +322,17 @@ KeyMaterial::generate(rnp::SecurityContext &ctx, const KeyParams &params)
}

rnp_result_t
KeyMaterial::encrypt(rnp::SecurityContext & ctx,
pgp_encrypted_material_t &out,
const rnp::secure_bytes & data) const
KeyMaterial::encrypt(rnp::SecurityContext & ctx,
EncMaterial & out,
const rnp::secure_bytes &data) const
{
return RNP_ERROR_NOT_SUPPORTED;
}

rnp_result_t
KeyMaterial::decrypt(rnp::SecurityContext & ctx,
rnp::secure_bytes & out,
const pgp_encrypted_material_t &in) const
KeyMaterial::decrypt(rnp::SecurityContext &ctx,
rnp::secure_bytes & out,
const EncMaterial & in) const
{
return RNP_ERROR_NOT_SUPPORTED;
}
Expand Down Expand Up @@ -562,19 +562,27 @@ RSAKeyMaterial::generate(rnp::SecurityContext &ctx, const KeyParams &params)
}

rnp_result_t
RSAKeyMaterial::encrypt(rnp::SecurityContext & ctx,
pgp_encrypted_material_t &out,
const rnp::secure_bytes & data) const
RSAKeyMaterial::encrypt(rnp::SecurityContext & ctx,
EncMaterial & out,
const rnp::secure_bytes &data) const
{
return key_.encrypt_pkcs1(ctx.rng, out.rsa, data);
auto rsa = dynamic_cast<pgp::RSAEncMaterial *>(&out);
if (!rsa) {
return RNP_ERROR_BAD_PARAMETERS;
}
return key_.encrypt_pkcs1(ctx.rng, rsa->enc, data);
}

rnp_result_t
RSAKeyMaterial::decrypt(rnp::SecurityContext & ctx,
rnp::secure_bytes & out,
const pgp_encrypted_material_t &in) const
RSAKeyMaterial::decrypt(rnp::SecurityContext &ctx,
rnp::secure_bytes & out,
const EncMaterial & in) const
{
return key_.decrypt_pkcs1(ctx.rng, out, in.rsa);
auto rsa = dynamic_cast<const pgp::RSAEncMaterial *>(&in);
if (!rsa) {
return RNP_ERROR_BAD_PARAMETERS;
}
return key_.decrypt_pkcs1(ctx.rng, out, rsa->enc);
}

rnp_result_t
Expand Down Expand Up @@ -892,19 +900,27 @@ EGKeyMaterial::generate(rnp::SecurityContext &ctx, const KeyParams &params)
}

rnp_result_t
EGKeyMaterial::encrypt(rnp::SecurityContext & ctx,
pgp_encrypted_material_t &out,
const rnp::secure_bytes & data) const
EGKeyMaterial::encrypt(rnp::SecurityContext & ctx,
EncMaterial & out,
const rnp::secure_bytes &data) const
{
return key_.encrypt_pkcs1(ctx.rng, out.eg, data);
auto eg = dynamic_cast<pgp::EGEncMaterial *>(&out);
if (!eg) {
return RNP_ERROR_BAD_PARAMETERS;
}
return key_.encrypt_pkcs1(ctx.rng, eg->enc, data);
}

rnp_result_t
EGKeyMaterial::decrypt(rnp::SecurityContext & ctx,
rnp::secure_bytes & out,
const pgp_encrypted_material_t &in) const
EGKeyMaterial::decrypt(rnp::SecurityContext &ctx,
rnp::secure_bytes & out,
const EncMaterial & in) const
{
return key_.decrypt_pkcs1(ctx.rng, out, in.eg);
auto eg = dynamic_cast<const pgp::EGEncMaterial *>(&in);
if (!eg) {
return RNP_ERROR_BAD_PARAMETERS;
}
return key_.decrypt_pkcs1(ctx.rng, out, eg->enc);
}

rnp_result_t
Expand Down Expand Up @@ -1201,21 +1217,25 @@ ECDHKeyMaterial::generate(rnp::SecurityContext &ctx, const KeyParams &params)
}

rnp_result_t
ECDHKeyMaterial::encrypt(rnp::SecurityContext & ctx,
pgp_encrypted_material_t &out,
const rnp::secure_bytes & data) const
ECDHKeyMaterial::encrypt(rnp::SecurityContext & ctx,
EncMaterial & out,
const rnp::secure_bytes &data) const
{
if (!ec::Curve::is_supported(key_.curve)) {
RNP_LOG("ECDH encrypt: curve %d is not supported.", key_.curve);
return RNP_ERROR_NOT_SUPPORTED;
}
return ecdh::encrypt_pkcs5(ctx.rng, out.ecdh, data, key_, out.ecdh.fp);
auto ecdh = dynamic_cast<pgp::ECDHEncMaterial *>(&out);
if (!ecdh) {
return RNP_ERROR_BAD_PARAMETERS;
}
return ecdh::encrypt_pkcs5(ctx.rng, ecdh->enc, data, key_);
}

rnp_result_t
ECDHKeyMaterial::decrypt(rnp::SecurityContext & ctx,
rnp::secure_bytes & out,
const pgp_encrypted_material_t &in) const
ECDHKeyMaterial::decrypt(rnp::SecurityContext &ctx,
rnp::secure_bytes & out,
const EncMaterial & in) const
{
if (!ec::Curve::is_supported(key_.curve)) {
RNP_LOG("ECDH decrypt: curve %d is not supported.", key_.curve);
Expand All @@ -1224,7 +1244,11 @@ ECDHKeyMaterial::decrypt(rnp::SecurityContext & ctx,
if ((key_.curve == PGP_CURVE_25519) && !x25519_bits_tweaked()) {
RNP_LOG("Warning: bits of 25519 secret key are not tweaked.");
}
return ecdh::decrypt_pkcs5(out, in.ecdh, key_, in.ecdh.fp);
auto ecdh = dynamic_cast<const pgp::ECDHEncMaterial *>(&in);
if (!ecdh) {
return RNP_ERROR_BAD_PARAMETERS;
}
return ecdh::decrypt_pkcs5(out, ecdh->enc, key_);
}

pgp_hash_alg_t
Expand Down Expand Up @@ -1307,25 +1331,33 @@ SM2KeyMaterial::clone()
}

rnp_result_t
SM2KeyMaterial::encrypt(rnp::SecurityContext & ctx,
pgp_encrypted_material_t &out,
const rnp::secure_bytes & data) const
SM2KeyMaterial::encrypt(rnp::SecurityContext & ctx,
EncMaterial & out,
const rnp::secure_bytes &data) const
{
#if defined(ENABLE_SM2)
return pgp::sm2::encrypt(ctx.rng, out.sm2, data, PGP_HASH_SM3, key_);
auto sm2 = dynamic_cast<pgp::SM2EncMaterial *>(&out);
if (!sm2) {
return RNP_ERROR_BAD_PARAMETERS;
}
return pgp::sm2::encrypt(ctx.rng, sm2->enc, data, PGP_HASH_SM3, key_);
#else
RNP_LOG("sm2_encrypt is not available");
return RNP_ERROR_NOT_IMPLEMENTED;
#endif
}

rnp_result_t
SM2KeyMaterial::decrypt(rnp::SecurityContext & ctx,
rnp::secure_bytes & out,
const pgp_encrypted_material_t &in) const
SM2KeyMaterial::decrypt(rnp::SecurityContext &ctx,
rnp::secure_bytes & out,
const EncMaterial & in) const
{
#if defined(ENABLE_SM2)
return pgp::sm2::decrypt(out, in.sm2, key_);
auto sm2 = dynamic_cast<const pgp::SM2EncMaterial *>(&in);
if (!sm2) {
return RNP_ERROR_BAD_PARAMETERS;
}
return pgp::sm2::decrypt(out, sm2->enc, key_);
#else
RNP_LOG("SM2 decryption is not available.");
return RNP_ERROR_NOT_IMPLEMENTED;
Expand Down Expand Up @@ -1591,21 +1623,29 @@ X25519KeyMaterial::generate(rnp::SecurityContext &ctx, const KeyParams &params)
}

rnp_result_t
X25519KeyMaterial::encrypt(rnp::SecurityContext & ctx,
pgp_encrypted_material_t &out,
const rnp::secure_bytes & data) const
X25519KeyMaterial::encrypt(rnp::SecurityContext & ctx,
EncMaterial & out,
const rnp::secure_bytes &data) const
{
return x25519_native_encrypt(&ctx.rng, key_.pub, data.data(), data.size(), &out.x25519);
auto x25519 = dynamic_cast<pgp::X25519EncMaterial *>(&out);
if (!x25519) {
return RNP_ERROR_BAD_PARAMETERS;
}
return x25519_native_encrypt(&ctx.rng, key_.pub, data.data(), data.size(), &x25519->enc);
}

rnp_result_t
X25519KeyMaterial::decrypt(rnp::SecurityContext & ctx,
rnp::secure_bytes & out,
const pgp_encrypted_material_t &in) const
X25519KeyMaterial::decrypt(rnp::SecurityContext &ctx,
rnp::secure_bytes & out,
const EncMaterial & in) const
{
auto x25519 = dynamic_cast<const pgp::X25519EncMaterial *>(&in);
if (!x25519) {
return RNP_ERROR_BAD_PARAMETERS;
}
out.resize(PGP_MPINT_SIZE);
size_t out_size = out.size();
auto ret = x25519_native_decrypt(&ctx.rng, key_, &in.x25519, out.data(), &out_size);
auto ret = x25519_native_decrypt(&ctx.rng, key_, &x25519->enc, out.data(), &out_size);
if (!ret) {
out.resize(out_size);
}
Expand Down Expand Up @@ -1722,21 +1762,29 @@ MlkemEcdhKeyMaterial::generate(rnp::SecurityContext &ctx, const KeyParams &param
}

rnp_result_t
MlkemEcdhKeyMaterial::encrypt(rnp::SecurityContext & ctx,
pgp_encrypted_material_t &out,
const rnp::secure_bytes & data) const
MlkemEcdhKeyMaterial::encrypt(rnp::SecurityContext & ctx,
EncMaterial & out,
const rnp::secure_bytes &data) const
{
return key_.pub.encrypt(&ctx.rng, &out.kyber_ecdh, data.data(), data.size());
auto mlkem = dynamic_cast<pgp::MlkemEcdhEncMaterial *>(&out);
if (!mlkem) {
return RNP_ERROR_BAD_PARAMETERS;
}
return key_.pub.encrypt(&ctx.rng, &mlkem->enc, data.data(), data.size());
}

rnp_result_t
MlkemEcdhKeyMaterial::decrypt(rnp::SecurityContext & ctx,
rnp::secure_bytes & out,
const pgp_encrypted_material_t &in) const
MlkemEcdhKeyMaterial::decrypt(rnp::SecurityContext &ctx,
rnp::secure_bytes & out,
const EncMaterial & in) const
{
auto mlkem = dynamic_cast<const pgp::MlkemEcdhEncMaterial *>(&in);
if (!mlkem) {
return RNP_ERROR_BAD_PARAMETERS;
}
out.resize(PGP_MPINT_SIZE);
size_t out_size = out.size();
auto ret = key_.priv.decrypt(&ctx.rng, out.data(), &out_size, &in.kyber_ecdh);
auto ret = key_.priv.decrypt(&ctx.rng, out.data(), &out_size, &mlkem->enc);
if (!ret) {
out.resize(out_size);
}
Expand Down
Loading

0 comments on commit 7187325

Please sign in to comment.