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