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:
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;