1 /**
2 ******************************************************************************
3 * @file rtl8721dhp_chacha_poly1305.c
4 * @author
5 * @version V1.0.0
6 * @date 2017-10-25
7 * @brief This file provides firmware functions to manage the following
8 * functionalities of the HW crypto:
9 * - CHACHA
10 * - POLY1305
11 * - CHACHA-POLY1305
12 ******************************************************************************
13 * @attention
14 *
15 * This module is a confidential and proprietary property of RealTek and
16 * possession or use of this module requires written permission of RealTek.
17 *
18 * Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
19 ******************************************************************************
20 */
21 #include "ameba_soc.h"
22 #include "hal_crypto.h"
23
24 /**
25 * @brief Poly1305 initialize.
26 * @param key: Cipher key
27 * @retval Initialize status.
28 */
rtl_crypto_poly1305_init(IN const u8 * key)29 int rtl_crypto_poly1305_init(IN const u8 *key)
30 {
31 HAL_CRYPTO_ADAPTER *pIE = &crypto_engine;
32
33 assert_param( (pIE != NULL) && (pIE->isInit == _TRUE) );
34 if ( key == NULL ) return _ERRNO_CRYPTO_NULL_POINTER;
35 if ( (u32)(key) & 0x3 ) return _ERRNO_CRYPTO_ADDR_NOT_4Byte_Aligned; // need to be 4-byte alignment
36
37 return CRYPTO_CipherInit(pIE, CIPHER_TYPE_POLY1305, key, 32);
38 }
39
40 /**
41 * @brief Poly1305 process
42 * @param message : input buffer
43 * @param msglen : input buffer length
44 * @param pDigest : output digest buffer
45 * @retval 0 : SUCCESS <br>
46 * others : fail, refer to ERRNO
47 */
rtl_crypto_poly1305_process(IN const u8 * message,IN const u32 msglen,OUT u8 * pDigest)48 int rtl_crypto_poly1305_process(IN const u8 *message, IN const u32 msglen, OUT u8 *pDigest)
49 {
50 HAL_CRYPTO_ADAPTER *pIE = &crypto_engine;
51
52 if ( message == NULL ) return _ERRNO_CRYPTO_NULL_POINTER;
53 if ( pDigest == NULL ) return _ERRNO_CRYPTO_NULL_POINTER;
54
55 return CRYPTO_CipherDecryptAD(pIE, message, msglen, NULL, 0, NULL, 0, NULL, pDigest);
56 }
57
58 /**
59 * @brief Poly1305 init & process
60 * @param key : need to be 4 byte alignment
61 * @param keylen : key length
62 * @param message : input buffer
63 * @param msglen : input buffer length
64 * @param pDigest : the result of Poly1305 function
65 * @retval 0 : SUCCESS <br>
66 * others : fail, refer to ERRNO
67 */
rtl_crypto_poly1305(IN const u8 * message,IN const u32 msglen,IN const u8 * key,OUT u8 * pDigest)68 int rtl_crypto_poly1305(IN const u8* message, IN const u32 msglen, IN const u8* key,
69 OUT u8* pDigest)
70 {
71 int ret;
72
73 ret = rtl_crypto_poly1305_init(key);
74 if ( ret != SUCCESS ) return ret;
75
76 ret = rtl_crypto_poly1305_process(message, msglen, pDigest);
77
78 return ret;
79 }
80
81 /**
82 * @brief ChaCha initialize.
83 * @param key: Cipher key
84 * @retval Initialize status.
85 */
rtl_crypto_chacha_init(IN const u8 * key)86 int rtl_crypto_chacha_init(IN const u8* key)
87 {
88 HAL_CRYPTO_ADAPTER *pIE = &crypto_engine;
89
90 assert_param( (pIE != NULL) && (pIE->isInit == _TRUE) );
91 if ( key == NULL ) return _ERRNO_CRYPTO_NULL_POINTER;
92 if ( (u32)(key) & 0x3 ) return _ERRNO_CRYPTO_ADDR_NOT_4Byte_Aligned; // need to be 4-byte alignment
93
94 return CRYPTO_CipherInit(pIE, CIPHER_TYPE_CHACHA, key, 32);
95 }
96
97 /**
98 * @brief ChaCha encryption.
99 * @param message: Point to message.
100 * @param msglen: Message length.
101 * @param iv: Point to IV(initialize vector).
102 * @param count: Counter value.
103 * @param pResult: Point to cipher result.
104 * @retval Process status.
105 */
rtl_crypto_chacha_encrypt(IN const u8 * message,IN const u32 msglen,IN const u8 * iv,IN const u32 count,OUT u8 * pResult)106 int rtl_crypto_chacha_encrypt(IN const u8* message, IN const u32 msglen,
107 IN const u8* iv, IN const u32 count,
108 OUT u8* pResult)
109 {
110 HAL_CRYPTO_ADAPTER *pIE = &crypto_engine;
111 u8 count_str[4];
112
113 if ( iv == NULL ) return _ERRNO_CRYPTO_NULL_POINTER;
114 if ( (u32)(iv) & 0x3 ) return _ERRNO_CRYPTO_ADDR_NOT_4Byte_Aligned; // need to be 4-byte alignment
115 if ( message == NULL ) return _ERRNO_CRYPTO_NULL_POINTER;
116 if ( pResult == NULL ) return _ERRNO_CRYPTO_NULL_POINTER;
117
118 //rtk_cpu_to_be32(count);
119 _memcpy((void*)count_str, (const void*)(&count), sizeof(u32));
120 _memcpy((void*)(&(pIE->gcm_iv)[0]), count_str, 4);
121 _memcpy((void*)(&(pIE->gcm_iv)[4]), iv, 96/8);
122
123 return CRYPTO_CipherEncryptAD(pIE, message, msglen, (u8*)(pIE->gcm_iv), 16, NULL, 0, pResult, NULL);
124 }
125
126 /**
127 * @brief ChaCha decryption.
128 * @param message: Point to message.
129 * @param msglen: Message length.
130 * @param iv: Point to IV(initialize vector).
131 * @param count: Counter value.
132 * @param pResult: Point to cipher result.
133 * @retval Process status.
134 */
rtl_crypto_chacha_decrypt(IN const u8 * message,IN const u32 msglen,IN const u8 * iv,IN const u32 count,OUT u8 * pResult)135 int rtl_crypto_chacha_decrypt(IN const u8* message, IN const u32 msglen,
136 IN const u8* iv, IN const u32 count,
137 OUT u8* pResult)
138 {
139 HAL_CRYPTO_ADAPTER *pIE = &crypto_engine;
140 u8 count_str[4];
141
142 if ( iv == NULL ) return _ERRNO_CRYPTO_NULL_POINTER;
143 if ( (u32)(iv) & 0x3 ) return _ERRNO_CRYPTO_ADDR_NOT_4Byte_Aligned; // need to be 4-byte alignment
144 if ( message == NULL ) return _ERRNO_CRYPTO_NULL_POINTER;
145 if ( pResult == NULL ) return _ERRNO_CRYPTO_NULL_POINTER;
146
147 //rtk_cpu_to_be32(count);
148 _memcpy((void*)count_str, (const void*)(&count), sizeof(u32));
149 _memcpy((void*)(&(pIE->gcm_iv)[0]), count_str, 4);
150 _memcpy((void*)(&(pIE->gcm_iv)[4]), iv, 96/8);
151
152 return CRYPTO_CipherDecryptAD(pIE, message, msglen, (u8*)(pIE->gcm_iv), 16, NULL, 0, pResult, NULL);
153 }
154
155 /**
156 * @brief ChaCha Poly1305 initialize.
157 * @param key: Cipher key
158 * @retval Initialize status.
159 */
rtl_crypto_chacha_poly1305_init(IN const u8 * key)160 int rtl_crypto_chacha_poly1305_init(IN const u8* key)
161 {
162 HAL_CRYPTO_ADAPTER *pIE = &crypto_engine;
163
164 assert_param( (pIE != NULL) && (pIE->isInit == _TRUE) );
165 if ( key == NULL ) return _ERRNO_CRYPTO_NULL_POINTER;
166 if ( (u32)(key) & 0x3 ) return _ERRNO_CRYPTO_ADDR_NOT_4Byte_Aligned; // need to be 4-byte alignment
167
168 return CRYPTO_CipherInit(pIE, CIPHER_TYPE_CHACHA_POLY1305, key, 32);
169 }
170
171 /**
172 * @brief ChaCha Poly1305 encryption.
173 * @param message: Point to message.
174 * @param msglen: Message length.
175 * @param nonce: Random value.
176 * @param aad: Point to AAD(additional authentication data).
177 * @param aadlen: AAD length.
178 * @param pResult: Point to cipher result.
179 * @param pTag: Point to MAC(Message Authentication Code) .
180 * @retval Process status.
181 */
rtl_crypto_chacha_poly1305_encrypt(IN const u8 * message,IN const u32 msglen,IN const u8 * nonce,IN const u8 * aad,IN const u32 aadlen,OUT u8 * pResult,OUT u8 * pTag)182 int rtl_crypto_chacha_poly1305_encrypt(IN const u8* message, IN const u32 msglen,
183 IN const u8* nonce,
184 IN const u8* aad, IN const u32 aadlen,
185 OUT u8* pResult, OUT u8 *pTag)
186 {
187 HAL_CRYPTO_ADAPTER *pIE = &crypto_engine;
188 u32 count_be;
189 u8 count_str[4];
190
191 if ( nonce == NULL ) return _ERRNO_CRYPTO_NULL_POINTER;
192 if ( (u32)(nonce) & 0x3 ) return _ERRNO_CRYPTO_ADDR_NOT_4Byte_Aligned; // need to be 4-byte alignment
193 if ( message == NULL ) return _ERRNO_CRYPTO_NULL_POINTER;
194 if ( pResult == NULL ) return _ERRNO_CRYPTO_NULL_POINTER;
195 if ( pTag == NULL ) return _ERRNO_CRYPTO_NULL_POINTER;
196
197 count_be = 1;
198 //rtk_cpu_to_be32(count_be);
199 _memcpy((void*)count_str, (const void*)(&count_be), sizeof(u32));
200 _memcpy((void*)(&(pIE->gcm_iv)[0]), count_str, 4);
201 _memcpy((void*)(&(pIE->gcm_iv)[4]), nonce, 96/8);
202 CRYPTO_CipherEncryptAD(pIE, message, msglen, (u8*)(pIE->gcm_iv), 16, aad, aadlen, pResult, pTag);
203
204 return 0;
205 }
206
207 /**
208 * @brief ChaCha Poly1305 decryption.
209 * @param message: Point to message.
210 * @param msglen: Message length.
211 * @param nonce: Random value.
212 * @param aad: Point to AAD(additional authentication data).
213 * @param aadlen: AAD length.
214 * @param pResult: Point to cipher result.
215 * @param pTag: Point to MAC(Message Authentication Code) .
216 * @retval Process status.
217 */
rtl_crypto_chacha_poly1305_decrypt(IN const u8 * message,IN const u32 msglen,IN const u8 * nonce,IN const u8 * aad,IN const u32 aadlen,OUT u8 * pResult,OUT u8 * pTag)218 int rtl_crypto_chacha_poly1305_decrypt(IN const u8* message, IN const u32 msglen,
219 IN const u8* nonce,
220 IN const u8* aad, IN const u32 aadlen,
221 OUT u8* pResult, OUT u8 *pTag)
222 {
223 HAL_CRYPTO_ADAPTER *pIE = &crypto_engine;
224 u32 count_be;
225 u8 count_str[4];
226
227 if ( nonce == NULL ) return _ERRNO_CRYPTO_NULL_POINTER;
228 if ( (u32)(nonce) & 0x3 ) return _ERRNO_CRYPTO_ADDR_NOT_4Byte_Aligned; // need to be 4-byte alignment
229 if ( message == NULL ) return _ERRNO_CRYPTO_NULL_POINTER;
230 if ( (u32)(aad) & 0x3 ) return _ERRNO_CRYPTO_ADDR_NOT_4Byte_Aligned;
231 if ( pResult == NULL ) return _ERRNO_CRYPTO_NULL_POINTER;
232 if ( pTag == NULL ) return _ERRNO_CRYPTO_NULL_POINTER;
233
234 count_be = 1;
235 //rtk_cpu_to_be32(count_be);
236 _memcpy((void*)count_str, (const void*)(&count_be), sizeof(u32));
237 _memcpy((void*)(&(pIE->gcm_iv)[0]), count_str, 4);
238 _memcpy((void*)(&(pIE->gcm_iv)[4]), nonce, 96/8);
239 CRYPTO_CipherDecryptAD(pIE, message, msglen, (u8*)(pIE->gcm_iv), 16, aad, aadlen, pResult, pTag);
240
241 return 0;
242 }
243
244 /******************* (C) COPYRIGHT 2017 Realtek Semiconductor *****END OF FILE****/
245
246