OLD | NEW |
| (Empty) |
1 /* This Source Code Form is subject to the terms of the Mozilla Public | |
2 * License, v. 2.0. If a copy of the MPL was not distributed with this | |
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
4 #include "sechash.h" | |
5 #include "secoidt.h" | |
6 #include "secerr.h" | |
7 #include "blapi.h" | |
8 #include "pk11func.h" /* for the PK11_ calls below. */ | |
9 | |
10 static void * | |
11 null_hash_new_context(void) | |
12 { | |
13 return NULL; | |
14 } | |
15 | |
16 static void * | |
17 null_hash_clone_context(void *v) | |
18 { | |
19 PORT_Assert(v == NULL); | |
20 return NULL; | |
21 } | |
22 | |
23 static void | |
24 null_hash_begin(void *v) | |
25 { | |
26 } | |
27 | |
28 static void | |
29 null_hash_update(void *v, const unsigned char *input, unsigned int length) | |
30 { | |
31 } | |
32 | |
33 static void | |
34 null_hash_end(void *v, unsigned char *output, unsigned int *outLen, | |
35 unsigned int maxOut) | |
36 { | |
37 *outLen = 0; | |
38 } | |
39 | |
40 static void | |
41 null_hash_destroy_context(void *v, PRBool b) | |
42 { | |
43 PORT_Assert(v == NULL); | |
44 } | |
45 | |
46 static void * | |
47 md2_NewContext(void) | |
48 { | |
49 return (void *)PK11_CreateDigestContext(SEC_OID_MD2); | |
50 } | |
51 | |
52 static void * | |
53 md5_NewContext(void) | |
54 { | |
55 return (void *)PK11_CreateDigestContext(SEC_OID_MD5); | |
56 } | |
57 | |
58 static void * | |
59 sha1_NewContext(void) | |
60 { | |
61 return (void *)PK11_CreateDigestContext(SEC_OID_SHA1); | |
62 } | |
63 | |
64 static void * | |
65 sha224_NewContext(void) | |
66 { | |
67 return (void *)PK11_CreateDigestContext(SEC_OID_SHA224); | |
68 } | |
69 | |
70 static void * | |
71 sha256_NewContext(void) | |
72 { | |
73 return (void *)PK11_CreateDigestContext(SEC_OID_SHA256); | |
74 } | |
75 | |
76 static void * | |
77 sha384_NewContext(void) | |
78 { | |
79 return (void *)PK11_CreateDigestContext(SEC_OID_SHA384); | |
80 } | |
81 | |
82 static void * | |
83 sha512_NewContext(void) | |
84 { | |
85 return (void *)PK11_CreateDigestContext(SEC_OID_SHA512); | |
86 } | |
87 | |
88 const SECHashObject SECHashObjects[] = { | |
89 { 0, | |
90 (void *(*)(void))null_hash_new_context, | |
91 (void *(*)(void *))null_hash_clone_context, | |
92 (void (*)(void *, PRBool))null_hash_destroy_context, | |
93 (void (*)(void *))null_hash_begin, | |
94 (void (*)(void *, const unsigned char *, unsigned int))null_hash_update, | |
95 (void (*)(void *, unsigned char *, unsigned int *, | |
96 unsigned int))null_hash_end, | |
97 0, | |
98 HASH_AlgNULL }, | |
99 { MD2_LENGTH, | |
100 (void *(*)(void))md2_NewContext, | |
101 (void *(*)(void *))PK11_CloneContext, | |
102 (void (*)(void *, PRBool))PK11_DestroyContext, | |
103 (void (*)(void *))PK11_DigestBegin, | |
104 (void (*)(void *, const unsigned char *, unsigned int))PK11_DigestOp, | |
105 (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) | |
106 PK11_DigestFinal, | |
107 MD2_BLOCK_LENGTH, | |
108 HASH_AlgMD2 }, | |
109 { MD5_LENGTH, | |
110 (void *(*)(void))md5_NewContext, | |
111 (void *(*)(void *))PK11_CloneContext, | |
112 (void (*)(void *, PRBool))PK11_DestroyContext, | |
113 (void (*)(void *))PK11_DigestBegin, | |
114 (void (*)(void *, const unsigned char *, unsigned int))PK11_DigestOp, | |
115 (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) | |
116 PK11_DigestFinal, | |
117 MD5_BLOCK_LENGTH, | |
118 HASH_AlgMD5 }, | |
119 { SHA1_LENGTH, | |
120 (void *(*)(void))sha1_NewContext, | |
121 (void *(*)(void *))PK11_CloneContext, | |
122 (void (*)(void *, PRBool))PK11_DestroyContext, | |
123 (void (*)(void *))PK11_DigestBegin, | |
124 (void (*)(void *, const unsigned char *, unsigned int))PK11_DigestOp, | |
125 (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) | |
126 PK11_DigestFinal, | |
127 SHA1_BLOCK_LENGTH, | |
128 HASH_AlgSHA1 }, | |
129 { SHA256_LENGTH, | |
130 (void *(*)(void))sha256_NewContext, | |
131 (void *(*)(void *))PK11_CloneContext, | |
132 (void (*)(void *, PRBool))PK11_DestroyContext, | |
133 (void (*)(void *))PK11_DigestBegin, | |
134 (void (*)(void *, const unsigned char *, unsigned int))PK11_DigestOp, | |
135 (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) | |
136 PK11_DigestFinal, | |
137 SHA256_BLOCK_LENGTH, | |
138 HASH_AlgSHA256 }, | |
139 { SHA384_LENGTH, | |
140 (void *(*)(void))sha384_NewContext, | |
141 (void *(*)(void *))PK11_CloneContext, | |
142 (void (*)(void *, PRBool))PK11_DestroyContext, | |
143 (void (*)(void *))PK11_DigestBegin, | |
144 (void (*)(void *, const unsigned char *, unsigned int))PK11_DigestOp, | |
145 (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) | |
146 PK11_DigestFinal, | |
147 SHA384_BLOCK_LENGTH, | |
148 HASH_AlgSHA384 }, | |
149 { SHA512_LENGTH, | |
150 (void *(*)(void))sha512_NewContext, | |
151 (void *(*)(void *))PK11_CloneContext, | |
152 (void (*)(void *, PRBool))PK11_DestroyContext, | |
153 (void (*)(void *))PK11_DigestBegin, | |
154 (void (*)(void *, const unsigned char *, unsigned int))PK11_DigestOp, | |
155 (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) | |
156 PK11_DigestFinal, | |
157 SHA512_BLOCK_LENGTH, | |
158 HASH_AlgSHA512 }, | |
159 { SHA224_LENGTH, | |
160 (void *(*)(void))sha224_NewContext, | |
161 (void *(*)(void *))PK11_CloneContext, | |
162 (void (*)(void *, PRBool))PK11_DestroyContext, | |
163 (void (*)(void *))PK11_DigestBegin, | |
164 (void (*)(void *, const unsigned char *, unsigned int))PK11_DigestOp, | |
165 (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) | |
166 PK11_DigestFinal, | |
167 SHA224_BLOCK_LENGTH, | |
168 HASH_AlgSHA224 }, | |
169 }; | |
170 | |
171 const SECHashObject * | |
172 HASH_GetHashObject(HASH_HashType type) | |
173 { | |
174 return &SECHashObjects[type]; | |
175 } | |
176 | |
177 HASH_HashType | |
178 HASH_GetHashTypeByOidTag(SECOidTag hashOid) | |
179 { | |
180 HASH_HashType ht = HASH_AlgNULL; | |
181 | |
182 switch (hashOid) { | |
183 case SEC_OID_MD2: | |
184 ht = HASH_AlgMD2; | |
185 break; | |
186 case SEC_OID_MD5: | |
187 ht = HASH_AlgMD5; | |
188 break; | |
189 case SEC_OID_SHA1: | |
190 ht = HASH_AlgSHA1; | |
191 break; | |
192 case SEC_OID_SHA224: | |
193 ht = HASH_AlgSHA224; | |
194 break; | |
195 case SEC_OID_SHA256: | |
196 ht = HASH_AlgSHA256; | |
197 break; | |
198 case SEC_OID_SHA384: | |
199 ht = HASH_AlgSHA384; | |
200 break; | |
201 case SEC_OID_SHA512: | |
202 ht = HASH_AlgSHA512; | |
203 break; | |
204 default: | |
205 ht = HASH_AlgNULL; | |
206 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); | |
207 break; | |
208 } | |
209 return ht; | |
210 } | |
211 | |
212 SECOidTag | |
213 HASH_GetHashOidTagByHMACOidTag(SECOidTag hmacOid) | |
214 { | |
215 SECOidTag hashOid = SEC_OID_UNKNOWN; | |
216 | |
217 switch (hmacOid) { | |
218 /* no oid exists for HMAC_MD2 */ | |
219 /* NSS does not define a oid for HMAC_MD4 */ | |
220 case SEC_OID_HMAC_SHA1: | |
221 hashOid = SEC_OID_SHA1; | |
222 break; | |
223 case SEC_OID_HMAC_SHA224: | |
224 hashOid = SEC_OID_SHA224; | |
225 break; | |
226 case SEC_OID_HMAC_SHA256: | |
227 hashOid = SEC_OID_SHA256; | |
228 break; | |
229 case SEC_OID_HMAC_SHA384: | |
230 hashOid = SEC_OID_SHA384; | |
231 break; | |
232 case SEC_OID_HMAC_SHA512: | |
233 hashOid = SEC_OID_SHA512; | |
234 break; | |
235 default: | |
236 hashOid = SEC_OID_UNKNOWN; | |
237 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); | |
238 break; | |
239 } | |
240 return hashOid; | |
241 } | |
242 | |
243 SECOidTag | |
244 HASH_GetHMACOidTagByHashOidTag(SECOidTag hashOid) | |
245 { | |
246 SECOidTag hmacOid = SEC_OID_UNKNOWN; | |
247 | |
248 switch (hashOid) { | |
249 /* no oid exists for HMAC_MD2 */ | |
250 /* NSS does not define a oid for HMAC_MD4 */ | |
251 case SEC_OID_SHA1: | |
252 hmacOid = SEC_OID_HMAC_SHA1; | |
253 break; | |
254 case SEC_OID_SHA224: | |
255 hmacOid = SEC_OID_HMAC_SHA224; | |
256 break; | |
257 case SEC_OID_SHA256: | |
258 hmacOid = SEC_OID_HMAC_SHA256; | |
259 break; | |
260 case SEC_OID_SHA384: | |
261 hmacOid = SEC_OID_HMAC_SHA384; | |
262 break; | |
263 case SEC_OID_SHA512: | |
264 hmacOid = SEC_OID_HMAC_SHA512; | |
265 break; | |
266 default: | |
267 hmacOid = SEC_OID_UNKNOWN; | |
268 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); | |
269 break; | |
270 } | |
271 return hmacOid; | |
272 } | |
273 | |
274 const SECHashObject * | |
275 HASH_GetHashObjectByOidTag(SECOidTag hashOid) | |
276 { | |
277 HASH_HashType ht = HASH_GetHashTypeByOidTag(hashOid); | |
278 | |
279 return (ht == HASH_AlgNULL) ? NULL : &SECHashObjects[ht]; | |
280 } | |
281 | |
282 /* returns zero for unknown hash OID */ | |
283 unsigned int | |
284 HASH_ResultLenByOidTag(SECOidTag hashOid) | |
285 { | |
286 const SECHashObject *hashObject = HASH_GetHashObjectByOidTag(hashOid); | |
287 unsigned int resultLen = 0; | |
288 | |
289 if (hashObject) | |
290 resultLen = hashObject->length; | |
291 return resultLen; | |
292 } | |
293 | |
294 /* returns zero if hash type invalid. */ | |
295 unsigned int | |
296 HASH_ResultLen(HASH_HashType type) | |
297 { | |
298 if ((type < HASH_AlgNULL) || (type >= HASH_AlgTOTAL)) { | |
299 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); | |
300 return (0); | |
301 } | |
302 | |
303 return (SECHashObjects[type].length); | |
304 } | |
305 | |
306 unsigned int | |
307 HASH_ResultLenContext(HASHContext *context) | |
308 { | |
309 return (context->hashobj->length); | |
310 } | |
311 | |
312 SECStatus | |
313 HASH_HashBuf(HASH_HashType type, | |
314 unsigned char *dest, | |
315 const unsigned char *src, | |
316 PRUint32 src_len) | |
317 { | |
318 HASHContext *cx; | |
319 unsigned int part; | |
320 | |
321 if ((type < HASH_AlgNULL) || (type >= HASH_AlgTOTAL)) { | |
322 return (SECFailure); | |
323 } | |
324 | |
325 cx = HASH_Create(type); | |
326 if (cx == NULL) { | |
327 return (SECFailure); | |
328 } | |
329 HASH_Begin(cx); | |
330 HASH_Update(cx, src, src_len); | |
331 HASH_End(cx, dest, &part, HASH_ResultLenContext(cx)); | |
332 HASH_Destroy(cx); | |
333 | |
334 return (SECSuccess); | |
335 } | |
336 | |
337 HASHContext * | |
338 HASH_Create(HASH_HashType type) | |
339 { | |
340 void *hash_context = NULL; | |
341 HASHContext *ret = NULL; | |
342 | |
343 if ((type < HASH_AlgNULL) || (type >= HASH_AlgTOTAL)) { | |
344 return (NULL); | |
345 } | |
346 | |
347 hash_context = (*SECHashObjects[type].create)(); | |
348 if (hash_context == NULL) { | |
349 goto loser; | |
350 } | |
351 | |
352 ret = (HASHContext *)PORT_Alloc(sizeof(HASHContext)); | |
353 if (ret == NULL) { | |
354 goto loser; | |
355 } | |
356 | |
357 ret->hash_context = hash_context; | |
358 ret->hashobj = &SECHashObjects[type]; | |
359 | |
360 return (ret); | |
361 | |
362 loser: | |
363 if (hash_context != NULL) { | |
364 (*SECHashObjects[type].destroy)(hash_context, PR_TRUE); | |
365 } | |
366 | |
367 return (NULL); | |
368 } | |
369 | |
370 HASHContext * | |
371 HASH_Clone(HASHContext *context) | |
372 { | |
373 void *hash_context = NULL; | |
374 HASHContext *ret = NULL; | |
375 | |
376 hash_context = (*context->hashobj->clone)(context->hash_context); | |
377 if (hash_context == NULL) { | |
378 goto loser; | |
379 } | |
380 | |
381 ret = (HASHContext *)PORT_Alloc(sizeof(HASHContext)); | |
382 if (ret == NULL) { | |
383 goto loser; | |
384 } | |
385 | |
386 ret->hash_context = hash_context; | |
387 ret->hashobj = context->hashobj; | |
388 | |
389 return (ret); | |
390 | |
391 loser: | |
392 if (hash_context != NULL) { | |
393 (*context->hashobj->destroy)(hash_context, PR_TRUE); | |
394 } | |
395 | |
396 return (NULL); | |
397 } | |
398 | |
399 void | |
400 HASH_Destroy(HASHContext *context) | |
401 { | |
402 (*context->hashobj->destroy)(context->hash_context, PR_TRUE); | |
403 PORT_Free(context); | |
404 return; | |
405 } | |
406 | |
407 void | |
408 HASH_Begin(HASHContext *context) | |
409 { | |
410 (*context->hashobj->begin)(context->hash_context); | |
411 return; | |
412 } | |
413 | |
414 void | |
415 HASH_Update(HASHContext *context, | |
416 const unsigned char *src, | |
417 unsigned int len) | |
418 { | |
419 (*context->hashobj->update)(context->hash_context, src, len); | |
420 return; | |
421 } | |
422 | |
423 void | |
424 HASH_End(HASHContext *context, | |
425 unsigned char *result, | |
426 unsigned int *result_len, | |
427 unsigned int max_result_len) | |
428 { | |
429 (*context->hashobj->end)(context->hash_context, result, result_len, | |
430 max_result_len); | |
431 return; | |
432 } | |
433 | |
434 HASH_HashType | |
435 HASH_GetType(HASHContext *context) | |
436 { | |
437 return (context->hashobj->type); | |
438 } | |
OLD | NEW |