diff options
Diffstat (limited to 'src/crypto/impl')
-rw-r--r-- | src/crypto/impl/bcrypt.c | 86 | ||||
-rw-r--r-- | src/crypto/impl/mbedtls.c | 20 | ||||
-rw-r--r-- | src/crypto/impl/monocypher.c | 5 | ||||
-rw-r--r-- | src/crypto/impl/openssl.c | 162 |
4 files changed, 186 insertions, 87 deletions
diff --git a/src/crypto/impl/bcrypt.c b/src/crypto/impl/bcrypt.c index 970f68f..9b01cac 100644 --- a/src/crypto/impl/bcrypt.c +++ b/src/crypto/impl/bcrypt.c @@ -32,8 +32,10 @@ #include <bcrypt.h> #include "nc-util.h" +#include "hkdf.h" -#define IF_BC_FAIL(x) if(!BCRYPT_SUCCESS(x)) +#define IF_BC_FAIL(x) if(!BCRYPT_SUCCESS(x)) +#define BC_FAIL(x) if(!BCRYPT_SUCCESS(x)) return CSTATUS_FAIL; struct _bcrypt_ctx { @@ -68,8 +70,8 @@ _IMPLSTB NTSTATUS _bcCreateHmac(struct _bcrypt_ctx* ctx, const cspan_t* key) { /* * NOTE: - * I am not explicitly managing the hash object buffer. By setting - * the hash object to NULL, and length to 0, the buffer will be + * I am not explicitly managing the update object buffer. By setting + * the update object to NULL, and length to 0, the buffer will be * managed by the bcrypt library. * * See: https://learn.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptcreatehash @@ -113,7 +115,7 @@ _IMPLSTB NTSTATUS _bcFinishHash(const struct _bcrypt_ctx* ctx, sha256_t digestOu _IMPLSTB void _bcDestroyCtx(struct _bcrypt_ctx* ctx) { - /* Free the hash memory if it was allocated */ + /* Free the update memory if it was allocated */ if(ctx->hHash) BCryptDestroyHash(ctx->hHash); /* Close the algorithm provider */ @@ -214,76 +216,42 @@ _IMPLSTB void _bcDestroyCtx(struct _bcrypt_ctx* ctx) #define _IMPL_CRYPTO_SHA256_HKDF_EXPAND _bcrypt_fallback_hkdf_expand - /* Include string for memmove */ - #include <string.h> - - static void ncWriteSpanS(span_t* span, uint32_t offset, const uint8_t* data, uint32_t size) + cstatus_t _bcrypt_hkdf_update(void* ctx, const cspan_t* data) { - DEBUG_ASSERT2(span != NULL, "Expected span to be non-null") - DEBUG_ASSERT2(data != NULL, "Expected data to be non-null") - DEBUG_ASSERT2(offset + size <= span->size, "Expected offset + size to be less than span size") + DEBUG_ASSERT(ctx != NULL) - /* Copy data to span */ - memmove(span->data + offset, data, size); + BC_FAIL(_bcHashData((struct _bcrypt_ctx*)ctx, data)) + return CSTATUS_OK; } - STATIC_ASSERT(HKDF_IN_BUF_SIZE > SHA256_DIGEST_SIZE, "HDK Buffer must be at least the size of the underlying hashing alg output") - - /* - * The following functions implements the HKDF expand function using an existing - * HMAC function. This is a fallback implementation for Windows platforms at the moment. - * - * This follows the guidence from RFC 5869: https://tools.ietf.org/html/rfc5869 - */ + cstatus_t _bcrypt_hkdf_finish(void* ctx, sha256_t hmacOut32) + { + DEBUG_ASSERT(ctx != NULL) - #define _BC_MIN(a, b) (a < b ? a : b) + BC_FAIL(_bcFinishHash((struct _bcrypt_ctx*)ctx, hmacOut32)) + return CSTATUS_OK; + } _IMPLSTB cstatus_t _bcrypt_fallback_hkdf_expand(const cspan_t* prk, const cspan_t* info, span_t* okm) { cstatus_t result; struct _bcrypt_ctx ctx; + struct nc_hkdf_fn_cb_struct handler; - uint8_t counter; - uint32_t tLen, okmOffset; - uint8_t t[HKDF_IN_BUF_SIZE]; - - _IMPL_SECURE_ZERO_MEMSET(t, sizeof(t)); - - tLen = 0; /* T(0) is an empty string(zero length) */ - okmOffset = 0; - result = CSTATUS_FAIL; /* Start in fail state */ - - /* Init context with hmac flag set, it will be reused */ - IF_BC_FAIL(_bcInitSha256(&ctx, BCRYPT_ALG_HANDLE_HMAC_FLAG)) goto Exit; - - /* Set hmac key to the prk, alg is set to reusable */ - IF_BC_FAIL(_bcCreateHmac(&ctx, prk)) goto Exit; - - /* Compute T(N) = HMAC(prk, T(n-1) | info | n) */ - for (counter = 1; okmOffset < okm->size; counter++) - { - IF_BC_FAIL(_bcHashDataRaw(&ctx, t, tLen)) goto Exit; - IF_BC_FAIL(_bcHashData(&ctx, info)) goto Exit; - IF_BC_FAIL(_bcHashDataRaw(&ctx, &counter, sizeof(counter))) goto Exit; - - /* Write current hash state to t buffer */ - IF_BC_FAIL(_bcFinishHash(&ctx, t)) goto Exit; + handler.update = _bcrypt_hkdf_update; + handler.finish = _bcrypt_hkdf_finish; - /* Set the length of the current hash state */ - tLen = _BC_MIN(okm->size - okmOffset, SHA256_DIGEST_SIZE); + /* Init bcrypt */ + BC_FAIL(_bcInitSha256(&ctx, BCRYPT_ALG_HANDLE_HMAC_FLAG)) - DEBUG_ASSERT(tLen <= sizeof(t)); + BC_FAIL(_bcCreateHmac(&ctx, prk)) - /* write the T buffer back to okm */ - ncWriteSpanS(okm, okmOffset, t, tLen); + /* + * NOTE! Hmac reusable flag must be set to allow for multiple + * calls to the finish function without losing the context. + */ - /* shift base okm pointer by T */ - okmOffset += tLen; - } - - result = CSTATUS_OK; /* HMAC operation completed, so set success */ - - Exit: + result = hkdfExpandProcess(&handler, &ctx, info, okm); _bcDestroyCtx(&ctx); diff --git a/src/crypto/impl/mbedtls.c b/src/crypto/impl/mbedtls.c index ae36bbd..18eb9db 100644 --- a/src/crypto/impl/mbedtls.c +++ b/src/crypto/impl/mbedtls.c @@ -28,6 +28,11 @@ #ifdef MBEDTLS_CRYPTO_LIB +/* Inline errors on linux in header files on linux */ +#ifndef inline +#define inline __inline +#endif + #include <mbedtls/md.h> #include <mbedtls/hkdf.h> #include <mbedtls/hmac_drbg.h> @@ -35,11 +40,10 @@ #include <mbedtls/chacha20.h> #include <mbedtls/constant_time.h> -#include "nc-util.h" +#ifndef inline +#undef inline +#endif -/* -* EXPORT SUPPORTED FUNCTION OVERRIDES -*/ _IMPLSTB const mbedtls_md_info_t* _mbed_sha256_alg(void) { @@ -51,10 +55,8 @@ _IMPLSTB const mbedtls_md_info_t* _mbed_sha256_alg(void) } #if SIZE_MAX < UINT64_MAX - #define _ssize_guard(x) if(x > SIZE_MAX) return CSTATUS_FAIL; #define _ssize_guard_int(x) if(x > SIZE_MAX) return 1; #else - #define _ssize_guard(x) #define _ssize_guard_int(x) #endif @@ -71,7 +73,7 @@ _IMPLSTB const mbedtls_md_info_t* _mbed_sha256_alg(void) uint32_t dataLen ) { - _ssize_guard(dataLen) + _sizet_check(dataLen) /* Counter always starts at 0 */ return mbedtls_chacha20_crypt( @@ -93,7 +95,7 @@ _IMPLSTB const mbedtls_md_info_t* _mbed_sha256_alg(void) _IMPLSTB cstatus_t _mbed_sha256_digest(const cspan_t* data, sha256_t digestOut32) { - _ssize_guard(data->size) + _sizet_check(data->size) return mbedtls_sha256( data->data, @@ -112,7 +114,7 @@ _IMPLSTB const mbedtls_md_info_t* _mbed_sha256_alg(void) _IMPLSTB cstatus_t _mbed_sha256_hmac(const cspan_t* key, const cspan_t* data, sha256_t hmacOut32) { - _ssize_guard(data->size) + _sizet_check(data->size) /* Keys should never be large enough for this to matter, but sanity check. */ DEBUG_ASSERT2(key->size < SIZE_MAX, "Expected key size to be less than SIZE_MAX") diff --git a/src/crypto/impl/monocypher.c b/src/crypto/impl/monocypher.c index 790f5e9..b695d08 100644 --- a/src/crypto/impl/monocypher.c +++ b/src/crypto/impl/monocypher.c @@ -53,10 +53,7 @@ uint32_t dataLen ) { - if(dataLen > SIZE_MAX) - { - return CSTATUS_FAIL; - } + _sizet_check(dataLen) /* * Function returns the next counter value which is not diff --git a/src/crypto/impl/openssl.c b/src/crypto/impl/openssl.c index 1217e60..90028e6 100644 --- a/src/crypto/impl/openssl.c +++ b/src/crypto/impl/openssl.c @@ -23,24 +23,156 @@ #ifdef OPENSSL_CRYPTO_LIB -#include <openssl/sha.h> - #include "nc-util.h" +#include <openssl/crypto.h> -/* -* EXPORT SUPPORTED FUNCTIONS AS MACROS -*/ -#define _IMPL_CHACHA20_CRYPT _mbed_chacha20_encrypt -#define _IMPL_CRYPTO_SHA256_HMAC _mbed_sha256_hmac -#define _IMPL_CRYPTO_SHA256_DIGEST _ossl_sha256_digest -#define _IMPL_CRYPTO_FIXED_TIME_COMPARE _mbed_fixed_time_compare -#define _IMPL_CRYPTO_SHA256_HKDF_EXPAND _mbed_sha256_hkdf_expand -#define _IMPL_CRYPTO_SHA256_HKDF_EXTRACT _mbed_sha256_hkdf_extract - -_IMPLSTB int _ossl_sha256_digest(const uint8_t* data, uint8_t* digest) -{ +#define _OSSL_FAIL(x) if(!(x)) return CSTATUS_FAIL; + +#ifndef _IMPL_SECURE_ZERO_MEMSET + + #define _IMPL_SECURE_ZERO_MEMSET _ossl_secure_zero_memset + + _IMPLSTB void _ossl_secure_zero_memset(void* ptr, size_t size) + { + _sizet_check(size) + + OPENSSL_cleanse(ptr, size); + } +#endif + +#ifndef _IMPL_CRYPTO_FIXED_TIME_COMPARE + + #define _IMPL_CRYPTO_FIXED_TIME_COMPARE _ossl_fixed_time_compare + + _IMPLSTB uint32_t _ossl_fixed_time_compare(const uint8_t* a, const uint8_t* b, uint32_t size) + { + int result; + + _sizet_check(size) + + result = CRYPTO_memcmp(a, b, size); + + return (uint32_t)result; + } + +#endif /* _IMPL_CRYPTO_FIXED_TIME_COMPARE */ + + +#ifndef _IMPL_CRYPTO_SHA256_DIGEST + + #include <openssl/sha.h> + + #define _IMPL_CRYPTO_SHA256_DIGEST _ossl_sha256_digest + + _IMPLSTB cstatus_t _ossl_sha256_digest(const cspan_t* data, sha256_t digestOut32) + { + _sizet_check(data->size) + + _OSSL_FAIL(SHA256(data->data, data->size, digestOut32)) + + return CSTATUS_OK; + } + +#endif + +#ifndef _IMPL_CRYPTO_SHA256_HMAC + + #include <openssl/hmac.h> + + /* Export function */ + #define _IMPL_CRYPTO_SHA256_HMAC _ossl_hmac_sha256 + + _IMPLSTB cstatus_t _ossl_hmac_sha256(const cspan_t* key, const cspan_t* data, sha256_t hmacOut32) + { + unsigned int hmacLen; + + _sizet_check(key->size) + _sizet_check(data->size) + + hmacLen = sizeof(sha256_t); + + _OSSL_FAIL( + HMAC( + EVP_sha256(), + key->data, + key->size, + data->data, + data->size, + hmacOut32, + &hmacLen + ) + ) + + /* digest length should match the actual digest size */ + _OSSL_FAIL(hmacLen != sizeof(sha256_t)) + + return CSTATUS_OK; + } + +#endif /* !_IMPL_CRYPTO_SHA256_HMAC */ + +#ifndef _IMPL_CRYPTO_SHA256_HKDF_EXPAND + + #include <openssl/hmac.h> + #include "hkdf.h" + + #define _IMPL_CRYPTO_SHA256_HKDF_EXPAND _ossl_sha256_hkdf_expand + + cstatus_t _ossl_hkdf_update(void* ctx, const cspan_t* data) + { + DEBUG_ASSERT(ctx != NULL) + + _OSS_FAIL(HMAC_Update((HMAC_CTX*)ctx, data->data, data->size)) + + return CSTATUS_OK; + } + + cstatus_t _ossl_hkdf_finish(void* ctx, sha256_t hmacOut32) + { + DEBUG_ASSERT(ctx != NULL) + + _OSSL_FAIL(HMAC_Final((HMAC_CTX*)ctx, hmacOut32, NULL)) + + return CSTATUS_OK; + } + + _IMPLSTB cstatus_t _ossl_fallback_hkdf_expand(const cspan_t* prk, const cspan_t* info, span_t* okm) + { + HMAC_CTX* hmac; + cstatus_t result; + struct nc_hkdf_fn_cb_struct handler; -} + /* + * NOTE! Hmac reusable flag must be set to allow for multiple + * calls to the finish function without losing the context. + */ + + if ((hmac = HMAC_CTX_new()) == NULL) + { + return CSTATUS_FAIL; + } + + + _OSSL_FAIL( + HMAC_Init_ex( + hmac, + prk->data, + pkr->size, + EVP_sha256(), + NULL + ) + ) + + handler.update = _ossl_hkdf_update; + handler.finish = _ossl_hkdf_finish; + + result = hkdfExpandProcess(&handler, hmac, info, okm); + + HMAC_CTX_free(hmac); + + return result; + } +#endif /* !_IMPL_CRYPTO_SHA256_HKDF_EXPAND */ #endif /*!OPENSSL_CRYPTO_LIB */
\ No newline at end of file |