From 62c3d7410653de807e64504b9414e7039448b4c5 Mon Sep 17 00:00:00 2001 From: kkrentz Date: Wed, 1 Nov 2023 21:35:51 +0100 Subject: [PATCH] Contiki-NG: Crypto adapter for OSCORE --- include/coap3/coap_internal.h | 5 ++ src/coap_gnutls.c | 4 +- src/coap_mbedtls.c | 4 +- src/coap_notls.c | 4 +- src/coap_openssl.c | 4 +- src/coap_tinydtls.c | 4 +- src/oscore/oscore_crypto_contiki.c | 138 +++++++++++++++++++++++++++++ 7 files changed, 153 insertions(+), 10 deletions(-) create mode 100644 src/oscore/oscore_crypto_contiki.c diff --git a/include/coap3/coap_internal.h b/include/coap3/coap_internal.h index 407cbc1efb..fe4e068be9 100644 --- a/include/coap3/coap_internal.h +++ b/include/coap3/coap_internal.h @@ -85,6 +85,11 @@ /* * Include all the header files that are for internal use only. */ +#if COAP_OSCORE_SUPPORT && defined(WITH_CONTIKI) +#include "lib/aes-128.h" +#include "lib/ccm-star.h" +#include "lib/sha-256.h" +#endif /*COAP_OSCORE_SUPPORT && WITH_CONTIKI */ #if defined(COAP_OSCORE_SUPPORT) || defined(COAP_WS_SUPPORT) /* Specific OSCORE general .h files */ diff --git a/src/coap_gnutls.c b/src/coap_gnutls.c index 8505622a4f..6c72fe1806 100644 --- a/src/coap_gnutls.c +++ b/src/coap_gnutls.c @@ -3006,7 +3006,7 @@ coap_crypto_hash(cose_alg_t alg, } #endif /* COAP_WS_SUPPORT */ -#if COAP_OSCORE_SUPPORT +#if COAP_OSCORE_SUPPORT && !defined(WITH_CONTIKI) int coap_oscore_is_supported(void) { return 1; @@ -3240,7 +3240,7 @@ coap_crypto_hmac(cose_hmac_alg_t hmac_alg, return ret == 1 ? 1 : 0; } -#endif /* COAP_OSCORE_SUPPORT */ +#endif /* COAP_OSCORE_SUPPORT && !WITH_CONTIKI */ #else /* !COAP_WITH_LIBGNUTLS */ diff --git a/src/coap_mbedtls.c b/src/coap_mbedtls.c index c81fb59694..d8e569d501 100644 --- a/src/coap_mbedtls.c +++ b/src/coap_mbedtls.c @@ -2708,7 +2708,7 @@ coap_crypto_hash(cose_alg_t alg, } #endif /* COAP_WS_SUPPORT */ -#if COAP_OSCORE_SUPPORT +#if COAP_OSCORE_SUPPORT && !defined(WITH_CONTIKI) int coap_oscore_is_supported(void) { return 1; @@ -3036,7 +3036,7 @@ coap_crypto_hmac(cose_hmac_alg_t hmac_alg, return ret; } -#endif /* COAP_OSCORE_SUPPORT */ +#endif /* COAP_OSCORE_SUPPORT && !WITH_CONTIKI */ #else /* !COAP_WITH_LIBMBEDTLS */ diff --git a/src/coap_notls.c b/src/coap_notls.c index 2aa41f2b9c..ca87c87f4a 100644 --- a/src/coap_notls.c +++ b/src/coap_notls.c @@ -339,7 +339,7 @@ coap_crypto_hash(cose_alg_t alg, } #endif /* COAP_WS_SUPPORT */ -#if COAP_OSCORE_SUPPORT +#if COAP_OSCORE_SUPPORT && !defined(WITH_CONTIKI) int coap_oscore_is_supported(void) { @@ -398,7 +398,7 @@ coap_crypto_hmac(cose_hmac_alg_t hmac_alg, return 0; } -#endif /* COAP_OSCORE_SUPPORT */ +#endif /* COAP_OSCORE_SUPPORT && !WITH_CONTIKI */ #else /* !COAP_WITH_LIBTINYDTLS && !COAP_WITH_LIBOPENSSL && !COAP_WITH_LIBGNUTLS */ diff --git a/src/coap_openssl.c b/src/coap_openssl.c index 6d90646fec..3f2810de14 100644 --- a/src/coap_openssl.c +++ b/src/coap_openssl.c @@ -3702,7 +3702,7 @@ coap_crypto_hash(cose_alg_t alg, } #endif /* COAP_WS_SUPPORT */ -#if COAP_OSCORE_SUPPORT +#if COAP_OSCORE_SUPPORT && !defined(WITH_CONTIKI) int coap_oscore_is_supported(void) { return 1; @@ -3939,7 +3939,7 @@ coap_crypto_hmac(cose_hmac_alg_t hmac_alg, return 0; } -#endif /* COAP_OSCORE_SUPPORT */ +#endif /* COAP_OSCORE_SUPPORT && !WITH_CONTIKI */ #else /* !COAP_WITH_LIBOPENSSL */ diff --git a/src/coap_tinydtls.c b/src/coap_tinydtls.c index 06e7826ab4..2284b1f957 100644 --- a/src/coap_tinydtls.c +++ b/src/coap_tinydtls.c @@ -1510,7 +1510,7 @@ coap_crypto_hash(cose_alg_t alg, } #endif /* COAP_WS_SUPPORT */ -#if COAP_OSCORE_SUPPORT +#if COAP_OSCORE_SUPPORT && !defined(WITH_CONTIKI) int coap_oscore_is_supported(void) { @@ -1711,7 +1711,7 @@ coap_crypto_hmac(cose_hmac_alg_t hmac_alg, coap_bin_const_t *key, return 1; } -#endif /* COAP_OSCORE_SUPPORT */ +#endif /* COAP_OSCORE_SUPPORT && !WITH_CONTIKI */ #else /* !COAP_WITH_LIBTINYDTLS */ diff --git a/src/oscore/oscore_crypto_contiki.c b/src/oscore/oscore_crypto_contiki.c new file mode 100644 index 0000000000..6580949b37 --- /dev/null +++ b/src/oscore/oscore_crypto_contiki.c @@ -0,0 +1,138 @@ +/* oscore_crypto_contiki.c -- Crypto adapter for Contiki-NG + * + * Copyright (C) 2023 Uppsala universitet + * + * SPDX-License-Identifier: BSD-2-Clause + * + * This file is part of the CoAP library libcoap. Please see + * README for terms of use. + */ + +/** + * @file oscore_crypto_contiki.c + * @brief Crypto adapter for Contiki-NG + */ + +#include "coap3/coap_internal.h" +#include +#include + +int +coap_oscore_is_supported(void) { + return 1; +} + +int +coap_crypto_check_cipher_alg(cose_alg_t alg) { + switch (alg) { + case COSE_ALGORITHM_AES_CCM_16_64_128: + case COSE_ALGORITHM_AES_CCM_16_128_128: + return 1; + default: + return 0; + } +} + +int +coap_crypto_check_hkdf_alg(cose_hkdf_alg_t hkdf_alg) { + return hkdf_alg == COSE_HKDF_ALG_HKDF_SHA_256; +} + +int +coap_crypto_aead_encrypt(const coap_crypto_param_t *params, + coap_bin_const_t *data, + coap_bin_const_t *aad, + uint8_t *result, + size_t *max_result_len) { + /* validate inputs */ + assert(params->params.aes.tag_len <= AES_128_BLOCK_SIZE); + if ((data->length > UINT16_MAX) || (aad->length > UINT16_MAX)) { + return 0; + } + size_t result_len = data->length + params->params.aes.tag_len; + if (*max_result_len < result_len) { + return 0; + } + + /* set max_result_len */ + *max_result_len = result_len; + + /* copy plaintext */ + memcpy(result, data->s, data->length); + + /* encrypt */ + while (!AES_128.get_lock()); + if (!CCM_STAR.set_key(params->params.key.s)) { + return 0; + } + if (!CCM_STAR.aead(params->params.aes.nonce, + result, data->length, + aad->s, aad->length, + result + data->length, params->params.aes.tag_len, + true)) { + return 0; + } + AES_128.release_lock(); + + return 1; +} + +int +coap_crypto_aead_decrypt(const coap_crypto_param_t *params, + coap_bin_const_t *data, + coap_bin_const_t *aad, + uint8_t *result, + size_t *max_result_len) { + size_t result_len; + uint8_t expected_tag[AES_128_BLOCK_SIZE]; + + /* validate inputs */ + assert(params->params.aes.tag_len <= AES_128_BLOCK_SIZE); + if (data->length < params->params.aes.tag_len) { + return 0; + } + result_len = data->length - params->params.aes.tag_len; + if (*max_result_len < result_len) { + return 0; + } + if ((result_len > UINT16_MAX) || (aad->length > UINT16_MAX)) { + return 0; + } + + /* set max_result_len */ + *max_result_len = result_len; + + /* copy ciphertext */ + memcpy(result, data->s, result_len); + + /* decrypt */ + while (!AES_128.get_lock()); + if (!CCM_STAR.set_key(params->params.key.s)) { + return 0; + } + if (!CCM_STAR.aead(params->params.aes.nonce, + result, result_len, + aad->s, aad->length, + expected_tag, params->params.aes.tag_len, + false)) { + return 0; + } + AES_128.release_lock(); + + return !memcmp(expected_tag, + data->s + result_len, + params->params.aes.tag_len); +} + +int +coap_crypto_hmac(cose_hmac_alg_t hmac_alg, + coap_bin_const_t *key, + coap_bin_const_t *data, + coap_bin_const_t **hmac) { + uint8_t hmac_bytes[SHA_256_DIGEST_LENGTH]; + + assert(hmac_alg == COSE_HMAC_ALG_HMAC256_256); + sha_256_hmac(key->s, key->length, data->s, data->length, hmac_bytes); + *hmac = coap_new_bin_const(hmac_bytes, sizeof(hmac_bytes)); + return *hmac != NULL; +}