diff options
author | Dimitri Staessens <dimitri@ouroboros.rocks> | 2023-09-29 13:15:00 +0200 |
---|---|---|
committer | Sander Vrijders <sander@ouroboros.rocks> | 2023-10-25 09:51:35 +0200 |
commit | fd3381002564c87b85feb2d1947a588e8ca6fdf9 (patch) | |
tree | b24d89230eb0eab26f18c0de4d714c09884b686e | |
parent | 3662d75fa3a2cbe52fd9008754b1b6222342308d (diff) | |
download | ouroboros-fd3381002564c87b85feb2d1947a588e8ca6fdf9.tar.gz ouroboros-fd3381002564c87b85feb2d1947a588e8ca6fdf9.zip |
lib: Make crypt.c independent source file
The cryptography functions were in a C source that was directly
imported into dev.c, enabling ECDHE+AES256 symmetric key encryption on
flows. Now crypt.c is an independent source file with associated
crypt.h header, to prepare for security management and configuration
in the IRMd.
Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks>
Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
-rw-r--r-- | include/ouroboros/crypt.h | 56 | ||||
-rw-r--r-- | src/lib/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/lib/crypt.c | 89 | ||||
-rw-r--r-- | src/lib/dev.c | 30 | ||||
-rw-r--r-- | src/lib/frct.c | 2 | ||||
-rw-r--r-- | src/tools/oping/oping_client.c | 2 |
6 files changed, 125 insertions, 55 deletions
diff --git a/include/ouroboros/crypt.h b/include/ouroboros/crypt.h new file mode 100644 index 00000000..dd58d798 --- /dev/null +++ b/include/ouroboros/crypt.h @@ -0,0 +1,56 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2023 + * + * Cryptography + * + * Dimitri Staessens <dimitri@ouroboros.rocks> + * Sander Vrijders <sander@ouroboros.rocks> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., http://www.fsf.org/about/contact/. + */ + +#ifndef OUROBOROS_LIB_CRYPT_H +#define OUROBOROS_LIB_CRYPT_H + +#include <ouroboros/shm_du_buff.h> + +#define SYMMKEYSZ 32 + +struct crypt_info { + uint16_t flags; + void * ctx; + uint8_t key[SYMMKEYSZ]; +}; + +int crypt_dh_pkp_create(void ** pkp, + uint8_t * pk); + +void crypt_dh_pkp_destroy(void * pkp); + +int crypt_dh_derive(void * pkp, + uint8_t * pk, + size_t len, + uint8_t * s); + +int crypt_encrypt(struct crypt_info * info, + struct shm_du_buff * sdb); + +int crypt_decrypt(struct crypt_info * info, + struct shm_du_buff * sdb); + +int crypt_init(struct crypt_info * info); + +void crypt_fini(struct crypt_info * info); + +#endif /* OUROBOROS_LIB_CRYPT_H */
\ No newline at end of file diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index b75fd0e0..514d60d4 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -253,6 +253,7 @@ set(SOURCE_FILES_COMMON bitmap.c btree.c crc32.c + crypt.c hash.c list.c lockfile.c diff --git a/src/lib/crypt.c b/src/lib/crypt.c index 600ff3d1..c5d6101a 100644 --- a/src/lib/crypt.c +++ b/src/lib/crypt.c @@ -20,9 +20,19 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., http://www.fsf.org/about/contact/. */ +#include <config.h> + +#include <ouroboros/crypt.h> +#include <ouroboros/errno.h> + +#include <assert.h> +#include <string.h> #ifdef HAVE_OPENSSL +#include <ouroboros/hash.h> +#include <ouroboros/random.h> + #include <openssl/evp.h> #include <openssl/ec.h> #include <openssl/pem.h> @@ -202,7 +212,8 @@ static int openssl_ecdh_derive(void * pkp, * encryption context for each packet. */ -static int openssl_encrypt(struct flow * f, +static int openssl_encrypt(void * ctx, + uint8_t * key, struct shm_du_buff * sdb) { uint8_t * out; @@ -226,24 +237,24 @@ static int openssl_encrypt(struct flow * f, if (out == NULL) goto fail_iv; - EVP_CIPHER_CTX_reset(f->ctx); + EVP_CIPHER_CTX_reset(ctx); - ret = EVP_EncryptInit_ex(f->ctx, EVP_aes_256_cbc(), NULL, f->key, iv); + ret = EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv); if (ret != 1) goto fail_encrypt_init; - ret = EVP_EncryptUpdate(f->ctx, out, &tmp_sz, in, in_sz); + ret = EVP_EncryptUpdate(ctx, out, &tmp_sz, in, in_sz); if (ret != 1) goto fail_encrypt; out_sz = tmp_sz; - ret = EVP_EncryptFinal_ex(f->ctx, out + tmp_sz, &tmp_sz); + ret = EVP_EncryptFinal_ex(ctx, out + tmp_sz, &tmp_sz); if (ret != 1) goto fail_encrypt; out_sz += tmp_sz; - EVP_CIPHER_CTX_cleanup(f->ctx); + EVP_CIPHER_CTX_cleanup(ctx); assert(out_sz >= in_sz); @@ -264,14 +275,15 @@ static int openssl_encrypt(struct flow * f, fail_tail_alloc: shm_du_buff_head_release(sdb, IVSZ); fail_encrypt: - EVP_CIPHER_CTX_cleanup(f->ctx); + EVP_CIPHER_CTX_cleanup(ctx); fail_encrypt_init: free(out); fail_iv: return -ECRYPT; } -static int openssl_decrypt(struct flow * f, +static int openssl_decrypt(void * ctx, + uint8_t * key, struct shm_du_buff * sdb) { uint8_t * in; @@ -297,19 +309,19 @@ static int openssl_decrypt(struct flow * f, if (out == NULL) goto fail_malloc; - EVP_CIPHER_CTX_reset(f->ctx); + EVP_CIPHER_CTX_reset(ctx); - ret = EVP_DecryptInit_ex(f->ctx, EVP_aes_256_cbc(), NULL, f->key, iv); + ret = EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv); if (ret != 1) goto fail_decrypt_init; - ret = EVP_DecryptUpdate(f->ctx, out, &tmp_sz, in, in_sz); + ret = EVP_DecryptUpdate(ctx, out, &tmp_sz, in, in_sz); if (ret != 1) goto fail_decrypt; out_sz = tmp_sz; - ret = EVP_DecryptFinal_ex(f->ctx, out + tmp_sz, &tmp_sz); + ret = EVP_DecryptFinal_ex(ctx, out + tmp_sz, &tmp_sz); if (ret != 1) goto fail_decrypt; @@ -326,7 +338,7 @@ static int openssl_decrypt(struct flow * f, return 0; fail_decrypt: - EVP_CIPHER_CTX_cleanup(f->ctx); + EVP_CIPHER_CTX_cleanup(ctx); fail_decrypt_init: free(out); fail_malloc: @@ -350,8 +362,8 @@ static void openssl_crypt_fini(void * ctx) #endif /* HAVE_OPENSSL */ -static int crypt_dh_pkp_create(void ** pkp, - uint8_t * pk) +int crypt_dh_pkp_create(void ** pkp, + uint8_t * pk) { #ifdef HAVE_OPENSSL assert(pkp != NULL); @@ -361,14 +373,13 @@ static int crypt_dh_pkp_create(void ** pkp, (void) pkp; (void) pk; - memset(pk, 0, MSGBUFSZ); *pkp = NULL; return 0; #endif } -static void crypt_dh_pkp_destroy(void * pkp) +void crypt_dh_pkp_destroy(void * pkp) { #ifdef HAVE_OPENSSL openssl_ecdh_pkp_destroy(pkp); @@ -378,10 +389,10 @@ static void crypt_dh_pkp_destroy(void * pkp) #endif } -static int crypt_dh_derive(void * pkp, - uint8_t * pk, - size_t len, - uint8_t * s) +int crypt_dh_derive(void * pkp, + uint8_t * pk, + size_t len, + uint8_t * s) { #ifdef HAVE_OPENSSL return openssl_ecdh_derive(pkp, pk, len, s); @@ -396,50 +407,52 @@ static int crypt_dh_derive(void * pkp, #endif } -static int crypt_encrypt(struct flow * f, - struct shm_du_buff * sdb) +int crypt_encrypt(struct crypt_info * info, + struct shm_du_buff * sdb) { + if (info->flags == 0) + return 0; + #ifdef HAVE_OPENSSL - return openssl_encrypt(f, sdb); + return openssl_encrypt(info->ctx, info->key, sdb); #else - (void) f; (void) sdb; return 0; #endif } -static int crypt_decrypt(struct flow * f, - struct shm_du_buff * sdb) +int crypt_decrypt(struct crypt_info * info, + struct shm_du_buff * sdb) { + if (info->flags == 0) + return 0; + #ifdef HAVE_OPENSSL - return openssl_decrypt(f, sdb); + return openssl_decrypt(info->ctx, info->key, sdb); #else - (void) f; (void) sdb; return -ECRYPT; #endif } -static int crypt_init(void ** ctx) +int crypt_init(struct crypt_info * info) { #ifdef HAVE_OPENSSL - return openssl_crypt_init(ctx); + return openssl_crypt_init(&info->ctx); #else - assert(ctx != NULL); - *ctx = NULL; - + info->ctx = NULL; return 0; #endif } -static void crypt_fini(void * ctx) +void crypt_fini(struct crypt_info * info) { #ifdef HAVE_OPENSSL - openssl_crypt_fini(ctx); + openssl_crypt_fini(info->ctx); #else - assert(ctx == NULL); - (void) ctx; + (void) info; + assert(info->ctx == NULL); #endif } diff --git a/src/lib/dev.c b/src/lib/dev.c index ef909e1a..02f9d3f9 100644 --- a/src/lib/dev.c +++ b/src/lib/dev.c @@ -30,6 +30,7 @@ #include <ouroboros/hash.h> #include <ouroboros/cacep.h> +#include <ouroboros/crypt.h> #include <ouroboros/errno.h> #include <ouroboros/dev.h> #include <ouroboros/ipcp-dev.h> @@ -71,7 +72,6 @@ #define CRCLEN (sizeof(uint32_t)) #define SECMEMSZ 16384 -#define SYMMKEYSZ 32 #define MSGBUFSZ 2048 enum flow_state { @@ -102,8 +102,7 @@ struct flow { qosspec_t qs; ssize_t part_idx; - void * ctx; - uint8_t key[SYMMKEYSZ]; + struct crypt_info crypt; pid_t pid; @@ -256,7 +255,6 @@ static int proc_announce(char * prog) return ret; } -#include "crypt.c" #include "frct.c" void * flow_tx(void * o) @@ -429,8 +427,7 @@ static void flow_fini(int fd) shm_flow_set_close(ai.flows[fd].set); } - if (ai.flows[fd].ctx != NULL) - crypt_fini(ai.flows[fd].ctx); + crypt_fini(&ai.flows[fd].crypt); list_del(&ai.flows[fd].next); @@ -480,12 +477,15 @@ static int flow_init(int flow_id, flow->snd_act = now; flow->rcv_act = now; - if (qs.cypher_s > 0) { - if (crypt_init(&flow->ctx) < 0) - goto fail_ctx; + flow->crypt.flags = qs.cypher_s; /* TODO: remove cypher_s from qos */ - memcpy(flow->key, s, SYMMKEYSZ); - } + if (flow->crypt.flags > 0) + memcpy(flow->crypt.key, s ,SYMMKEYSZ); + else + memset(flow->crypt.key, 0, SYMMKEYSZ); + + if (crypt_init(&flow->crypt) < 0) + goto fail_crypt; assert(flow->frcti == NULL); @@ -518,8 +518,8 @@ static int flow_init(int flow_id, fail_flow_set_add: frcti_destroy(flow->frcti); fail_frcti: - crypt_fini(flow->ctx); - fail_ctx: + crypt_fini(&flow->crypt); + fail_crypt: shm_flow_set_close(flow->set); fail_set: shm_rbuff_close(flow->tx_rb); @@ -1299,7 +1299,7 @@ static int flow_tx_sdb(struct flow * flow, if (frcti_snd(flow->frcti, sdb) < 0) goto enomem; - if (flow->qs.cypher_s > 0 && crypt_encrypt(flow, sdb) < 0) + if (crypt_encrypt(&flow->crypt, sdb) < 0) goto enomem; if (flow->qs.ber == 0 && add_crc(sdb) != 0) @@ -1401,7 +1401,7 @@ static bool invalid_pkt(struct flow * flow, if (flow->qs.ber == 0 && chk_crc(sdb) != 0) return true; - if (flow->qs.cypher_s > 0 && crypt_decrypt(flow, sdb) < 0) + if (crypt_decrypt(&flow->crypt, sdb) < 0) return true; return false; diff --git a/src/lib/frct.c b/src/lib/frct.c index a00b1acd..a3408481 100644 --- a/src/lib/frct.c +++ b/src/lib/frct.c @@ -261,7 +261,7 @@ static void __send_frct_pkt(int fd, f = &ai.flows[fd]; - if (f->qs.cypher_s > 0 && crypt_encrypt(f, sdb) < 0) + if (crypt_encrypt(&f->crypt, sdb) < 0) goto fail; #ifdef RXM_BLOCKING diff --git a/src/tools/oping/oping_client.c b/src/tools/oping/oping_client.c index a8e2dab7..6d3fecc8 100644 --- a/src/tools/oping/oping_client.c +++ b/src/tools/oping/oping_client.c @@ -232,7 +232,7 @@ static int client_main(void) fd = flow_alloc(client.s_apn, &client.qs, NULL); if (fd < 0) { - printf("Failed to allocate flow.\n"); + printf("Failed to allocate flow: %d.\n", fd); client_fini(); return -1; } |