Amazon Kinesis Webrtc C SDK
Loading...
Searching...
No Matches
Crypto.h
Go to the documentation of this file.
1#ifndef __KINESIS_VIDEO_WEBRTC_CLIENT_CRYPTO_CRYPTO__
2#define __KINESIS_VIDEO_WEBRTC_CLIENT_CRYPTO_CRYPTO__
3
4#pragma once
5
6#ifdef __cplusplus
7extern "C" {
8#endif
9
10#ifdef KVS_USE_OPENSSL
11#include <openssl/opensslv.h>
12
13/*
14 * OpenSSL 3.x compatibility macros.
15 * The deprecated 1.1.x APIs still work in 3.x but will be removed in 4.0.
16 * When OPENSSL_VERSION_NUMBER >= 0x30000000L, use the modern EVP-based APIs.
17 */
18
19/* SSL_get_peer_certificate was renamed to SSL_get1_peer_certificate in 3.0 */
20#if OPENSSL_VERSION_NUMBER >= 0x30000000L
21#define KVS_SSL_GET_PEER_CERTIFICATE(ssl) SSL_get1_peer_certificate(ssl)
22#else
23#define KVS_SSL_GET_PEER_CERTIFICATE(ssl) SSL_get_peer_certificate(ssl)
24#endif
25
26#define KVS_RSA_F4 RSA_F4
27#define KVS_MD5_DIGEST_LENGTH MD5_DIGEST_LENGTH
28#define KVS_SHA1_DIGEST_LENGTH SHA_DIGEST_LENGTH
29
30/* MD5 one-shot: MD5() removed in OpenSSL 3.x, use EVP_Q_digest */
31#if OPENSSL_VERSION_NUMBER >= 0x30000000L
32#define KVS_MD5_DIGEST(m, mlen, ob) \
33 CHK(1 == EVP_Q_digest(NULL, "MD5", NULL, (m), (mlen), (ob), NULL), STATUS_ICE_FAILED_TO_COMPUTE_MD5_FOR_LONG_TERM_CREDENTIAL);
34#else
35#define KVS_MD5_DIGEST(m, mlen, ob) CHK(NULL != MD5((m), (mlen), (ob)), STATUS_ICE_FAILED_TO_COMPUTE_MD5_FOR_LONG_TERM_CREDENTIAL);
36#endif
37
38/* HMAC one-shot: HMAC() deprecated in OpenSSL 3.x, use kvsSha1Hmac() function with proper cleanup */
39#if OPENSSL_VERSION_NUMBER >= 0x30000000L
40STATUS kvsSha1Hmac(const PBYTE pKey, size_t keyLen, const PBYTE pMessage, size_t messageLen, PBYTE pOutput, PUINT32 pOutputLen);
41#define KVS_SHA1_HMAC(k, klen, m, mlen, ob, plen) \
42 CHK_STATUS(kvsSha1Hmac((const PBYTE)(k), (size_t) (klen), (const PBYTE)(m), (size_t) (mlen), (ob), (plen)));
43#else
44#define KVS_SHA1_HMAC(k, klen, m, mlen, ob, plen) \
45 CHK(NULL != HMAC(EVP_sha1(), (k), (INT32) (klen), (m), (mlen), (ob), (plen)), STATUS_HMAC_GENERATION_ERROR);
46#endif
47
48/*
49 * KVS_CRYPTO_INIT: On OpenSSL 1.1.0+, the library auto-initializes so the legacy
50 * init calls are no-ops. On 3.x, OPENSSL_INIT_NO_ATEXIT prevents OPENSSL_cleanup()
51 * from being called by libwebsockets on context destroy, avoiding state corruption.
52 */
53#if OPENSSL_VERSION_NUMBER >= 0x30000000L
54#define KVS_CRYPTO_INIT() \
55 do { \
56 OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS | OPENSSL_INIT_NO_ATEXIT, NULL); \
57 } while (0)
58#else
59#define KVS_CRYPTO_INIT() \
60 do { \
61 OpenSSL_add_ssl_algorithms(); \
62 SSL_load_error_strings(); \
63 SSL_library_init(); \
64 } while (0)
65#endif
66
67#define LOG_OPENSSL_ERROR(s) \
68 while ((sslErr = ERR_get_error()) != 0) { \
69 if (sslErr != SSL_ERROR_WANT_WRITE && sslErr != SSL_ERROR_WANT_READ) { \
70 DLOGW("%s failed with %s", (s), ERR_error_string(sslErr, NULL)); \
71 } \
72 }
73
74typedef enum {
75 KVS_SRTP_PROFILE_AES128_CM_HMAC_SHA1_80 = SRTP_AES128_CM_SHA1_80,
76 KVS_SRTP_PROFILE_AES128_CM_HMAC_SHA1_32 = SRTP_AES128_CM_SHA1_32,
77} KVS_SRTP_PROFILE;
78#elif KVS_USE_MBEDTLS
79#define KVS_RSA_F4 0x10001L
80#define KVS_MD5_DIGEST_LENGTH 16
81#define KVS_SHA1_DIGEST_LENGTH 20
82
83/* go through the generic message-digest layer rather than the MD5 module. */
84#define KVS_MD5_DIGEST(m, mlen, ob) \
85 CHK(0 == mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_MD5), (m), (mlen), (ob)), STATUS_ICE_FAILED_TO_COMPUTE_MD5_FOR_LONG_TERM_CREDENTIAL);
86#define KVS_SHA1_HMAC(k, klen, m, mlen, ob, plen) \
87 CHK(0 == mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), (k), (klen), (m), (mlen), (ob)), STATUS_HMAC_GENERATION_ERROR); \
88 *(plen) = mbedtls_md_get_size(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1));
89#if MBEDTLS_VERSION_MAJOR >= 4
90/* PSA Crypto must be initialised before any psa_* call. psa_crypto_init() is
91 * idempotent; calling it once from the SDK init path avoids the per-session
92 * race on builds without MBEDTLS_THREADING_C. */
93#define KVS_CRYPTO_INIT() \
94 do { \
95 (void) psa_crypto_init(); \
96 } while (0)
97#else
98#define KVS_CRYPTO_INIT() \
99 do { \
100 } while (0)
101#endif
102#define LOG_MBEDTLS_ERROR(s, ret) \
103 do { \
104 CHAR __mbedtlsErr[1024]; \
105 if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { \
106 mbedtls_strerror(ret, __mbedtlsErr, SIZEOF(__mbedtlsErr)); \
107 DLOGW("%s failed with %s", (s), __mbedtlsErr); \
108 } \
109 } while (0)
110
111typedef enum {
112 KVS_SRTP_PROFILE_AES128_CM_HMAC_SHA1_80 = MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80,
113 KVS_SRTP_PROFILE_AES128_CM_HMAC_SHA1_32 = MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32,
114} KVS_SRTP_PROFILE;
115#else
116#error "A Crypto implementation is required."
117#endif
118
119#ifdef __cplusplus
120}
121#endif
122#endif //__KINESIS_VIDEO_WEBRTC_CLIENT_CRYPTO_CRYPTO__