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