libqaeda

Unnamed repository; edit this file 'description' to name the repository.
Info | Log | Files | Refs | README | LICENSE

commit 2f17205db6e857c4f87167fc4920a8357accc674
parent 01b9e92a8746114f6759449e5682d52463653fdd
Author: lash <dev@holbrook.no>
Date:   Wed,  5 Mar 2025 16:18:40 +0000

Add passphrase private key encryption everywhere

Diffstat:
Msrc/crypto/dummy.c | 27++++++++++++++++-----------
Msrc/lq/crypto.h | 9++++++---
Msrc/test/test_cert.c | 12++++++------
Msrc/test/test_crypto.c | 16+++++++++++++---
4 files changed, 41 insertions(+), 23 deletions(-)

diff --git a/src/crypto/dummy.c b/src/crypto/dummy.c @@ -48,18 +48,19 @@ struct dummycrypto { size_t len; ///< Length of private key data. }; -void keylock_xor(LQPrivKey *pk) { +void keylock_xor(LQPrivKey *pk, const char *passphrase_digest) { int i; struct dummycrypto *o; o = (struct dummycrypto*)pk->impl; - for (i = 0; i < 32; i++) { + for (i = 0; i < LQ_PRIVKEY_LEN; i++) { *((char*)o->data+i) ^= encrypt_dummy_transport[i]; } } -int lq_privatekey_unlock(LQPrivKey *pk, const char *passphrase) { +int lq_privatekey_unlock(LQPrivKey *pk, const char *passphrase, size_t passphrase_len) { char b; + char digest[LQ_DIGEST_LEN]; if (pk == NULL) { return ERR_INIT; @@ -67,27 +68,29 @@ int lq_privatekey_unlock(LQPrivKey *pk, const char *passphrase) { if ((pk->key_state & LQ_KEY_LOCK) == 0) { return ERR_NOOP; } - keylock_xor(pk); + lq_digest(passphrase, passphrase_len, digest); + keylock_xor(pk, digest); b = LQ_KEY_LOCK; pk->key_state &= ~b; return 0; } -int lq_privatekey_lock(LQPrivKey *pk, const char *passphrase) { - char b; +int lq_privatekey_lock(LQPrivKey *pk, const char *passphrase, size_t passphrase_len) { + char digest[LQ_DIGEST_LEN]; if (pk == NULL) { return ERR_INIT; } - if ((pk->key_state & LQ_KEY_LOCK) == 0) { + if ((pk->key_state & LQ_KEY_LOCK) > 0) { return ERR_NOOP; } - keylock_xor(pk); + lq_digest(passphrase, passphrase_len, digest); + keylock_xor(pk, digest); pk->key_state |= LQ_KEY_LOCK; return 0; } -LQPrivKey* lq_privatekey_new(const char *seed, size_t seed_len) { +LQPrivKey* lq_privatekey_new(const char *seed, size_t seed_len, const char *passphrase, size_t passphrase_len) { LQPrivKey *pk; struct dummycrypto *o; @@ -97,9 +100,11 @@ LQPrivKey* lq_privatekey_new(const char *seed, size_t seed_len) { lq_cpy(o->data, seed, seed_len); o->len = seed_len; pk->impl = o; - pk->key_state = 0; - pk->key_state |= LQ_KEY_LOCK; pk->key_typ = 0; + pk->key_state = 0; + if (passphrase != NULL) { + lq_privatekey_lock(pk, passphrase, passphrase_len); + } return pk; } diff --git a/src/lq/crypto.h b/src/lq/crypto.h @@ -70,12 +70,15 @@ typedef struct lq_signature_t LQSig; /** * @brief Create a new private key * + * If passphrase is not null the passphrase will be encrypted using that passphrase by default. + * * @param[in] Key material. If NULL, a new random private key will be generated. * @param[in] Length of key material. Ignored if seed parameter is NULL. + * @param[in] Encryption passphrase for key. * @return Pointer to new private key. Freeing the object is the caller's responsibility. * @see lq_privatekey_free */ -LQPrivKey* lq_privatekey_new(const char *seed, size_t seed_len); +LQPrivKey* lq_privatekey_new(const char *seed, size_t seed_len, const char *passphrase, size_t passphrase_len); /** * @brief Get raw private key bytes @@ -121,7 +124,7 @@ size_t lq_publickey_bytes(LQPubKey *pubk, char **out); * @param[in] Private Key object * @return ERR_OK if encrypted, ERR_NOOP if already encrypted, or ERR_INIT if encryption fails. */ -int lq_privatekey_lock(LQPrivKey *pk, const char *passphrase); +int lq_privatekey_lock(LQPrivKey *pk, const char *passphrase, size_t passphrase_len); /** * @brief Decrypt private key in place. @@ -129,7 +132,7 @@ int lq_privatekey_lock(LQPrivKey *pk, const char *passphrase); * @param[in] Private Key object * @return ERR_OK if decrypted, ERR_NOOP if not encrypted, or ERR_INIT if decryption fails. */ -int lq_privatekey_unlock(LQPrivKey *pk, const char *passphrase); +int lq_privatekey_unlock(LQPrivKey *pk, const char *passphrase, size_t passphrase_len); /** * @brief Sign digest data using a private key. diff --git a/src/test/test_cert.c b/src/test/test_cert.c @@ -78,11 +78,11 @@ START_TEST(check_cert_symmetric_req_sig) { LQCtx ctx; char buf[4096]; - pk = lq_privatekey_new(privkeydata, 32); + pk = lq_privatekey_new(privkeydata, 32, passphrase, 32); lq_set(&ctx, 0, sizeof(LQCtx)); req = lq_msg_new(data, strlen(data) + 1); cert = lq_certificate_new(NULL, &ctx, req, NULL); - lq_privatekey_unlock(pk, passphrase); + lq_privatekey_unlock(pk, passphrase, 32); r = lq_certificate_sign(cert, pk); ck_assert_int_eq(r, 0); @@ -107,12 +107,12 @@ START_TEST(check_cert_symmetric_rsp_onesig) { LQCtx ctx; char buf[4096]; - pk = lq_privatekey_new(data, 32); + pk = lq_privatekey_new(privkeydata, 32, passphrase, 32); lq_set(&ctx, 0, sizeof(LQCtx)); req = lq_msg_new(data, strlen(data) + 1); rsp = lq_msg_new(data_two, strlen(data_two) + 1); cert = lq_certificate_new(NULL, &ctx, req, NULL); - lq_privatekey_unlock(pk, passphrase); + lq_privatekey_unlock(pk, passphrase, 32); r = lq_certificate_sign(cert, pk); ck_assert_int_eq(r, 0); cert->response = rsp; @@ -137,11 +137,11 @@ START_TEST(check_cert_symmetric_rsp_bothsig) { LQCtx ctx; char buf[4096]; - pk = lq_privatekey_new(data, 32); + pk = lq_privatekey_new(privkeydata, 32, passphrase, 32); lq_set(&ctx, 0, sizeof(LQCtx)); req = lq_msg_new(data, strlen(data) + 1); cert = lq_certificate_new(NULL, &ctx, req, NULL); - lq_privatekey_unlock(pk, passphrase); + lq_privatekey_unlock(pk, passphrase, 32); r = lq_certificate_sign(cert, pk); ck_assert_int_eq(r, 0); diff --git a/src/test/test_crypto.c b/src/test/test_crypto.c @@ -39,6 +39,15 @@ START_TEST(check_digest) { } END_TEST +START_TEST(check_privatekey) { + int r; + LQPrivKey *pk; + + pk = lq_privatekey_new(privkeydata, 32, NULL, 0); + lq_privatekey_free(pk); +} +END_TEST + START_TEST(check_publickey) { LQPrivKey *pk; LQPubKey *pubk; @@ -46,7 +55,7 @@ START_TEST(check_publickey) { char *keydata; char *keydata_manual; - pk = lq_privatekey_new(privkeydata, 32); + pk = lq_privatekey_new(privkeydata, 32, passphrase, 32); pubk = lq_publickey_from_privatekey(pk); lq_publickey_bytes(pubk, &keydata); pubk_manual = lq_publickey_new(keydata); @@ -65,12 +74,12 @@ START_TEST(check_signature) { LQSig *sig; char *sigdata; - pk = lq_privatekey_new(privkeydata, 32); + pk = lq_privatekey_new(privkeydata, 32, passphrase, 32); lq_digest(data, strlen(data), (char*)digest); sig = lq_privatekey_sign(pk, digest, 32, salt); ck_assert_ptr_null(sig); - r = lq_privatekey_unlock(pk, passphrase); + r = lq_privatekey_unlock(pk, passphrase, 32); ck_assert_int_eq(r, 0); sig = lq_privatekey_sign(pk, digest, 32, salt); @@ -92,6 +101,7 @@ Suite * common_suite(void) { s = suite_create("crypto"); tc = tcase_create("dummy"); tcase_add_test(tc, check_digest); + tcase_add_test(tc, check_privatekey); tcase_add_test(tc, check_publickey); tcase_add_test(tc, check_signature); suite_add_tcase(s, tc);