summaryrefslogtreecommitdiff
path: root/src/lib/crypt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/crypt.c')
-rw-r--r--src/lib/crypt.c579
1 files changed, 462 insertions, 117 deletions
diff --git a/src/lib/crypt.c b/src/lib/crypt.c
index 71197f6e..8ca7084f 100644
--- a/src/lib/crypt.c
+++ b/src/lib/crypt.c
@@ -27,10 +27,14 @@
#include <config.h>
#include <ouroboros/errno.h>
+#include <ouroboros/pthread.h>
#include <ouroboros/random.h>
#include <ouroboros/crypt.h>
+#include "crypt/keyrot.h"
+
#ifdef HAVE_OPENSSL
+#include <openssl/crypto.h>
#include <openssl/evp.h>
#include "crypt/openssl.h"
#endif
@@ -50,18 +54,12 @@ static const struct nid_map cipher_nid_map[] = {
{NID_aes_192_gcm, "aes-192-gcm"},
{NID_aes_256_gcm, "aes-256-gcm"},
{NID_chacha20_poly1305, "chacha20-poly1305"},
- {NID_aes_128_ctr, "aes-128-ctr"},
- {NID_aes_192_ctr, "aes-192-ctr"},
- {NID_aes_256_ctr, "aes-256-ctr"},
{NID_undef, NULL}
};
/* Ordered in strength preference, lowest first */
const uint16_t crypt_supported_nids[] = {
#ifdef HAVE_OPENSSL
- NID_aes_128_ctr,
- NID_aes_192_ctr,
- NID_aes_256_ctr,
NID_aes_128_gcm,
NID_aes_192_gcm,
NID_aes_256_gcm,
@@ -71,39 +69,43 @@ const uint16_t crypt_supported_nids[] = {
};
static const struct nid_map kex_nid_map[] = {
- {NID_X9_62_prime256v1, "prime256v1"},
- {NID_secp384r1, "secp384r1"},
- {NID_secp521r1, "secp521r1"},
- {NID_X25519, "X25519"},
- {NID_X448, "X448"},
- {NID_ffdhe2048, "ffdhe2048"},
- {NID_ffdhe3072, "ffdhe3072"},
- {NID_ffdhe4096, "ffdhe4096"},
- {NID_MLKEM512, "ML-KEM-512"},
- {NID_MLKEM768, "ML-KEM-768"},
- {NID_MLKEM1024, "ML-KEM-1024"},
- {NID_X25519MLKEM768, "X25519MLKEM768"},
- {NID_X448MLKEM1024, "X448MLKEM1024"},
- {NID_undef, NULL}
+ {NID_X9_62_prime256v1, "prime256v1"},
+ {NID_secp384r1, "secp384r1"},
+ {NID_secp521r1, "secp521r1"},
+ {NID_X25519, "X25519"},
+ {NID_X448, "X448"},
+ {NID_ffdhe2048, "ffdhe2048"},
+ {NID_ffdhe3072, "ffdhe3072"},
+ {NID_ffdhe4096, "ffdhe4096"},
+ {NID_MLKEM512, "ML-KEM-512"},
+ {NID_MLKEM768, "ML-KEM-768"},
+ {NID_MLKEM1024, "ML-KEM-1024"},
+ {NID_X25519MLKEM768, "X25519MLKEM768"},
+ {NID_X448MLKEM1024, "X448MLKEM1024"},
+ {NID_SecP256r1MLKEM768, "SecP256r1MLKEM768"},
+ {NID_SecP384r1MLKEM1024, "SecP384r1MLKEM1024"},
+ {NID_undef, NULL}
};
-/* Ordered in strength preference, lowest first */
+/* Ordered in strength preference, lowest first (NIST SP 800-57 levels) */
const uint16_t kex_supported_nids[] = {
#ifdef HAVE_OPENSSL
- NID_ffdhe2048,
- NID_X9_62_prime256v1,
- NID_X25519,
- NID_ffdhe3072,
- NID_secp384r1,
- NID_ffdhe4096,
- NID_X448,
- NID_secp521r1,
-#ifdef HAVE_OPENSSL_ML_KEM
- NID_MLKEM512,
- NID_MLKEM768,
- NID_MLKEM1024,
- NID_X25519MLKEM768,
- NID_X448MLKEM1024,
+ NID_ffdhe2048, /* FFDHE-2048, ~112-bit */
+ NID_X9_62_prime256v1, /* ECDH P-256, 128-bit */
+ NID_X25519, /* ECDH X25519, 128-bit */
+ NID_ffdhe3072, /* FFDHE-3072, ~128-bit */
+ NID_ffdhe4096, /* FFDHE-4096, ~152-bit */
+ NID_secp384r1, /* ECDH P-384, 192-bit */
+ NID_X448, /* ECDH X448, 224-bit */
+ NID_secp521r1, /* ECDH P-521, 256-bit */
+#ifdef HAVE_ML
+ NID_MLKEM512, /* ML-KEM-512, PQC L1 (~AES-128) */
+ NID_MLKEM768, /* ML-KEM-768, PQC L3 (~AES-192) */
+ NID_MLKEM1024, /* ML-KEM-1024, PQC L5 (~AES-256) */
+ NID_SecP256r1MLKEM768, /* P-256 + ML-KEM-768, PQC L3 */
+ NID_X25519MLKEM768, /* X25519 + ML-KEM-768, PQC L3 */
+ NID_SecP384r1MLKEM1024, /* P-384 + ML-KEM-1024, PQC L5 */
+ NID_X448MLKEM1024, /* X448 + ML-KEM-1024, PQC L5 */
#endif
#endif
NID_undef
@@ -137,11 +139,13 @@ const uint16_t md_supported_nids[] = {
};
struct crypt_ctx {
- void * ctx; /* Encryption context */
+ struct keyrot * kr; /* backend-independent key rotation */
+ void * cipher; /* backend AEAD cipher context */
};
struct auth_ctx {
- void * store;
+ void * store; /* trusted anchors */
+ void * chain; /* untrusted build-only interm */
};
static int parse_kex_value(const char * value,
@@ -162,6 +166,7 @@ int parse_sec_config(struct sec_config * cfg,
char * equals;
char * key;
char * value;
+ bool no_enc = false;
assert(cfg != NULL);
assert(fp != NULL);
@@ -172,6 +177,7 @@ int parse_sec_config(struct sec_config * cfg,
SET_KEX_KDF_NID(cfg, NID_sha256);
SET_KEX_CIPHER_NID(cfg, NID_aes_256_gcm);
SET_KEX_DIGEST_NID(cfg, NID_sha256);
+ /* a.req is seeded per-role by the caller; only auth= overrides it */
while (fgets(line, sizeof(line), fp) != NULL) {
char * trimmed;
@@ -180,12 +186,10 @@ int parse_sec_config(struct sec_config * cfg,
if (line[0] == '#' || line[0] == '\n')
continue;
- /* Check for 'none' keyword */
+ /* Bare 'none' keyword replaced by encryption=none */
trimmed = trim_whitespace(line);
- if (strcmp(trimmed, "none") == 0) {
- memset(cfg, 0, sizeof(*cfg));
- return 0;
- }
+ if (strcmp(trimmed, "none") == 0)
+ return -EINVAL;
/* Find the = separator */
equals = strchr(line, '=');
@@ -221,12 +225,54 @@ int parse_sec_config(struct sec_config * cfg,
} else {
return -EINVAL;
}
+ } else if (strcmp(key, "auth") == 0) {
+ if (strcmp(value, "required") == 0) {
+ cfg->a.req = true;
+ } else if (strcmp(value, "optional") == 0) {
+ cfg->a.req = false;
+ } else {
+ return -EINVAL;
+ }
+ } else if (strcmp(key, "cacert") == 0) {
+ if (strlen(value) >= sizeof(cfg->a.cacert))
+ return -EINVAL;
+ strcpy(cfg->a.cacert, value);
+ } else if (strcmp(key, "encryption") == 0) {
+ if (strcmp(value, "none") != 0)
+ return -EINVAL;
+ no_enc = true;
+ } else {
+ return -EINVAL;
}
}
+ if (no_enc) {
+ /* Digest stays: it belongs to the auth axis */
+ CLEAR_KEX_ALGO(cfg);
+ CLEAR_KEX_KDF(cfg);
+ CLEAR_KEX_CIPHER(cfg);
+ }
+
return 0;
}
+/*
+ * Not in header, but non-static for unit testing. Without a crypto
+ * backend a present security config is refused.
+ */
+int crypt_load_sec_config(struct sec_config * cfg,
+ FILE * fp)
+{
+ assert(cfg != NULL);
+ assert(fp != NULL);
+
+#ifndef HAVE_OPENSSL
+ return -ENOTSUP;
+#endif
+
+ return parse_sec_config(cfg, fp);
+}
+
/* Parse key exchange config from file */
int load_sec_config_file(struct sec_config * cfg,
const char * path)
@@ -239,12 +285,19 @@ int load_sec_config_file(struct sec_config * cfg,
fp = fopen(path, "r");
if (fp == NULL) {
- /* File doesn't exist - disable encryption */
- CLEAR_KEX_ALGO(cfg);
- return 0;
+ /* Absent config disables encryption; other errors fail */
+ if (errno == ENOENT) {
+ CLEAR_KEX_ALGO(cfg);
+ return 0;
+ }
+ return -errno;
}
- ret = parse_sec_config(cfg, fp);
+ pthread_cleanup_push(__cleanup_fclose, fp);
+
+ ret = crypt_load_sec_config(cfg, fp);
+
+ pthread_cleanup_pop(0);
fclose(fp);
@@ -329,14 +382,16 @@ ssize_t kex_kem_encap(buffer_t pk,
#endif
}
-ssize_t kex_kem_encap_raw(buffer_t pk,
- uint8_t * ct,
- int kdf,
- uint8_t * s)
+ssize_t kex_kem_encap_raw(const char * algo,
+ buffer_t pk,
+ uint8_t * ct,
+ int kdf,
+ uint8_t * s)
{
#ifdef HAVE_OPENSSL
- return openssl_kem_encap_raw(pk, ct, kdf, s);
+ return openssl_kem_encap_raw(algo, pk, ct, kdf, s);
#else
+ (void) algo;
(void) pk;
(void) ct;
(void) kdf;
@@ -378,19 +433,6 @@ int kex_get_algo_from_pk_der(buffer_t pk,
#endif
}
-int kex_get_algo_from_pk_raw(buffer_t pk,
- char * algo)
-{
-#ifdef HAVE_OPENSSL
- return openssl_get_algo_from_pk_raw(pk, algo);
-#else
- (void) pk;
- algo[0] = '\0';
-
- return -ECRYPT;
-#endif
-}
-
int kex_validate_algo(const char * algo)
{
if (algo == NULL)
@@ -498,6 +540,11 @@ int kex_validate_nid(int nid)
return -ENOTSUP;
}
+bool kex_nid_is_hybrid(uint16_t nid)
+{
+ return nid >= NID_HYBRID_KEM_MIN && nid <= NID_HYBRID_KEM_MAX;
+}
+
const char * md_nid_to_str(uint16_t nid)
{
const struct nid_map * p;
@@ -592,19 +639,71 @@ int crypt_kex_rank(int nid)
return -1;
}
-/* Hash length now returned by md_digest() */
+/* AEAD primitive: 1:1 backend wrappers used by the data path below. */
+static int crypt_seal(void * cipher,
+ const uint8_t * key,
+ const uint8_t * nonce,
+ buffer_t aad,
+ buffer_t in,
+ uint8_t * out,
+ uint8_t * tag)
+{
+#ifdef HAVE_OPENSSL
+ return openssl_seal(cipher, key, nonce, aad, in, out, tag);
+#else
+ (void) cipher;
+ (void) key;
+ (void) nonce;
+ (void) aad;
+ (void) in;
+ (void) out;
+ (void) tag;
-int crypt_encrypt(struct crypt_ctx * ctx,
- buffer_t in,
- buffer_t * out)
+ return -ECRYPT;
+#endif
+}
+
+static int crypt_open(void * cipher,
+ const uint8_t * key,
+ const uint8_t * nonce,
+ buffer_t aad,
+ buffer_t in,
+ const uint8_t * tag,
+ buffer_t * out)
{
- assert(ctx != NULL);
- assert(ctx->ctx != NULL);
+#ifdef HAVE_OPENSSL
+ return openssl_open(cipher, key, nonce, aad, in, tag, out);
+#else
+ (void) cipher;
+ (void) key;
+ (void) nonce;
+ (void) aad;
+ (void) in;
+ (void) tag;
+ (void) out;
+
+ return -ECRYPT;
+#endif
+}
+
+int crypt_oneshot_seal(int nid,
+ const uint8_t * key,
+ const uint8_t * nonce,
+ buffer_t aad,
+ buffer_t in,
+ buffer_t * out)
+{
+ assert(key != NULL);
+ assert(nonce != NULL);
+ assert(out != NULL);
#ifdef HAVE_OPENSSL
- return openssl_encrypt(ctx->ctx, in, out);
+ return openssl_oneshot_seal(nid, key, nonce, aad, in, out);
#else
- (void) ctx;
+ (void) nid;
+ (void) key;
+ (void) nonce;
+ (void) aad;
(void) in;
(void) out;
@@ -612,17 +711,24 @@ int crypt_encrypt(struct crypt_ctx * ctx,
#endif
}
-int crypt_decrypt(struct crypt_ctx * ctx,
- buffer_t in,
- buffer_t * out)
+int crypt_oneshot_open(int nid,
+ const uint8_t * key,
+ const uint8_t * nonce,
+ buffer_t aad,
+ buffer_t in,
+ buffer_t * out)
{
- assert(ctx != NULL);
- assert(ctx->ctx != NULL);
+ assert(key != NULL);
+ assert(nonce != NULL);
+ assert(out != NULL);
#ifdef HAVE_OPENSSL
- return openssl_decrypt(ctx->ctx, in, out);
+ return openssl_oneshot_open(nid, key, nonce, aad, in, out);
#else
- (void) ctx;
+ (void) nid;
+ (void) key;
+ (void) nonce;
+ (void) aad;
(void) in;
(void) out;
@@ -630,8 +736,122 @@ int crypt_decrypt(struct crypt_ctx * ctx,
#endif
}
+/*
+ * Data-path encrypt: rotate the key, frame selector ‖ ct ‖ tag, seal.
+ * Backend-agnostic: composed from keyrot_*, crypt_seal and crypt_get_tagsz.
+ */
+int crypt_encrypt(struct crypt_ctx * ctx,
+ buffer_t in,
+ buffer_t * out)
+{
+ uint8_t nonce[KR_NONCE_LEN];
+ const uint8_t * key;
+ uint8_t * ct;
+ buffer_t aad;
+ int tagsz;
+ int out_sz;
+
+ assert(ctx != NULL);
+ assert(ctx->kr != NULL);
+
+ tagsz = crypt_get_tagsz(ctx);
+ if (tagsz < 0)
+ return -ECRYPT;
+
+ out->data = malloc(KR_SELECTOR_LEN + in.len + (size_t) tagsz);
+ if (out->data == NULL)
+ goto fail_malloc;
+
+ ct = out->data + KR_SELECTOR_LEN;
+
+ /* keyrot writes the selector into the wire header (== AAD). */
+ if (keyrot_tx_next(ctx->kr, out->data, &key, nonce) != 0)
+ goto fail_encrypt;
+
+ aad.data = out->data;
+ aad.len = KR_SELECTOR_LEN;
+
+ out_sz = crypt_seal(ctx->cipher, key, nonce, aad, in, ct, ct + in.len);
+ if (out_sz < 0)
+ goto fail_encrypt;
+
+ out->len = KR_SELECTOR_LEN + (size_t) out_sz + (size_t) tagsz;
+
+ return 0;
+ fail_encrypt:
+ free(out->data);
+ fail_malloc:
+ clrbuf(*out);
+ return -ECRYPT;
+}
+
+/*
+ * Data-path decrypt: look up the rotated key from the selector, open, and
+ * commit the replay window only after the tag verifies.
+ */
+int crypt_decrypt(struct crypt_ctx * ctx,
+ buffer_t in,
+ buffer_t * out)
+{
+ uint8_t nonce[KR_NONCE_LEN];
+ const uint8_t * key;
+ const uint8_t * tag;
+ struct kr_rx rx;
+ buffer_t aad;
+ buffer_t ct;
+ int tagsz;
+ int in_sz;
+
+ assert(ctx != NULL);
+ assert(ctx->kr != NULL);
+
+ tagsz = crypt_get_tagsz(ctx);
+ if (tagsz < 0)
+ return -ECRYPT;
+
+ if (in.len < (size_t) (KR_SELECTOR_LEN + tagsz))
+ return -ECRYPT;
+
+ if (keyrot_rx_lookup(ctx->kr, in.data, &key, nonce, &rx) != 0)
+ return -ECRYPT;
+
+ in_sz = (int) in.len - KR_SELECTOR_LEN - tagsz;
+
+ /* +1 keeps malloc(0) defined for an empty (zero-length) frame. */
+ out->data = malloc((size_t) in_sz + 1);
+ if (out->data == NULL)
+ goto fail_malloc;
+
+ aad.data = in.data;
+ aad.len = KR_SELECTOR_LEN;
+
+ ct.data = in.data + KR_SELECTOR_LEN;
+ ct.len = (size_t) in_sz;
+
+ tag = in.data + KR_SELECTOR_LEN + in_sz;
+
+ if (crypt_open(ctx->cipher, key, nonce, aad, ct, tag, out) < 0)
+ goto fail_decrypt;
+
+ /* Commit replay state only after the tag verifies. */
+ if (keyrot_rx_commit(ctx->kr, &rx) != 0)
+ goto fail_decrypt;
+
+ return 0;
+ fail_decrypt:
+ free(out->data);
+ fail_malloc:
+ clrbuf(*out);
+ return -ECRYPT;
+}
+
struct crypt_ctx * crypt_create_ctx(struct crypt_sk * sk)
{
+#ifndef HAVE_OPENSSL
+ (void) sk;
+
+ return NULL; /* nothing to seal with */
+#else
struct crypt_ctx * crypt;
if (crypt_validate_nid(sk->nid) != 0)
@@ -643,18 +863,23 @@ struct crypt_ctx * crypt_create_ctx(struct crypt_sk * sk)
memset(crypt, 0, sizeof(*crypt));
-#ifdef HAVE_OPENSSL
- crypt->ctx = openssl_crypt_create_ctx(sk);
- if (crypt->ctx == NULL)
- goto fail_ctx;
-#endif
+ crypt->kr = keyrot_create(sk->key, sk->epoch, sk->role);
+ if (crypt->kr == NULL)
+ goto fail_kr;
+
+ crypt->cipher = openssl_crypt_create_ctx(sk);
+ if (crypt->cipher == NULL)
+ goto fail_cipher;
+
return crypt;
-#ifdef HAVE_OPENSSL
- fail_ctx:
+
+ fail_cipher:
+ keyrot_destroy(crypt->kr);
+ fail_kr:
free(crypt);
-#endif
fail_crypt:
return NULL;
+#endif
}
void crypt_destroy_ctx(struct crypt_ctx * crypt)
@@ -662,43 +887,76 @@ void crypt_destroy_ctx(struct crypt_ctx * crypt)
if (crypt == NULL)
return;
+ keyrot_destroy(crypt->kr);
#ifdef HAVE_OPENSSL
- assert(crypt->ctx != NULL);
- openssl_crypt_destroy_ctx(crypt->ctx);
-#else
- assert(crypt->ctx == NULL);
+ openssl_crypt_destroy_ctx(crypt->cipher);
#endif
free(crypt);
}
-int crypt_get_ivsz(struct crypt_ctx * ctx)
+int crypt_get_headsz(struct crypt_ctx * ctx)
{
- if (ctx == NULL)
- return -EINVAL;
+ assert(ctx != NULL);
+ assert(ctx->kr != NULL);
-#ifdef HAVE_OPENSSL
- assert(ctx->ctx != NULL);
- return openssl_crypt_get_ivsz(ctx->ctx);
-#else
- assert(ctx->ctx == NULL);
- return -ENOTSUP;
-#endif
+ (void) ctx; /* validated only; header size is a constant */
+
+ return KR_SELECTOR_LEN;
+}
+
+int crypt_rekey(struct crypt_ctx * ctx,
+ struct crypt_sk * sk)
+{
+ int ret;
+
+ assert(ctx != NULL);
+ assert(sk != NULL);
+ assert(ctx->kr != NULL);
+
+ ret = keyrot_rekey(ctx->kr, sk->key, sk->epoch);
+ if (ret == -EREPLAY)
+ return -EREPLAY;
+
+ return ret == 0 ? 0 : -ECRYPT;
}
int crypt_get_tagsz(struct crypt_ctx * ctx)
{
- if (ctx == NULL)
- return -EINVAL;
+ assert(ctx != NULL);
+ assert(ctx->cipher != NULL);
#ifdef HAVE_OPENSSL
- assert(ctx->ctx != NULL);
- return openssl_crypt_get_tagsz(ctx->ctx);
+ return openssl_crypt_get_tagsz(ctx->cipher);
#else
- assert(ctx->ctx == NULL);
+ (void) ctx;
return -ENOTSUP;
#endif
}
+int crypt_nodes_left(struct crypt_ctx * ctx)
+{
+ assert(ctx != NULL);
+ assert(ctx->kr != NULL);
+
+ return (int) keyrot_tx_nodes_left(ctx->kr);
+}
+
+int crypt_peer_synced(struct crypt_ctx * ctx)
+{
+ assert(ctx != NULL);
+ assert(ctx->kr != NULL);
+
+ return keyrot_peer_switched(ctx->kr) ? 1 : 0;
+}
+
+void crypt_tx_promote(struct crypt_ctx * ctx)
+{
+ assert(ctx != NULL);
+ assert(ctx->kr != NULL);
+
+ keyrot_tx_promote(ctx->kr);
+}
+
int crypt_load_privkey_file(const char * path,
void ** key)
{
@@ -709,7 +967,7 @@ int crypt_load_privkey_file(const char * path,
#else
(void) path;
- return 0;
+ return -ENOTSUP;
#endif
}
@@ -723,7 +981,7 @@ int crypt_load_privkey_str(const char * str,
#else
(void) str;
- return 0;
+ return -ENOTSUP;
#endif
}
@@ -737,7 +995,7 @@ int crypt_load_pubkey_str(const char * str,
#else
(void) str;
- return 0;
+ return -ENOTSUP;
#endif
}
@@ -751,7 +1009,7 @@ int crypt_load_pubkey_file(const char * path,
#else
(void) path;
- return 0;
+ return -ENOTSUP;
#endif
}
@@ -772,14 +1030,16 @@ int crypt_load_pubkey_file_to_der(const char * path,
}
int crypt_load_pubkey_raw_file(const char * path,
+ const char * algo,
buffer_t * buf)
{
assert(buf != NULL);
#ifdef HAVE_OPENSSL
- return openssl_load_pubkey_raw_file(path, buf);
+ return openssl_load_pubkey_raw_file(path, algo, buf);
#else
(void) path;
+ (void) algo;
buf->data = NULL;
buf->len = 0;
@@ -788,19 +1048,40 @@ int crypt_load_pubkey_raw_file(const char * path,
}
int crypt_load_privkey_raw_file(const char * path,
+ const char * algo,
void ** key)
{
*key = NULL;
#ifdef HAVE_OPENSSL
- return openssl_load_privkey_raw_file(path, key);
+ return openssl_load_privkey_raw_file(path, algo, key);
#else
(void) path;
+ (void) algo;
return 0;
#endif
}
+int crypt_ct_cmp(const void * a,
+ const void * b,
+ size_t len)
+{
+#ifdef HAVE_OPENSSL
+ return CRYPTO_memcmp(a, b, len);
+#else
+ const volatile uint8_t * pa = a;
+ const volatile uint8_t * pb = b;
+ uint8_t d = 0;
+ size_t i;
+
+ for (i = 0; i < len; i++)
+ d |= pa[i] ^ pb[i];
+
+ return d != 0;
+#endif
+}
+
int crypt_cmp_key(const void * key1,
const void * key2)
{
@@ -937,7 +1218,7 @@ int crypt_check_crt_name(void * crt,
(void) crt;
(void) name;
- return 0;
+ return -ENOTSUP;
#endif
}
@@ -967,9 +1248,15 @@ struct auth_ctx * auth_create_ctx(void)
ctx->store = openssl_auth_create_store();
if (ctx->store == NULL)
goto fail_store;
+
+ ctx->chain = openssl_auth_create_chain();
+ if (ctx->chain == NULL)
+ goto fail_chain;
#endif
return ctx;
#ifdef HAVE_OPENSSL
+ fail_chain:
+ openssl_auth_destroy_store(ctx->store);
fail_store:
free(ctx);
#endif
@@ -982,6 +1269,7 @@ void auth_destroy_ctx(struct auth_ctx * ctx)
if (ctx == NULL)
return;
#ifdef HAVE_OPENSSL
+ openssl_auth_destroy_chain(ctx->chain);
openssl_auth_destroy_store(ctx->store);
#endif
free(ctx);
@@ -1003,16 +1291,58 @@ int auth_add_crt_to_store(struct auth_ctx * ctx,
#endif
}
+int auth_add_crt_to_chain(struct auth_ctx * ctx,
+ void * crt)
+{
+ assert(ctx != NULL);
+ assert(crt != NULL);
+
+#ifdef HAVE_OPENSSL
+ return openssl_auth_add_crt_to_chain(ctx->chain, crt);
+#else
+ (void) ctx;
+ (void) crt;
+
+ return 0;
+#endif
+}
+
int auth_verify_crt(struct auth_ctx * ctx,
void * crt)
{
#ifdef HAVE_OPENSSL
- return openssl_verify_crt(ctx->store, crt);
+ return openssl_verify_crt(ctx->store, ctx->chain, crt);
#else
(void) ctx;
(void) crt;
- return 0;
+ return -ENOTSUP;
+#endif
+}
+
+int auth_verify_crt_pin(struct auth_ctx * ctx,
+ void * crt,
+ void * pin)
+{
+#ifdef HAVE_OPENSSL
+ return openssl_verify_crt_pin(ctx->store, ctx->chain, crt, pin);
+#else
+ (void) ctx;
+ (void) crt;
+ (void) pin;
+
+ return -ENOTSUP;
+#endif
+}
+
+bool crypt_pk_requires_md(const void * pk)
+{
+#ifdef HAVE_OPENSSL
+ return openssl_pk_requires_md((const EVP_PKEY *) pk);
+#else
+ (void) pk;
+
+ return false;
#endif
}
@@ -1048,7 +1378,7 @@ int auth_verify_sig(void * pk,
(void) msg;
(void) sig;
- return 0;
+ return -ENOTSUP;
#endif
}
@@ -1077,10 +1407,25 @@ ssize_t md_len(int md_nid)
#endif
}
+int crypt_hkdf_expand(buffer_t key,
+ buffer_t info,
+ buffer_t out)
+{
+#ifdef HAVE_OPENSSL
+ return openssl_hkdf_expand(key, info, out) == 0 ? 0 : -ECRYPT;
+#else
+ (void) key;
+ (void) info;
+ (void) out;
+
+ return -ECRYPT;
+#endif
+}
+
int crypt_secure_malloc_init(size_t max)
{
#ifdef HAVE_OPENSSL
- return openssl_secure_malloc_init(max, SECMEM_GUARD);
+ return openssl_secure_malloc_init(max, SECMEM_MINSIZE);
#else
(void) max;
return 0;