1 /**
2   ******************************************************************************
3   * @file    rtl8721dhp_md5.c
4   * @author
5   * @version V1.0.0
6   * @date    2016-05-17
7   * @brief   This file provides firmware functions to manage the following
8   *          functionalities of the HW crypto:
9   *           - MD5
10   *           - HMAC MD5
11   ******************************************************************************
12   * @attention
13   *
14   * This module is a confidential and proprietary property of RealTek and
15   * possession or use of this module requires written permission of RealTek.
16   *
17   * Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
18   ******************************************************************************
19   */
20 
21 #include "ameba_soc.h"
22 #include "hal_crypto.h"
23 
24 static const u8 md5_null_msg_result[16] = {
25 	0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
26 	0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E
27 };
28 
29 /**
30   * @brief  MD5 Init.
31   * @param  none
32   * @retval	0		: SUCCESS <br>
33   *			others	: fail, refer to ERRNO
34   */
rtl_crypto_md5_init(void)35 int rtl_crypto_md5_init(void)
36 {
37 	HAL_CRYPTO_ADAPTER *pIE = &crypto_engine;
38 	const u8* pCipherKey 	= NULL;
39 	const u32 lenCipherKey 	= 0;
40 	const u8* pAuthKey 		= NULL;
41 	const u32 lenAuthKey 	= 0;
42 
43 	assert_param( (pIE != NULL) && (pIE->isInit == _TRUE) );
44 
45 	// for sequential hash
46 	pIE->hmac_seq_is_recorded = 0;
47 	pIE->hmac_seq_buf_is_used_bytes = 0;
48 
49 	return CRYPTO_SetSecurityModeAD(pIE, CIPHER_TYPE_NO_CIPHER, AUTH_TYPE_MD5,
50 		pCipherKey, lenCipherKey, pAuthKey, lenAuthKey);
51 }
52 
53 /**
54   * @brief  MD5 process.
55   * @param 	message : input buffer
56   * @param    msglen 	: input buffer length
57   * @param    pDigest	: the result of MD5 function
58   * @retval	0		: SUCCESS <br>
59   *			others	: fail, refer to ERRNO
60   */
rtl_crypto_md5_process(IN const u8 * message,IN const u32 msglen,OUT u8 * pDigest)61 int rtl_crypto_md5_process(
62 			IN const u8* message, IN const u32 msglen,
63 			OUT u8* pDigest)
64 {
65 	HAL_CRYPTO_ADAPTER *pIE = &crypto_engine;
66 
67 	if ( message == NULL ) {
68 		if ( msglen > 0 ) {
69 		    return _ERRNO_CRYPTO_NULL_POINTER;
70 		} else {
71 			_memcpy(pDigest, md5_null_msg_result, 16);
72 		}
73 	}
74 
75 	if ( (pIE->auth_type & AUTH_TYPE_MASK_FUNC) != AUTH_TYPE_MD5 )
76 		return _ERRNO_CRYPTO_AUTH_TYPE_NOT_MATCH;
77 
78 	return CRYPTO_ProcessAD(pIE, message, msglen, NULL, 0, NULL, 0, pDigest, NULL);
79 }
80 
81 /**
82   * @brief  MD5 update.
83   * @param 	message : input buffer
84   * @param    msglen 	: input buffer length
85   * @note    Use in sequential hash
86   * @retval	0		: SUCCESS <br>
87   *			others	: fail, refer to ERRNO
88   */
rtl_crypto_md5_update(IN const u8 * message,IN const u32 msglen)89 int rtl_crypto_md5_update(IN const u8* message, IN const u32 msglen)
90 {
91 	HAL_CRYPTO_ADAPTER *pIE = &crypto_engine;
92 	int ret = SUCCESS;
93 
94 	assert_param( (pIE != NULL) && (pIE->isInit == _TRUE) );
95 	assert_param(message != NULL);
96 	if ( (pIE->auth_type & AUTH_TYPE_MASK_FUNC) != AUTH_TYPE_MD5 )
97 		return _ERRNO_CRYPTO_AUTH_TYPE_NOT_MATCH;
98 /*
99 	if ( pIE->hmac_seq_is_recorded != 0 )  {
100 		ret = CRYPTO_SendSeqBuf(NULL);
101 		if ( ret != SUCCESS ) return ret;
102 	}*/
103 
104 	pIE->hmac_seq_last_message = (u8*)message;
105 	pIE->hmac_seq_last_msglen = msglen;
106 	pIE->hmac_seq_is_recorded = 1;
107 	ret = CRYPTO_SendSeqBuf(NULL);
108 
109 	return ret;
110 }
111 
112 /**
113   * @brief  MD5 final process.
114   * @param    pDigest	: the result of MD5 function
115   * @note    Use in sequential hash, process the last block
116   * @retval	0		: SUCCESS <br>
117   *			others	: fail, refer to ERRNO
118   */
rtl_crypto_md5_final(OUT u8 * pDigest)119 int rtl_crypto_md5_final(OUT u8* pDigest)
120 {
121 	HAL_CRYPTO_ADAPTER *pIE = &crypto_engine;
122 
123 	assert_param( (pIE != NULL) && (pIE->isInit == _TRUE) );
124 	if ( (pIE->auth_type & AUTH_TYPE_MASK_FUNC) != AUTH_TYPE_MD5 )
125 		return _ERRNO_CRYPTO_AUTH_TYPE_NOT_MATCH;
126 
127 	if ( pDigest == NULL ) return _ERRNO_CRYPTO_NULL_POINTER;
128 
129 	if ( pIE->hmac_seq_is_recorded == 0 ) return _ERRNO_CRYPTO_HASH_FINAL_NO_UPDATE;
130 
131 	//return CRYPTO_SendSeqBuf(pDigest);
132 	return CRYPTO_ProcessAD(pIE, (const uint8_t *)pIE->hmac_seq_buf, pIE->hmac_seq_buf_is_used_bytes, NULL, 0, NULL, 0, pDigest, NULL);
133 }
134 
135 /**
136   * @brief  MD5 init & process
137   * @param 	message : input buffer
138   * @param    msglen 	: input buffer length
139   * @param    pDigest	: the result of MD5 function
140   * @retval	0		: SUCCESS <br>
141   *			others	: fail, refer to ERRNO
142   */
rtl_crypto_md5(IN const u8 * message,IN const u32 msglen,OUT u8 * pDigest)143 int rtl_crypto_md5(IN const u8* message, IN const u32 msglen, OUT u8* pDigest)
144 {
145 	int ret;
146 
147 	ret = rtl_crypto_md5_init();
148 	if ( ret != SUCCESS ) return ret;
149 
150 	ret = rtl_crypto_md5_process(message, msglen, pDigest);
151 
152 	return ret;
153 }
154 
155 /**
156   * @brief  HMAC-MD5 init, set key
157   * @param	key		: need to be 4 byte alignment
158   * @param	keylen	: key length
159   * @retval	0		: SUCCESS <br>
160   *			others	: fail, refer to ERRNO
161   */
rtl_crypto_hmac_md5_init(IN const u8 * key,IN const u32 keylen)162 int rtl_crypto_hmac_md5_init(IN const u8* key, IN const u32 keylen)
163 {
164 	HAL_CRYPTO_ADAPTER *pIE = &crypto_engine;
165 	u8* pCipherKey = NULL;
166 	u32 lenCipherKey = 0;
167 
168 	if ( key == NULL ) return _ERRNO_CRYPTO_NULL_POINTER;
169 	if ( (u32)(key) & 0x3 ) return _ERRNO_CRYPTO_ADDR_NOT_4Byte_Aligned; // need to be 4 byte alignment
170 	if ( keylen > CRYPTO_AUTH_PADDING ) return _ERRNO_CRYPTO_KEY_OutRange;
171 
172 	assert_param( (pIE != NULL) && (pIE->isInit == _TRUE) );
173 
174 	// for sequential hash
175 	pIE->hmac_seq_is_recorded = 0;
176 	pIE->hmac_seq_buf_is_used_bytes = 0;
177 
178 	return CRYPTO_SetSecurityModeAD(pIE, CIPHER_TYPE_NO_CIPHER, AUTH_TYPE_HMAC_MD5,
179 		pCipherKey, lenCipherKey, key, keylen);
180 }
181 
182 /**
183   * @brief  brief  HMAC-MD5 process.
184   * @param 	message : input buffer
185   * @param    msglen 	: input buffer length
186   * @param    pDigest	: the result of HMAC-MD5 function
187   * @retval	0		: SUCCESS <br>
188   *			others	: fail, refer to ERRNO
189   */
rtl_crypto_hmac_md5_process(IN const u8 * message,IN const u32 msglen,OUT u8 * pDigest)190 int rtl_crypto_hmac_md5_process(
191 	IN const u8* message, 	IN const u32 msglen,
192 	OUT u8* pDigest)
193 {
194 	HAL_CRYPTO_ADAPTER *pIE = &crypto_engine;
195 
196 	if ( (pIE->auth_type & AUTH_TYPE_MASK_HMAC) == 0 )
197 		return _ERRNO_CRYPTO_AUTH_TYPE_NOT_MATCH;
198 
199 	if ( (pIE->auth_type & AUTH_TYPE_MASK_FUNC) != AUTH_TYPE_MD5 )
200 		return _ERRNO_CRYPTO_AUTH_TYPE_NOT_MATCH;
201 
202 	return CRYPTO_ProcessAD(pIE, message, msglen, NULL, 0, NULL, 0, pDigest, NULL);
203 }
204 
205 /**
206   * @brief  HMAC-MD5 update.
207   * @param 	message : input buffer
208   * @param    msglen 	: input buffer length
209   * @note    Use in sequential hash
210   * @retval	0		: SUCCESS <br>
211   *			others	: fail, refer to ERRNO
212   */
rtl_crypto_hmac_md5_update(IN const u8 * message,IN const u32 msglen)213 int rtl_crypto_hmac_md5_update(IN const u8* message, IN const u32 msglen)
214 {
215 	HAL_CRYPTO_ADAPTER *pIE = &crypto_engine;
216 	int ret = SUCCESS;
217 
218 	assert_param( (pIE != NULL) && (pIE->isInit == _TRUE) );
219 	assert_param(message != NULL);
220 	if ( (pIE->auth_type & AUTH_TYPE_MASK_HMAC) == 0 )
221 		return _ERRNO_CRYPTO_AUTH_TYPE_NOT_MATCH;
222 
223 	if ( (pIE->auth_type & AUTH_TYPE_MASK_FUNC) != AUTH_TYPE_MD5 )
224 		return _ERRNO_CRYPTO_AUTH_TYPE_NOT_MATCH;
225 /*
226 	if ( pIE->hmac_seq_is_recorded != 0 )  {
227 		ret = CRYPTO_SendSeqBuf(NULL);
228 		if ( ret != SUCCESS ) return ret;
229 	}
230 */
231 	pIE->hmac_seq_last_message = (u8*)message;
232 	pIE->hmac_seq_last_msglen = msglen;
233 	pIE->hmac_seq_is_recorded = 1;
234 	ret = CRYPTO_SendSeqBuf(NULL);
235 
236 	return ret;
237 }
238 
239 /**
240   * @brief  HMAC-MD5 final process.
241   * @param    pDigest	: the result of HMAC-MD5 function
242   * @note    Use in sequential hash, process the last block
243   * @retval	0		: SUCCESS <br>
244   *			others	: fail, refer to ERRNO
245   */
rtl_crypto_hmac_md5_final(OUT u8 * pDigest)246 int rtl_crypto_hmac_md5_final(OUT u8* pDigest)
247 {
248 	HAL_CRYPTO_ADAPTER *pIE = &crypto_engine;
249 
250 	assert_param( (pIE != NULL) && (pIE->isInit == _TRUE) );
251 	if ( (pIE->auth_type & AUTH_TYPE_MASK_HMAC) == 0 )
252 		return _ERRNO_CRYPTO_AUTH_TYPE_NOT_MATCH;
253 
254 	if ( (pIE->auth_type & AUTH_TYPE_MASK_FUNC) != AUTH_TYPE_MD5 )
255 		return _ERRNO_CRYPTO_AUTH_TYPE_NOT_MATCH;
256 
257 	if ( pDigest == NULL ) return _ERRNO_CRYPTO_NULL_POINTER;
258 
259 	if ( pIE->hmac_seq_is_recorded == 0 ) return _ERRNO_CRYPTO_HASH_FINAL_NO_UPDATE;
260 
261 	//return CRYPTO_SendSeqBuf(pDigest);
262 	return CRYPTO_ProcessAD(pIE, (const uint8_t *)pIE->hmac_seq_buf, pIE->hmac_seq_buf_is_used_bytes, NULL, 0, NULL, 0, pDigest, NULL);
263 }
264 
265 /**
266   * @brief  HMAC-MD5 init & process
267   * @param	key		: need to be 4 byte alignment
268   * @param	keylen	: key length
269   * @param 	message : input buffer
270   * @param    msglen 	: input buffer length
271   * @param    pDigest	: the result of HMAC-MD5 function
272   * @retval	0		: SUCCESS <br>
273   *			others	: fail, refer to ERRNO
274   */
rtl_crypto_hmac_md5(IN const u8 * message,IN const u32 msglen,IN const u8 * key,IN const u32 keylen,OUT u8 * pDigest)275 int rtl_crypto_hmac_md5(
276 	IN const u8* message, 	IN const u32 msglen,
277 	IN const u8* key, 		IN const u32 keylen,
278 	OUT u8* pDigest)
279 {
280 	int ret;
281 
282 	ret = rtl_crypto_hmac_md5_init(key, keylen);
283 	if ( ret != SUCCESS ) return ret;
284 
285 	ret = rtl_crypto_hmac_md5_process(message, msglen, pDigest);
286 
287 	return ret;
288 }
289 /******************* (C) COPYRIGHT 2016 Realtek Semiconductor *****END OF FILE****/
290