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