libqaeda

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

commit 3e8d05c6405fcf863a27d4b0d2abdcdabd0d2ac4
parent 9734f2f0f23e09432cca1dedc124b96e7be3f28f
Author: lash <dev@holbrook.no>
Date:   Fri,  4 Apr 2025 01:49:25 +0100

WIP decrypt mac and fix verify

Diffstat:
Msrc/crypto/gcrypt.c | 56++++++++++++++++++++++++++++++--------------------------
Msrc/lq/crypto.h | 2+-
Msrc/lq/err.c | 6++++--
Msrc/lq/err.h | 4++--
Msrc/test/Makefile | 14+++++++-------
Msrc/test/test_crypto.c | 15++++++++-------
6 files changed, 52 insertions(+), 45 deletions(-)

diff --git a/src/crypto/gcrypt.c b/src/crypto/gcrypt.c @@ -456,18 +456,7 @@ static int key_create(struct gpg_store *gpg) { return ERR_OK; } -// Create a new store instance using the crypto partition path -// set in the configuration. -// Caller must free it. -LQStore *key_store_get() { -// int r; -// char *p; - -// r = lq_config_get(gpg_cfg_idx_dir, (void**)&p); -// if (r) { -// return NULL; -// } -// return lq_store_new(p); +static LQStore *key_store_get() { return gpg_key_store; } @@ -493,6 +482,10 @@ static int key_create_store(struct gpg_store *gpg, const char *passphrase, size_ char passphrase_hash[LQ_DIGEST_LEN]; char mac[POLY1305_MAC_LEN]; + // Initialize to assist debugging. + lq_zero(buf_key, LQ_STORE_KEY_MAX); + lq_zero(buf_val, LQ_STORE_VAL_MAX); + // Create the private key and corresponding public key. r = key_create(gpg); if (r) { @@ -649,6 +642,10 @@ static int key_from_data(gcry_sexp_t *key, const char *indata, size_t indata_len return ERR_OK; } +static int check_ciphertext(const char *buf, size_t buf_len) { + return buf_len % (LQ_CRYPTO_BLOCKSIZE + CHACHA20_NONCE_LENGTH_BYTES + POLY1305_MAC_LEN); +} + /// Load a private key from the store's crypto partition. static int key_from_store(struct gpg_store *gpg, const char *passphrase, size_t passphrase_len) { char *nonce; @@ -683,6 +680,11 @@ static int key_from_store(struct gpg_store *gpg, const char *passphrase, size_t return ERR_NOENT; } + r = check_ciphertext(in, in_len); + if (r) { + return debug_logerr(LLOG_ERROR, ERR_CIPHER, "incorrect ciphertext"); + } + // Hash the encryption key to the expected length. r = calculate_digest_algo(passphrase, passphrase_len, passphrase_hash, gpg_passphrase_digest); if (r) { @@ -973,11 +975,12 @@ size_t lq_signature_bytes(LQSig *sig, char **out) { } int lq_signature_verify(LQSig *sig, const char *data, size_t data_len) { + char *p; int r; size_t c; gcry_mpi_t sig_r; gcry_mpi_t sig_s; - gcry_error_t err; + gcry_error_t e; gcry_sexp_t sigx; gcry_sexp_t msgx; gcry_sexp_t pubkey; @@ -990,14 +993,14 @@ int lq_signature_verify(LQSig *sig, const char *data, size_t data_len) { gpg = (struct gpg_store*)sig->pubkey->impl; c = 0; - err = gcry_sexp_build(&pubkey, &c, "(key-data(public-key(ecc(curve Ed25519)(q %b))))", LQ_PUBKEY_LEN, gpg->public_key); - if (err != GPG_ERR_NO_ERROR) { + e = gcry_sexp_build(&pubkey, &c, "(key-data(public-key(ecc(curve Ed25519)(q %b))))", LQ_PUBKEY_LEN, gpg->public_key); + if (e != GPG_ERR_NO_ERROR) { return ERR_KEYFAIL; } c = 0; - err = gcry_mpi_scan(&sig_r, GCRYMPI_FMT_STD, sig->impl, LQ_POINT_LEN, &c); - if (err != GPG_ERR_NO_ERROR) { + e = gcry_mpi_scan(&sig_r, GCRYMPI_FMT_STD, sig->impl, LQ_POINT_LEN, &c); + if (e != GPG_ERR_NO_ERROR) { gcry_sexp_release(pubkey); return ERR_KEYFAIL; } @@ -1008,8 +1011,8 @@ int lq_signature_verify(LQSig *sig, const char *data, size_t data_len) { } c = 0; - err = gcry_mpi_scan(&sig_s, GCRYMPI_FMT_STD, sig->impl + LQ_POINT_LEN, LQ_POINT_LEN, &c); - if (err != GPG_ERR_NO_ERROR) { + e = gcry_mpi_scan(&sig_s, GCRYMPI_FMT_STD, sig->impl + LQ_POINT_LEN, LQ_POINT_LEN, &c); + if (e != GPG_ERR_NO_ERROR) { gcry_mpi_release(sig_r); gcry_sexp_release(pubkey); return ERR_KEYFAIL; @@ -1022,8 +1025,8 @@ int lq_signature_verify(LQSig *sig, const char *data, size_t data_len) { } c = 0; - err = gcry_sexp_build(&sigx, &c, "(sig-val(eddsa(r %m)(s %m)))", sig_r, sig_s); - if (err != GPG_ERR_NO_ERROR) { + e = gcry_sexp_build(&sigx, &c, "(sig-val(eddsa(r %m)(s %m)))", sig_r, sig_s); + if (e != GPG_ERR_NO_ERROR) { gcry_mpi_release(sig_s); gcry_mpi_release(sig_r); gcry_sexp_release(pubkey); @@ -1040,19 +1043,20 @@ int lq_signature_verify(LQSig *sig, const char *data, size_t data_len) { } c = 0; - err = gcry_sexp_build(&msgx, &c, "(data(flags eddsa)(hash-algo sha512)(value %b))", LQ_DIGEST_LEN, digest); - if (err != GPG_ERR_NO_ERROR) { + e = gcry_sexp_build(&msgx, &c, "(data(flags eddsa)(hash-algo sha512)(value %b))", LQ_DIGEST_LEN, digest); + if (e != GPG_ERR_NO_ERROR) { gcry_sexp_release(sigx); gcry_sexp_release(pubkey); return ERR_DIGEST; } - err = gcry_pk_verify(sigx, msgx, pubkey); - if (err != GPG_ERR_NO_ERROR) { + e = gcry_pk_verify(sigx, msgx, pubkey); + if (e != GPG_ERR_NO_ERROR) { + p = gcry_strerror(e); gcry_sexp_release(msgx); gcry_sexp_release(sigx); gcry_sexp_release(pubkey); - return ERR_SIGVALID; + return debug_logerr(LLOG_INFO, ERR_SIGVALID, p); } gcry_sexp_release(msgx); diff --git a/src/lq/crypto.h b/src/lq/crypto.h @@ -32,7 +32,7 @@ #endif #ifndef LQ_CRYPTO_BUFLEN -#define LQ_CRYPTO_BUFLEN 524288 +#define LQ_CRYPTO_BUFLEN 65536 #endif #ifndef LQ_CRYPTO_BLOCKSIZE diff --git a/src/lq/err.c b/src/lq/err.c @@ -10,15 +10,17 @@ static char *_rerr[3] = { "Invalid response", }; -static char *_rerr_crypto[10] = { +static char *_rerr_crypto[12] = { "", "Crypto backend", "Key fail", "Key storage fail", + "Key unlock", + "Key lock", "Sign reject", - "Resource fail", "No key found", "Encryption", + "Digest", "Signature", "Invalid signature", }; diff --git a/src/lq/err.h b/src/lq/err.h @@ -20,8 +20,8 @@ enum err_e { ERR_NOKEY = 0x207, ERR_CIPHER = 0x208, ERR_DIGEST = 0x209, - ERR_SIGFAIL = 0x210, - ERR_SIGVALID = 0x211, + ERR_SIGFAIL = 0x20a, + ERR_SIGVALID = 0x20b, RERR_PFX_STORE = 0x300, ERR_STORE_AVAIL = 0x301, diff --git a/src/test/Makefile b/src/test/Makefile @@ -8,14 +8,14 @@ LDFLAGS := -lcheck $(LIBS) COMMONOBJS = ../mem/std.o ../lq/config.o ../lq/err.o ../lq/base.o ../debug.o all: build - CK_FORK=no LD_LIBRARY_PATH=`realpath ../aux/lib` ./test_test_bin - CK_FORK=no LD_LIBRARY_PATH=`realpath ../aux/lib` ./test_debug_bin - CK_FORK=no LD_LIBRARY_PATH=`realpath ../aux/lib` ./test_config_bin +# cK_FORK=no LD_LIBRARY_PATH=`realpath ../aux/lib` ./test_test_bin +# CK_FORK=no LD_LIBRARY_PATH=`realpath ../aux/lib` ./test_debug_bin +# CK_FORK=no LD_LIBRARY_PATH=`realpath ../aux/lib` ./test_config_bin CK_FORK=no LD_LIBRARY_PATH=`realpath ../aux/lib` ./test_crypto_bin - CK_FORK=no LD_LIBRARY_PATH=`realpath ../aux/lib` ./test_msg_bin - CK_FORK=no LD_LIBRARY_PATH=`realpath ../aux/lib` ./test_cert_bin - CK_FORK=no LD_LIBRARY_PATH=`realpath ../aux/lib` ./test_trust_bin - CK_FORK=no LD_LIBRARY_PATH=`realpath ../aux/lib` ./test_store_bin +# CK_FORK=no LD_LIBRARY_PATH=`realpath ../aux/lib` ./test_msg_bin +# CK_FORK=no LD_LIBRARY_PATH=`realpath ../aux/lib` ./test_cert_bin +# CK_FORK=no LD_LIBRARY_PATH=`realpath ../aux/lib` ./test_trust_bin +# CK_FORK=no LD_LIBRARY_PATH=`realpath ../aux/lib` ./test_store_bin test: all diff --git a/src/test/test_crypto.c b/src/test/test_crypto.c @@ -112,6 +112,7 @@ START_TEST(check_verify) { ck_assert_ptr_nonnull(sig); r = lq_signature_verify(sig, data, strlen(data)); + ck_assert_int_eq(r, 0); lq_signature_free(sig); lq_privatekey_free(pk); @@ -179,14 +180,14 @@ Suite * common_suite(void) { s = suite_create("crypto"); tc = tcase_create("file"); - tcase_add_test(tc, check_digest); - tcase_add_test(tc, check_privatekey); - tcase_add_test(tc, check_publickey); - tcase_add_test(tc, check_signature); +// tcase_add_test(tc, check_digest); +// tcase_add_test(tc, check_privatekey); +// tcase_add_test(tc, check_publickey); +// tcase_add_test(tc, check_signature); tcase_add_test(tc, check_verify); - tcase_add_test(tc, check_create_load); - tcase_add_test(tc, check_load_specific); - tcase_add_test(tc, check_many); +// tcase_add_test(tc, check_create_load); +// tcase_add_test(tc, check_load_specific); +// tcase_add_test(tc, check_many); suite_add_tcase(s, tc); return s;