Back to index

lightning-sunbird  0.9+nobinonly
sechash.c
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is the Netscape security libraries.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 1994-2000
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 #include "sechash.h"
00037 #include "secoidt.h"
00038 #include "secerr.h"
00039 #include "blapi.h"
00040 #include "pk11func.h"       /* for the PK11_ calls below. */
00041 
00042 static void *
00043 null_hash_new_context(void)
00044 {
00045     return NULL;
00046 }
00047 
00048 static void *
00049 null_hash_clone_context(void *v)
00050 {
00051     PORT_Assert(v == NULL);
00052     return NULL;
00053 }
00054 
00055 static void
00056 null_hash_begin(void *v)
00057 {
00058 }
00059 
00060 static void
00061 null_hash_update(void *v, const unsigned char *input, unsigned int length)
00062 {
00063 }
00064 
00065 static void
00066 null_hash_end(void *v, unsigned char *output, unsigned int *outLen,
00067              unsigned int maxOut)
00068 {
00069     *outLen = 0;
00070 }
00071 
00072 static void
00073 null_hash_destroy_context(void *v, PRBool b)
00074 {
00075     PORT_Assert(v == NULL);
00076 }
00077 
00078 
00079 static void *
00080 md2_NewContext(void) {
00081        return (void *) PK11_CreateDigestContext(SEC_OID_MD2);
00082 }
00083 
00084 static void *
00085 md5_NewContext(void) {
00086        return (void *) PK11_CreateDigestContext(SEC_OID_MD5);
00087 }
00088 
00089 static void *
00090 sha1_NewContext(void) {
00091        return (void *) PK11_CreateDigestContext(SEC_OID_SHA1);
00092 }
00093 
00094 static void *
00095 sha256_NewContext(void) {
00096        return (void *) PK11_CreateDigestContext(SEC_OID_SHA256);
00097 }
00098 
00099 static void *
00100 sha384_NewContext(void) {
00101        return (void *) PK11_CreateDigestContext(SEC_OID_SHA384);
00102 }
00103 
00104 static void *
00105 sha512_NewContext(void) {
00106        return (void *) PK11_CreateDigestContext(SEC_OID_SHA512);
00107 }
00108 
00109 const SECHashObject SECHashObjects[] = {
00110   { 0,
00111     (void * (*)(void)) null_hash_new_context,
00112     (void * (*)(void *)) null_hash_clone_context,
00113     (void (*)(void *, PRBool)) null_hash_destroy_context,
00114     (void (*)(void *)) null_hash_begin,
00115     (void (*)(void *, const unsigned char *, unsigned int)) null_hash_update,
00116     (void (*)(void *, unsigned char *, unsigned int *,
00117              unsigned int)) null_hash_end,
00118     0,
00119     HASH_AlgNULL
00120   },
00121   { MD2_LENGTH,
00122     (void * (*)(void)) md2_NewContext,
00123     (void * (*)(void *)) PK11_CloneContext,
00124     (void (*)(void *, PRBool)) PK11_DestroyContext,
00125     (void (*)(void *)) PK11_DigestBegin,
00126     (void (*)(void *, const unsigned char *, unsigned int)) PK11_DigestOp,
00127     (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) 
00128                                                  PK11_DigestFinal,
00129     MD2_BLOCK_LENGTH,
00130     HASH_AlgMD2
00131   },
00132   { MD5_LENGTH,
00133     (void * (*)(void)) md5_NewContext,
00134     (void * (*)(void *)) PK11_CloneContext,
00135     (void (*)(void *, PRBool)) PK11_DestroyContext,
00136     (void (*)(void *)) PK11_DigestBegin,
00137     (void (*)(void *, const unsigned char *, unsigned int)) PK11_DigestOp,
00138     (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) 
00139                                                  PK11_DigestFinal,
00140     MD5_BLOCK_LENGTH,
00141     HASH_AlgMD5
00142   },
00143   { SHA1_LENGTH,
00144     (void * (*)(void)) sha1_NewContext,
00145     (void * (*)(void *)) PK11_CloneContext,
00146     (void (*)(void *, PRBool)) PK11_DestroyContext,
00147     (void (*)(void *)) PK11_DigestBegin,
00148     (void (*)(void *, const unsigned char *, unsigned int)) PK11_DigestOp,
00149     (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) 
00150                                                  PK11_DigestFinal,
00151     SHA1_BLOCK_LENGTH,
00152     HASH_AlgSHA1
00153   },
00154   { SHA256_LENGTH,
00155     (void * (*)(void)) sha256_NewContext,
00156     (void * (*)(void *)) PK11_CloneContext,
00157     (void (*)(void *, PRBool)) PK11_DestroyContext,
00158     (void (*)(void *)) PK11_DigestBegin,
00159     (void (*)(void *, const unsigned char *, unsigned int)) PK11_DigestOp,
00160     (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) 
00161                                                  PK11_DigestFinal,
00162     SHA256_BLOCK_LENGTH,
00163     HASH_AlgSHA256
00164   },
00165   { SHA384_LENGTH,
00166     (void * (*)(void)) sha384_NewContext,
00167     (void * (*)(void *)) PK11_CloneContext,
00168     (void (*)(void *, PRBool)) PK11_DestroyContext,
00169     (void (*)(void *)) PK11_DigestBegin,
00170     (void (*)(void *, const unsigned char *, unsigned int)) PK11_DigestOp,
00171     (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) 
00172                                                  PK11_DigestFinal,
00173     SHA384_BLOCK_LENGTH,
00174     HASH_AlgSHA384
00175   },
00176   { SHA512_LENGTH,
00177     (void * (*)(void)) sha512_NewContext,
00178     (void * (*)(void *)) PK11_CloneContext,
00179     (void (*)(void *, PRBool)) PK11_DestroyContext,
00180     (void (*)(void *)) PK11_DigestBegin,
00181     (void (*)(void *, const unsigned char *, unsigned int)) PK11_DigestOp,
00182     (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) 
00183                                                  PK11_DigestFinal,
00184     SHA512_BLOCK_LENGTH,
00185     HASH_AlgSHA512
00186   },
00187 };
00188 
00189 const SECHashObject * 
00190 HASH_GetHashObject(HASH_HashType type)
00191 {
00192     return &SECHashObjects[type];
00193 }
00194 
00195 HASH_HashType
00196 HASH_GetHashTypeByOidTag(SECOidTag hashOid)
00197 {
00198     HASH_HashType ht = HASH_AlgNULL;
00199 
00200     switch(hashOid) {
00201     case SEC_OID_MD2:        ht = HASH_AlgMD2;    break;
00202     case SEC_OID_MD5:        ht = HASH_AlgMD5;    break;
00203     case SEC_OID_SHA1:       ht = HASH_AlgSHA1;   break;
00204     case SEC_OID_SHA256: ht = HASH_AlgSHA256; break;
00205     case SEC_OID_SHA384: ht = HASH_AlgSHA384; break;
00206     case SEC_OID_SHA512: ht = HASH_AlgSHA512; break;
00207     default:             ht = HASH_AlgNULL;   
00208        PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
00209        break;
00210     }
00211     return ht;
00212 }
00213 
00214 const SECHashObject * 
00215 HASH_GetHashObjectByOidTag(SECOidTag hashOid)
00216 {
00217     HASH_HashType ht = HASH_GetHashTypeByOidTag(hashOid);
00218 
00219     return (ht == HASH_AlgNULL) ? NULL : &SECHashObjects[ht];
00220 }
00221 
00222 /* returns zero for unknown hash OID */
00223 unsigned int
00224 HASH_ResultLenByOidTag(SECOidTag hashOid)
00225 {
00226     const SECHashObject * hashObject = HASH_GetHashObjectByOidTag(hashOid);
00227     unsigned int          resultLen = 0;
00228 
00229     if (hashObject)
00230        resultLen = hashObject->length;
00231     return resultLen;
00232 }
00233 
00234 /* returns zero if hash type invalid. */
00235 unsigned int
00236 HASH_ResultLen(HASH_HashType type)
00237 {
00238     if ( ( type < HASH_AlgNULL ) || ( type >= HASH_AlgTOTAL ) ) {
00239        PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
00240        return(0);
00241     }
00242     
00243     return(SECHashObjects[type].length);
00244 }
00245 
00246 unsigned int
00247 HASH_ResultLenContext(HASHContext *context)
00248 {
00249     return(context->hashobj->length);
00250 }
00251 
00252 
00253 
00254 SECStatus
00255 HASH_HashBuf(HASH_HashType type,
00256             unsigned char *dest,
00257             unsigned char *src,
00258             uint32 src_len)
00259 {
00260     HASHContext *cx;
00261     unsigned int part;
00262     
00263     if ( ( type < HASH_AlgNULL ) || ( type >= HASH_AlgTOTAL ) ) {
00264        return(SECFailure);
00265     }
00266     
00267     cx = HASH_Create(type);
00268     if ( cx == NULL ) {
00269        return(SECFailure);
00270     }
00271     HASH_Begin(cx);
00272     HASH_Update(cx, src, src_len);
00273     HASH_End(cx, dest, &part, HASH_ResultLenContext(cx));
00274     HASH_Destroy(cx);
00275 
00276     return(SECSuccess);
00277 }
00278 
00279 HASHContext *
00280 HASH_Create(HASH_HashType type)
00281 {
00282     void *hash_context = NULL;
00283     HASHContext *ret = NULL;
00284     
00285     if ( ( type < HASH_AlgNULL ) || ( type >= HASH_AlgTOTAL ) ) {
00286        return(NULL);
00287     }
00288     
00289     hash_context = (* SECHashObjects[type].create)();
00290     if ( hash_context == NULL ) {
00291        goto loser;
00292     }
00293 
00294     ret = (HASHContext *)PORT_Alloc(sizeof(HASHContext));
00295     if ( ret == NULL ) {
00296        goto loser;
00297     }
00298 
00299     ret->hash_context = hash_context;
00300     ret->hashobj = &SECHashObjects[type];
00301     
00302     return(ret);
00303     
00304 loser:
00305     if ( hash_context != NULL ) {
00306        (* SECHashObjects[type].destroy)(hash_context, PR_TRUE);
00307     }
00308     
00309     return(NULL);
00310 }
00311 
00312 
00313 HASHContext *
00314 HASH_Clone(HASHContext *context)
00315 {
00316     void *hash_context = NULL;
00317     HASHContext *ret = NULL;
00318     
00319     hash_context = (* context->hashobj->clone)(context->hash_context);
00320     if ( hash_context == NULL ) {
00321        goto loser;
00322     }
00323 
00324     ret = (HASHContext *)PORT_Alloc(sizeof(HASHContext));
00325     if ( ret == NULL ) {
00326        goto loser;
00327     }
00328 
00329     ret->hash_context = hash_context;
00330     ret->hashobj = context->hashobj;
00331     
00332     return(ret);
00333     
00334 loser:
00335     if ( hash_context != NULL ) {
00336        (* context->hashobj->destroy)(hash_context, PR_TRUE);
00337     }
00338     
00339     return(NULL);
00340 
00341 }
00342 
00343 void
00344 HASH_Destroy(HASHContext *context)
00345 {
00346     (* context->hashobj->destroy)(context->hash_context, PR_TRUE);
00347     PORT_Free(context);
00348     return;
00349 }
00350 
00351 
00352 void
00353 HASH_Begin(HASHContext *context)
00354 {
00355     (* context->hashobj->begin)(context->hash_context);
00356     return;
00357 }
00358 
00359 
00360 void
00361 HASH_Update(HASHContext *context,
00362            const unsigned char *src,
00363            unsigned int len)
00364 {
00365     (* context->hashobj->update)(context->hash_context, src, len);
00366     return;
00367 }
00368 
00369 void
00370 HASH_End(HASHContext *context,
00371         unsigned char *result,
00372         unsigned int *result_len,
00373         unsigned int max_result_len)
00374 {
00375     (* context->hashobj->end)(context->hash_context, result, result_len,
00376                            max_result_len);
00377     return;
00378 }
00379 
00380 
00381