Skip to content

Commit

Permalink
Merge pull request #17 from anakinxc/main
Browse files Browse the repository at this point in the history
YASL-0.1.1
  • Loading branch information
oeqqwq authored Nov 16, 2022
2 parents 8515e87 + 54b42c7 commit a1cd56d
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 87 deletions.
14 changes: 0 additions & 14 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,3 @@ rules_foreign_cc_dependencies(
register_preinstalled_tools = True,
)

load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")

# Hedron's Compile Commands Extractor for Bazel
# https://github.com/hedronvision/bazel-compile-commands-extractor
git_repository(
name = "hedron_compile_commands",
commit = "1d21dc390e20ecb24d73e9dbb439e971e0d30337",
remote = "https://gitee.com/anakin-xc/bazel-compile-commands-extractor.git",
shallow_since = "1644967664 -0800",
)

load("@hedron_compile_commands//:workspace_setup.bzl", "hedron_compile_commands_setup")

hedron_compile_commands_setup()
1 change: 1 addition & 0 deletions bazel/repositories.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")


def yasl_deps():
_rule_python()
_rules_foreign_cc()
Expand Down
22 changes: 15 additions & 7 deletions yasl/crypto/asymmetric_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -144,13 +144,21 @@ UniqueRsa CreateRsaFromX509(ByteContainerView x509_public_key) {
return UniqueRsa(rsa, ::RSA_free);
}

std::string GetPublicKeyFromRsa(const UniqueRsa& rsa) {
std::string GetPublicKeyFromRsa(const UniqueRsa& rsa, bool x509_pkey) {
std::string public_key;
{
UniqueBio bio(BIO_new(BIO_s_mem()), BIO_free);
YASL_ENFORCE(bio, "New bio failed.");
YASL_ENFORCE(PEM_write_bio_RSAPublicKey(bio.get(), rsa.get()),
"Write public key failed.");
if (x509_pkey) {
UniqueEVP unique_pkey(EVP_PKEY_new(), ::EVP_PKEY_free);
YASL_ENFORCE(EVP_PKEY_set1_RSA(unique_pkey.get(), rsa.get()),
"Convert rsa to pubkey failed.");
YASL_ENFORCE(PEM_write_bio_PUBKEY(bio.get(), unique_pkey.get()),
"Write public key failed.");
} else {
YASL_ENFORCE(PEM_write_bio_RSAPublicKey(bio.get(), rsa.get()),
"Write public key failed.");
}
int size = BIO_pending(bio.get());
YASL_ENFORCE_GT(size, 0, "Bad key size.");
public_key.resize(size);
Expand All @@ -160,15 +168,15 @@ std::string GetPublicKeyFromRsa(const UniqueRsa& rsa) {
return public_key;
}

std::tuple<std::string, std::string> CreateRsaKeyPair() {
std::tuple<std::string, std::string> CreateRsaKeyPair(bool x509_pkey) {
std::unique_ptr<BIGNUM, decltype(&BN_free)> exp(BN_new(), BN_free);
YASL_ENFORCE_EQ(BN_set_word(exp.get(), RSA_F4), 1, "BN_set_word failed.");
UniqueRsa rsa(RSA_new(), RSA_free);
YASL_ENFORCE(
RSA_generate_key_ex(rsa.get(), kRsaKeyBitSize, exp.get(), nullptr),
"Generate rsa key pair failed.");

std::string public_key = GetPublicKeyFromRsa(rsa);
std::string public_key = GetPublicKeyFromRsa(rsa, x509_pkey);

std::string private_key;
{
Expand Down Expand Up @@ -211,7 +219,7 @@ std::tuple<std::string, std::string> CreateRsaCertificateAndPrivateKey(
// - random serial number
std::random_device rd;
YASL_ENFORCE(ASN1_INTEGER_set(X509_get_serialNumber(x509.get()), rd()) == 1,
"ASN1_INTEGER_set failed");
"ASN1_INTEGER_set failed.");
// 3.2 valid range
X509_gmtime_adj(X509_get_notBefore(x509.get()), 0);
X509_gmtime_adj(X509_get_notAfter(x509.get()), days * kSecondsInDay);
Expand All @@ -232,7 +240,7 @@ std::tuple<std::string, std::string> CreateRsaCertificateAndPrivateKey(

// 3.5 self-signed: issuer name == name.
YASL_ENFORCE(X509_set_issuer_name(x509.get(), name) == 1,
"X509_set_issuer_name failed");
"X509_set_issuer_name failed.");
AddX509Extension(x509.get(), NID_basic_constraints, (char*)"CA:TRUE");
AddX509Extension(x509.get(), NID_subject_key_identifier, (char*)"hash");
// 3.6 Do self signing with sha256-rsa.
Expand Down
5 changes: 3 additions & 2 deletions yasl/crypto/asymmetric_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,11 @@ UniquePkey CreatePubPkeyFromSm2Pem(ByteContainerView pem);

std::tuple<std::string, std::string> CreateSm2KeyPair();

std::tuple<std::string, std::string> CreateRsaKeyPair();
std::tuple<std::string, std::string> CreateRsaKeyPair(bool x509_pkey = false);

UniqueRsa CreateRsaFromX509(ByteContainerView x509_public_key);
std::string GetPublicKeyFromRsa(const UniqueRsa& rsa);

std::string GetPublicKeyFromRsa(const UniqueRsa& rsa, bool x509_pkey = false);

std::tuple<std::string, std::string> CreateRsaCertificateAndPrivateKey(
const std::unordered_map<std::string, std::string>& subject_map,
Expand Down
48 changes: 21 additions & 27 deletions yasl/crypto/symmetric_crypto.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,13 @@
#include "openssl/crypto.h"
#include "openssl/err.h"
#include "openssl/evp.h"
#include "spdlog/spdlog.h"

#include "yasl/base/exception.h"

namespace yasl {
namespace {

constexpr size_t kBatchSize = 1024;

const EVP_CIPHER* CreateEvpCipher(SymmetricCrypto::CryptoType type) {
switch (type) {
case SymmetricCrypto::CryptoType::AES128_ECB:
Expand Down Expand Up @@ -124,21 +123,18 @@ void SymmetricCrypto::Decrypt(absl::Span<const uint8_t> ciphertext,
EVP_CIPHER_CTX_copy(ctx, dec_ctx_);
}

size_t left = plaintext.size();
size_t i = 0;

while (left > 0) {
int n = std::min<size_t>(left, kBatchSize);
int out_length;
int rc =
EVP_CipherUpdate(ctx, plaintext.data() + i * kBatchSize, &out_length,
ciphertext.data() + i * kBatchSize, n);
YASL_ENFORCE(rc, "Fail to decrypt, rc={}", rc);
i++;
left -= n;
}
EVP_CIPHER_CTX_set_padding(ctx, plaintext.size() % BlockSize());

int out_length;
int rc = EVP_CipherUpdate(ctx, plaintext.data(), &out_length,
ciphertext.data(), ciphertext.size());
YASL_ENFORCE(rc, "Fail to decrypt, rc={}", rc);

// Does not require `Finalize` for aligned inputs.
if (plaintext.size() % BlockSize() != 0) {
rc = EVP_CipherFinal(ctx, plaintext.data() + out_length, &out_length);
YASL_ENFORCE(rc, "Fail to finalize decrypt, rc={}", rc);
}

if ((type_ != SymmetricCrypto::CryptoType::AES128_ECB) &&
(type_ != SymmetricCrypto::CryptoType::SM4_ECB)) {
Expand Down Expand Up @@ -166,20 +162,18 @@ void SymmetricCrypto::Encrypt(absl::Span<const uint8_t> plaintext,
EVP_CIPHER_CTX_copy(ctx, enc_ctx_);
}

size_t left = plaintext.size();
size_t i = 0;

while (left > 0) {
int n = std::min<size_t>(left, kBatchSize);
int outlen;
int rc = EVP_CipherUpdate(ctx, ciphertext.data() + i * kBatchSize, &outlen,
plaintext.data() + i * kBatchSize, n);
YASL_ENFORCE(rc, "Fail to encrypt, rc={}", rc);
i++;
left -= n;
}
EVP_CIPHER_CTX_set_padding(ctx, ciphertext.size() % BlockSize());

int outlen;
int rc = EVP_CipherUpdate(ctx, ciphertext.data(), &outlen, plaintext.data(),
plaintext.size());
YASL_ENFORCE(rc, "Fail to encrypt, rc={}", rc);

// Does not require `Finalize` for aligned inputs.
if (ciphertext.size() % BlockSize() != 0) {
rc = EVP_CipherFinal(ctx, ciphertext.data() + outlen, &outlen);
YASL_ENFORCE(rc, "Fail to finalize encrypt, rc={}", rc);
}

if ((type_ != SymmetricCrypto::CryptoType::AES128_ECB) &&
(type_ != SymmetricCrypto::CryptoType::SM4_ECB)) {
Expand Down
67 changes: 39 additions & 28 deletions yasl/crypto/symmetric_crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,8 @@
namespace yasl {
namespace internal {

inline std::vector<uint128_t> EcbMakeContentBlocks(uint128_t count,
int nblocks) {
std::vector<uint128_t> ret(nblocks);
std::iota(ret.begin(), ret.end(), count);
return ret;
inline void EcbMakeContentBlocks(uint128_t count, absl::Span<uint128_t> buf) {
std::iota(buf.begin(), buf.end(), count);
}

} // namespace internal
Expand Down Expand Up @@ -119,34 +116,48 @@ inline uint64_t FillPseudoRandom(SymmetricCrypto::CryptoType crypto_type,
const size_t nblock = (nbytes + block_size - 1) / block_size;
const size_t padding_bytes = nbytes % block_size;

SymmetricCrypto crypto(crypto_type, seed, iv);
bool isCTR = (crypto_type == SymmetricCrypto::CryptoType::AES128_CTR ||
crypto_type == SymmetricCrypto::CryptoType::SM4_CTR);

if (padding_bytes == 0) {
// No padding, fast path
crypto.Encrypt(
internal::EcbMakeContentBlocks(count, nblock),
absl::MakeSpan(reinterpret_cast<uint128_t*>(out.data()), nblock));
std::unique_ptr<SymmetricCrypto> crypto;
if (isCTR) {
// CTR mode does not requires padding or manully build counter...
crypto = std::make_unique<SymmetricCrypto>(crypto_type, seed, count);
std::memset(out.data(), 0, nbytes);
auto bv = absl::MakeSpan(reinterpret_cast<uint8_t*>(out.data()), nbytes);
crypto->Encrypt(bv, bv);
} else {
if (crypto_type == SymmetricCrypto::CryptoType::AES128_ECB ||
crypto_type == SymmetricCrypto::CryptoType::SM4_ECB) {
if (nblock > 1) {
// first n-1 block
crypto.Encrypt(internal::EcbMakeContentBlocks(count, nblock - 1),
absl::MakeSpan(reinterpret_cast<uint128_t*>(out.data()),
nblock - 1));
}
// last padding block
uint128_t padding = count + nblock - 1;
padding = crypto.Encrypt(padding);
std::memcpy(reinterpret_cast<uint128_t*>(out.data()) + (nblock - 1),
&padding, padding_bytes);
crypto = std::make_unique<SymmetricCrypto>(crypto_type, seed, iv);
if (padding_bytes == 0) {
// No padding, fast path
auto s = absl::MakeSpan(reinterpret_cast<uint128_t*>(out.data()), nblock);
internal::EcbMakeContentBlocks(count, s);
crypto->Encrypt(s, s);
} else {
std::vector<uint128_t> cipher(nblock);
crypto.Encrypt(internal::EcbMakeContentBlocks(count, nblock),
absl::MakeSpan(cipher));
std::memcpy(out.data(), cipher.data(), nbytes);
if (crypto_type == SymmetricCrypto::CryptoType::AES128_ECB ||
crypto_type == SymmetricCrypto::CryptoType::SM4_ECB) {
if (nblock > 1) {
// first n-1 block
auto s = absl::MakeSpan(reinterpret_cast<uint128_t*>(out.data()),
nblock - 1);
internal::EcbMakeContentBlocks(count, s);
crypto->Encrypt(s, s);
}
// last padding block
uint128_t padding = count + nblock - 1;
padding = crypto->Encrypt(padding);
std::memcpy(reinterpret_cast<uint128_t*>(out.data()) + (nblock - 1),
&padding, padding_bytes);
} else {
std::vector<uint128_t> cipher(nblock);
auto s = absl::MakeSpan(cipher);
internal::EcbMakeContentBlocks(count, s);
crypto->Encrypt(s, s);
std::memcpy(out.data(), cipher.data(), nbytes);
}
}
}

return count + nblock;
}

Expand Down
29 changes: 20 additions & 9 deletions yasl/crypto/symmetric_crypto_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -211,21 +211,32 @@ TEST(SymmetricCrypto, WrongKey) {

TEST(SymmetricCrypto, PartialBlock) {
for (auto type : kTestTypes) {
if ((type == SymmetricCrypto::CryptoType::AES128_CTR) ||
(type == SymmetricCrypto::CryptoType::SM4_CTR))
continue;
bool isCTR = ((type == SymmetricCrypto::CryptoType::AES128_CTR) ||
(type == SymmetricCrypto::CryptoType::SM4_CTR));
SymmetricCrypto crypto(type, kKey1, kIv1);
auto plaintext = MakeVector(SymmetricCrypto::BlockSize() - 1);
std::vector<uint8_t> encrypted(plaintext.size());
ASSERT_THROW(crypto.Encrypt(plaintext, absl::MakeSpan(encrypted)),
Exception);
if (!isCTR) {
ASSERT_THROW(crypto.Encrypt(plaintext, absl::MakeSpan(encrypted)),
Exception);
} else {
crypto.Encrypt(plaintext, absl::MakeSpan(encrypted));
}

SymmetricCrypto crypto2(type, kKey1, kIv1);
std::vector<uint8_t> decrypted(encrypted.size());
ASSERT_THROW(crypto2.Decrypt(absl::MakeConstSpan(encrypted),
absl::MakeSpan(decrypted)),
Exception);
EXPECT_NE(decrypted, plaintext);
if (!isCTR) {
ASSERT_THROW(crypto2.Decrypt(absl::MakeConstSpan(encrypted),
absl::MakeSpan(decrypted)),
Exception);
} else {
crypto2.Decrypt(absl::MakeConstSpan(encrypted),
absl::MakeSpan(decrypted));
}
if (isCTR) {
// Partial block should work under CRT mode
EXPECT_EQ(decrypted, plaintext);
}
}
}

Expand Down

0 comments on commit a1cd56d

Please sign in to comment.