Imported Upstream version 3.13.6
[platform/upstream/nss.git] / mozilla / security / nss / lib / cryptohi / sechash.c
1 /* ***** BEGIN LICENSE BLOCK *****
2  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3  *
4  * The contents of this file are subject to the Mozilla Public License Version
5  * 1.1 (the "License"); you may not use this file except in compliance with
6  * the License. You may obtain a copy of the License at
7  * http://www.mozilla.org/MPL/
8  *
9  * Software distributed under the License is distributed on an "AS IS" basis,
10  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11  * for the specific language governing rights and limitations under the
12  * License.
13  *
14  * The Original Code is the Netscape security libraries.
15  *
16  * The Initial Developer of the Original Code is
17  * Netscape Communications Corporation.
18  * Portions created by the Initial Developer are Copyright (C) 1994-2000
19  * the Initial Developer. All Rights Reserved.
20  *
21  * Contributor(s):
22  *
23  * Alternatively, the contents of this file may be used under the terms of
24  * either the GNU General Public License Version 2 or later (the "GPL"), or
25  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26  * in which case the provisions of the GPL or the LGPL are applicable instead
27  * of those above. If you wish to allow use of your version of this file only
28  * under the terms of either the GPL or the LGPL, and not to allow others to
29  * use your version of this file under the terms of the MPL, indicate your
30  * decision by deleting the provisions above and replace them with the notice
31  * and other provisions required by the GPL or the LGPL. If you do not delete
32  * the provisions above, a recipient may use your version of this file under
33  * the terms of any one of the MPL, the GPL or the LGPL.
34  *
35  * ***** END LICENSE BLOCK ***** */
36 #include "sechash.h"
37 #include "secoidt.h"
38 #include "secerr.h"
39 #include "blapi.h"
40 #include "pk11func.h"   /* for the PK11_ calls below. */
41
42 static void *
43 null_hash_new_context(void)
44 {
45     return NULL;
46 }
47
48 static void *
49 null_hash_clone_context(void *v)
50 {
51     PORT_Assert(v == NULL);
52     return NULL;
53 }
54
55 static void
56 null_hash_begin(void *v)
57 {
58 }
59
60 static void
61 null_hash_update(void *v, const unsigned char *input, unsigned int length)
62 {
63 }
64
65 static void
66 null_hash_end(void *v, unsigned char *output, unsigned int *outLen,
67               unsigned int maxOut)
68 {
69     *outLen = 0;
70 }
71
72 static void
73 null_hash_destroy_context(void *v, PRBool b)
74 {
75     PORT_Assert(v == NULL);
76 }
77
78
79 static void *
80 md2_NewContext(void) {
81         return (void *) PK11_CreateDigestContext(SEC_OID_MD2);
82 }
83
84 static void *
85 md5_NewContext(void) {
86         return (void *) PK11_CreateDigestContext(SEC_OID_MD5);
87 }
88
89 static void *
90 sha1_NewContext(void) {
91         return (void *) PK11_CreateDigestContext(SEC_OID_SHA1);
92 }
93
94 static void *
95 sha224_NewContext(void) {
96         return (void *) PK11_CreateDigestContext(SEC_OID_SHA224);
97 }
98
99 static void *
100 sha256_NewContext(void) {
101         return (void *) PK11_CreateDigestContext(SEC_OID_SHA256);
102 }
103
104 static void *
105 sha384_NewContext(void) {
106         return (void *) PK11_CreateDigestContext(SEC_OID_SHA384);
107 }
108
109 static void *
110 sha512_NewContext(void) {
111         return (void *) PK11_CreateDigestContext(SEC_OID_SHA512);
112 }
113
114 const SECHashObject SECHashObjects[] = {
115   { 0,
116     (void * (*)(void)) null_hash_new_context,
117     (void * (*)(void *)) null_hash_clone_context,
118     (void (*)(void *, PRBool)) null_hash_destroy_context,
119     (void (*)(void *)) null_hash_begin,
120     (void (*)(void *, const unsigned char *, unsigned int)) null_hash_update,
121     (void (*)(void *, unsigned char *, unsigned int *,
122               unsigned int)) null_hash_end,
123     0,
124     HASH_AlgNULL
125   },
126   { MD2_LENGTH,
127     (void * (*)(void)) md2_NewContext,
128     (void * (*)(void *)) PK11_CloneContext,
129     (void (*)(void *, PRBool)) PK11_DestroyContext,
130     (void (*)(void *)) PK11_DigestBegin,
131     (void (*)(void *, const unsigned char *, unsigned int)) PK11_DigestOp,
132     (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) 
133                                                         PK11_DigestFinal,
134     MD2_BLOCK_LENGTH,
135     HASH_AlgMD2
136   },
137   { MD5_LENGTH,
138     (void * (*)(void)) md5_NewContext,
139     (void * (*)(void *)) PK11_CloneContext,
140     (void (*)(void *, PRBool)) PK11_DestroyContext,
141     (void (*)(void *)) PK11_DigestBegin,
142     (void (*)(void *, const unsigned char *, unsigned int)) PK11_DigestOp,
143     (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) 
144                                                         PK11_DigestFinal,
145     MD5_BLOCK_LENGTH,
146     HASH_AlgMD5
147   },
148   { SHA1_LENGTH,
149     (void * (*)(void)) sha1_NewContext,
150     (void * (*)(void *)) PK11_CloneContext,
151     (void (*)(void *, PRBool)) PK11_DestroyContext,
152     (void (*)(void *)) PK11_DigestBegin,
153     (void (*)(void *, const unsigned char *, unsigned int)) PK11_DigestOp,
154     (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) 
155                                                         PK11_DigestFinal,
156     SHA1_BLOCK_LENGTH,
157     HASH_AlgSHA1
158   },
159   { SHA256_LENGTH,
160     (void * (*)(void)) sha256_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     SHA256_BLOCK_LENGTH,
168     HASH_AlgSHA256
169   },
170   { SHA384_LENGTH,
171     (void * (*)(void)) sha384_NewContext,
172     (void * (*)(void *)) PK11_CloneContext,
173     (void (*)(void *, PRBool)) PK11_DestroyContext,
174     (void (*)(void *)) PK11_DigestBegin,
175     (void (*)(void *, const unsigned char *, unsigned int)) PK11_DigestOp,
176     (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) 
177                                                         PK11_DigestFinal,
178     SHA384_BLOCK_LENGTH,
179     HASH_AlgSHA384
180   },
181   { SHA512_LENGTH,
182     (void * (*)(void)) sha512_NewContext,
183     (void * (*)(void *)) PK11_CloneContext,
184     (void (*)(void *, PRBool)) PK11_DestroyContext,
185     (void (*)(void *)) PK11_DigestBegin,
186     (void (*)(void *, const unsigned char *, unsigned int)) PK11_DigestOp,
187     (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) 
188                                                         PK11_DigestFinal,
189     SHA512_BLOCK_LENGTH,
190     HASH_AlgSHA512
191   },
192   { SHA224_LENGTH,
193     (void * (*)(void)) sha224_NewContext,
194     (void * (*)(void *)) PK11_CloneContext,
195     (void (*)(void *, PRBool)) PK11_DestroyContext,
196     (void (*)(void *)) PK11_DigestBegin,
197     (void (*)(void *, const unsigned char *, unsigned int)) PK11_DigestOp,
198     (void (*)(void *, unsigned char *, unsigned int *, unsigned int))
199                                                         PK11_DigestFinal,
200     SHA224_BLOCK_LENGTH,
201     HASH_AlgSHA224
202   },
203 };
204
205 const SECHashObject * 
206 HASH_GetHashObject(HASH_HashType type)
207 {
208     return &SECHashObjects[type];
209 }
210
211 HASH_HashType
212 HASH_GetHashTypeByOidTag(SECOidTag hashOid)
213 {
214     HASH_HashType ht    = HASH_AlgNULL;
215
216     switch(hashOid) {
217     case SEC_OID_MD2:    ht = HASH_AlgMD2;    break;
218     case SEC_OID_MD5:    ht = HASH_AlgMD5;    break;
219     case SEC_OID_SHA1:   ht = HASH_AlgSHA1;   break;
220     case SEC_OID_SHA224: ht = HASH_AlgSHA224; break;
221     case SEC_OID_SHA256: ht = HASH_AlgSHA256; break;
222     case SEC_OID_SHA384: ht = HASH_AlgSHA384; break;
223     case SEC_OID_SHA512: ht = HASH_AlgSHA512; break;
224     default:             ht = HASH_AlgNULL;   
225         PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
226         break;
227     }
228     return ht;
229 }
230
231 SECOidTag
232 HASH_GetHashOidTagByHMACOidTag(SECOidTag hmacOid)
233 {
234     SECOidTag hashOid = SEC_OID_UNKNOWN;
235
236     switch(hmacOid) {
237     /* no oid exists for HMAC_MD2 */
238     /* NSS does not define a oid for HMAC_MD4 */
239     case SEC_OID_HMAC_SHA1:   hashOid = SEC_OID_SHA1;   break;
240     case SEC_OID_HMAC_SHA224: hashOid = SEC_OID_SHA224; break;
241     case SEC_OID_HMAC_SHA256: hashOid = SEC_OID_SHA256; break;
242     case SEC_OID_HMAC_SHA384: hashOid = SEC_OID_SHA384; break;
243     case SEC_OID_HMAC_SHA512: hashOid = SEC_OID_SHA512; break;
244     default:                  hashOid = SEC_OID_UNKNOWN;   
245         PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
246         break;
247     }
248     return hashOid;
249 }
250
251 SECOidTag
252 HASH_GetHMACOidTagByHashOidTag(SECOidTag hashOid)
253 {
254     SECOidTag hmacOid = SEC_OID_UNKNOWN;
255
256     switch(hashOid) {
257     /* no oid exists for HMAC_MD2 */
258     /* NSS does not define a oid for HMAC_MD4 */
259     case SEC_OID_SHA1:   hmacOid = SEC_OID_HMAC_SHA1;   break;
260     case SEC_OID_SHA224: hmacOid = SEC_OID_HMAC_SHA224; break;
261     case SEC_OID_SHA256: hmacOid = SEC_OID_HMAC_SHA256; break;
262     case SEC_OID_SHA384: hmacOid = SEC_OID_HMAC_SHA384; break;
263     case SEC_OID_SHA512: hmacOid = SEC_OID_HMAC_SHA512; break;
264     default:             hmacOid = SEC_OID_UNKNOWN;   
265         PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
266         break;
267     }
268     return hmacOid;
269 }
270
271 const SECHashObject * 
272 HASH_GetHashObjectByOidTag(SECOidTag hashOid)
273 {
274     HASH_HashType ht    = HASH_GetHashTypeByOidTag(hashOid);
275
276     return (ht == HASH_AlgNULL) ? NULL : &SECHashObjects[ht];
277 }
278
279 /* returns zero for unknown hash OID */
280 unsigned int
281 HASH_ResultLenByOidTag(SECOidTag hashOid)
282 {
283     const SECHashObject * hashObject = HASH_GetHashObjectByOidTag(hashOid);
284     unsigned int          resultLen = 0;
285
286     if (hashObject)
287         resultLen = hashObject->length;
288     return resultLen;
289 }
290
291 /* returns zero if hash type invalid. */
292 unsigned int
293 HASH_ResultLen(HASH_HashType type)
294 {
295     if ( ( type < HASH_AlgNULL ) || ( type >= HASH_AlgTOTAL ) ) {
296         PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
297         return(0);
298     }
299     
300     return(SECHashObjects[type].length);
301 }
302
303 unsigned int
304 HASH_ResultLenContext(HASHContext *context)
305 {
306     return(context->hashobj->length);
307 }
308
309
310
311 SECStatus
312 HASH_HashBuf(HASH_HashType type,
313              unsigned char *dest,
314              unsigned char *src,
315              PRUint32 src_len)
316 {
317     HASHContext *cx;
318     unsigned int part;
319     
320     if ( ( type < HASH_AlgNULL ) || ( type >= HASH_AlgTOTAL ) ) {
321         return(SECFailure);
322     }
323     
324     cx = HASH_Create(type);
325     if ( cx == NULL ) {
326         return(SECFailure);
327     }
328     HASH_Begin(cx);
329     HASH_Update(cx, src, src_len);
330     HASH_End(cx, dest, &part, HASH_ResultLenContext(cx));
331     HASH_Destroy(cx);
332
333     return(SECSuccess);
334 }
335
336 HASHContext *
337 HASH_Create(HASH_HashType type)
338 {
339     void *hash_context = NULL;
340     HASHContext *ret = NULL;
341     
342     if ( ( type < HASH_AlgNULL ) || ( type >= HASH_AlgTOTAL ) ) {
343         return(NULL);
344     }
345     
346     hash_context = (* SECHashObjects[type].create)();
347     if ( hash_context == NULL ) {
348         goto loser;
349     }
350
351     ret = (HASHContext *)PORT_Alloc(sizeof(HASHContext));
352     if ( ret == NULL ) {
353         goto loser;
354     }
355
356     ret->hash_context = hash_context;
357     ret->hashobj = &SECHashObjects[type];
358     
359     return(ret);
360     
361 loser:
362     if ( hash_context != NULL ) {
363         (* SECHashObjects[type].destroy)(hash_context, PR_TRUE);
364     }
365     
366     return(NULL);
367 }
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
400 void
401 HASH_Destroy(HASHContext *context)
402 {
403     (* context->hashobj->destroy)(context->hash_context, PR_TRUE);
404     PORT_Free(context);
405     return;
406 }
407
408
409 void
410 HASH_Begin(HASHContext *context)
411 {
412     (* context->hashobj->begin)(context->hash_context);
413     return;
414 }
415
416
417 void
418 HASH_Update(HASHContext *context,
419             const unsigned char *src,
420             unsigned int len)
421 {
422     (* context->hashobj->update)(context->hash_context, src, len);
423     return;
424 }
425
426 void
427 HASH_End(HASHContext *context,
428          unsigned char *result,
429          unsigned int *result_len,
430          unsigned int max_result_len)
431 {
432     (* context->hashobj->end)(context->hash_context, result, result_len,
433                               max_result_len);
434     return;
435 }
436
437 HASH_HashType
438 HASH_GetType(HASHContext *context)
439 {
440     return(context->hashobj->type);
441 }