aboutsummaryrefslogtreecommitdiff
path: root/src/providers/mbedtls.c
blob: 8479380f6811c0345ae948548bade82b51dd9f2f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/*
* Copyright (c) 2024 Vaughn Nugent
*
* Package: noscrypt
* File: mbedtls.c
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1
* of the License, or  (at your option) any later version.
*
* 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 noscrypt. If not, see http://www.gnu.org/licenses/.
*/


/*
* This file contains implemntation functions for the required 
* cryptography primitives of noscrypt. This file stubs functionality
* using the Mbed-TLS library, if the builder desires to link against
* it. 
*/

#ifdef MBEDTLS_CRYPTO_LIB

/* Inline errors on linux in header files on linux */
#ifndef inline
	#define inline __inline
	#include <mbedtls/md.h>
	#include <mbedtls/hkdf.h>
	#include <mbedtls/hmac_drbg.h>
	#include <mbedtls/sha256.h>
	#include <mbedtls/chacha20.h>
	#include <mbedtls/constant_time.h>
	#undef inline
#else
	#include <mbedtls/md.h>
	#include <mbedtls/hkdf.h>
	#include <mbedtls/hmac_drbg.h>
	#include <mbedtls/sha256.h>
	#include <mbedtls/chacha20.h>
	#include <mbedtls/constant_time.h>
#endif

_IMPLSTB const mbedtls_md_info_t* _mbed_sha256_alg(void)
{
	const mbedtls_md_info_t* info;
	/* Get sha256 md info for hdkf operations */
	info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
	DEBUG_ASSERT2(info != NULL, "Expected SHA256 md info pointer to be valid")
	return info;
}

#if SIZE_MAX < UINT64_MAX
	#define _ssize_guard_int(x) if(x > SIZE_MAX) return 1;
#else
	#define _ssize_guard_int(x)
#endif

#ifndef _IMPL_CHACHA20_CRYPT
	
	/* Export chacha20 computation */
	#define _IMPL_CHACHA20_CRYPT _mbed_chacha20_encrypt	

	_IMPLSTB cstatus_t _mbed_chacha20_encrypt(
		const uint8_t* key,
		const uint8_t* nonce,
		const uint8_t* input,
		uint8_t* output,
		uint32_t dataLen
	)
	{
		_overflow_check(dataLen)

		/* Counter always starts at 0 */
		return mbedtls_chacha20_crypt(
			key, 
			nonce, 
			0x00u,		/* nip-44 counter version */
			dataLen, 
			input, 
			output
		) == 0 ? CSTATUS_OK : CSTATUS_FAIL;
	}

#endif

/* Export sha256 if not already defined */
#ifndef _IMPL_CRYPTO_SHA256_DIGEST	
	
	#define _IMPL_CRYPTO_SHA256_DIGEST			_mbed_sha256_digest	

	_IMPLSTB cstatus_t _mbed_sha256_digest(cspan_t data, sha256_t digestOut32)
	{
		_overflow_check(data.size)

		return mbedtls_sha256(
			data.data, 
			data.size, 
			digestOut32, 
			0				/* Set 0 for sha256 mode */
		) == 0 ? CSTATUS_OK : CSTATUS_FAIL;
	}

#endif

/* Export Sha256 hmac if not already defined by other libs */
#ifndef _IMPL_CRYPTO_SHA256_HMAC

	#define _IMPL_CRYPTO_SHA256_HMAC			_mbed_sha256_hmac

	_IMPLSTB cstatus_t _mbed_sha256_hmac(cspan_t key, cspan_t data, sha256_t hmacOut32)
	{
		_overflow_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")

		return mbedtls_md_hmac(
			_mbed_sha256_alg(),
			key.data, 
			key.size,
			data.data, 
			data.size,
			hmacOut32
		) == 0 ? CSTATUS_OK : CSTATUS_FAIL;
	}
#endif

/* Export hkdf expand if not already defined */
#ifndef _IMPL_CRYPTO_SHA256_HKDF_EXPAND

	#define _IMPL_CRYPTO_SHA256_HKDF_EXPAND		_mbed_sha256_hkdf_expand

	_IMPLSTB cstatus_t _mbed_sha256_hkdf_expand(cspan_t prk, cspan_t info, span_t okm)
	{
		/* These sizes should never be large enough to overflow on <64bit platforms, but sanity check */
		DEBUG_ASSERT(okm.size < SIZE_MAX)
		DEBUG_ASSERT(prk.size < SIZE_MAX)
		DEBUG_ASSERT(info.size < SIZE_MAX)

		return mbedtls_hkdf_expand(
			_mbed_sha256_alg(),
			prk.data, 
			prk.size,
			info.data, 
			info.size,
			okm.data, 
			okm.size
		) == 0 ? CSTATUS_OK : CSTATUS_FAIL;
	}

#endif

/* Export fixed-time compare if not already defined */
#ifndef _IMPL_CRYPTO_FIXED_TIME_COMPARE

	#define _IMPL_CRYPTO_FIXED_TIME_COMPARE		_mbed_fixed_time_compare

	/* fixed-time memcmp */
	_IMPLSTB uint32_t _mbed_fixed_time_compare(const uint8_t* a, const uint8_t* b, uint32_t size)
	{
		_ssize_guard_int(size)

		return (uint32_t)mbedtls_ct_memcmp(a, b, size);
	}
#endif

#endif