security/nss/lib/cryptohi/sechash.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/security/nss/lib/cryptohi/sechash.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,409 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +#include "sechash.h"
     1.8 +#include "secoidt.h"
     1.9 +#include "secerr.h"
    1.10 +#include "blapi.h"
    1.11 +#include "pk11func.h"	/* for the PK11_ calls below. */
    1.12 +
    1.13 +static void *
    1.14 +null_hash_new_context(void)
    1.15 +{
    1.16 +    return NULL;
    1.17 +}
    1.18 +
    1.19 +static void *
    1.20 +null_hash_clone_context(void *v)
    1.21 +{
    1.22 +    PORT_Assert(v == NULL);
    1.23 +    return NULL;
    1.24 +}
    1.25 +
    1.26 +static void
    1.27 +null_hash_begin(void *v)
    1.28 +{
    1.29 +}
    1.30 +
    1.31 +static void
    1.32 +null_hash_update(void *v, const unsigned char *input, unsigned int length)
    1.33 +{
    1.34 +}
    1.35 +
    1.36 +static void
    1.37 +null_hash_end(void *v, unsigned char *output, unsigned int *outLen,
    1.38 +	      unsigned int maxOut)
    1.39 +{
    1.40 +    *outLen = 0;
    1.41 +}
    1.42 +
    1.43 +static void
    1.44 +null_hash_destroy_context(void *v, PRBool b)
    1.45 +{
    1.46 +    PORT_Assert(v == NULL);
    1.47 +}
    1.48 +
    1.49 +
    1.50 +static void *
    1.51 +md2_NewContext(void) {
    1.52 +	return (void *) PK11_CreateDigestContext(SEC_OID_MD2);
    1.53 +}
    1.54 +
    1.55 +static void *
    1.56 +md5_NewContext(void) {
    1.57 +	return (void *) PK11_CreateDigestContext(SEC_OID_MD5);
    1.58 +}
    1.59 +
    1.60 +static void *
    1.61 +sha1_NewContext(void) {
    1.62 +	return (void *) PK11_CreateDigestContext(SEC_OID_SHA1);
    1.63 +}
    1.64 +
    1.65 +static void *
    1.66 +sha224_NewContext(void) {
    1.67 +	return (void *) PK11_CreateDigestContext(SEC_OID_SHA224);
    1.68 +}
    1.69 +
    1.70 +static void *
    1.71 +sha256_NewContext(void) {
    1.72 +	return (void *) PK11_CreateDigestContext(SEC_OID_SHA256);
    1.73 +}
    1.74 +
    1.75 +static void *
    1.76 +sha384_NewContext(void) {
    1.77 +	return (void *) PK11_CreateDigestContext(SEC_OID_SHA384);
    1.78 +}
    1.79 +
    1.80 +static void *
    1.81 +sha512_NewContext(void) {
    1.82 +	return (void *) PK11_CreateDigestContext(SEC_OID_SHA512);
    1.83 +}
    1.84 +
    1.85 +const SECHashObject SECHashObjects[] = {
    1.86 +  { 0,
    1.87 +    (void * (*)(void)) null_hash_new_context,
    1.88 +    (void * (*)(void *)) null_hash_clone_context,
    1.89 +    (void (*)(void *, PRBool)) null_hash_destroy_context,
    1.90 +    (void (*)(void *)) null_hash_begin,
    1.91 +    (void (*)(void *, const unsigned char *, unsigned int)) null_hash_update,
    1.92 +    (void (*)(void *, unsigned char *, unsigned int *,
    1.93 +	      unsigned int)) null_hash_end,
    1.94 +    0,
    1.95 +    HASH_AlgNULL
    1.96 +  },
    1.97 +  { MD2_LENGTH,
    1.98 +    (void * (*)(void)) md2_NewContext,
    1.99 +    (void * (*)(void *)) PK11_CloneContext,
   1.100 +    (void (*)(void *, PRBool)) PK11_DestroyContext,
   1.101 +    (void (*)(void *)) PK11_DigestBegin,
   1.102 +    (void (*)(void *, const unsigned char *, unsigned int)) PK11_DigestOp,
   1.103 +    (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) 
   1.104 +							PK11_DigestFinal,
   1.105 +    MD2_BLOCK_LENGTH,
   1.106 +    HASH_AlgMD2
   1.107 +  },
   1.108 +  { MD5_LENGTH,
   1.109 +    (void * (*)(void)) md5_NewContext,
   1.110 +    (void * (*)(void *)) PK11_CloneContext,
   1.111 +    (void (*)(void *, PRBool)) PK11_DestroyContext,
   1.112 +    (void (*)(void *)) PK11_DigestBegin,
   1.113 +    (void (*)(void *, const unsigned char *, unsigned int)) PK11_DigestOp,
   1.114 +    (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) 
   1.115 +							PK11_DigestFinal,
   1.116 +    MD5_BLOCK_LENGTH,
   1.117 +    HASH_AlgMD5
   1.118 +  },
   1.119 +  { SHA1_LENGTH,
   1.120 +    (void * (*)(void)) sha1_NewContext,
   1.121 +    (void * (*)(void *)) PK11_CloneContext,
   1.122 +    (void (*)(void *, PRBool)) PK11_DestroyContext,
   1.123 +    (void (*)(void *)) PK11_DigestBegin,
   1.124 +    (void (*)(void *, const unsigned char *, unsigned int)) PK11_DigestOp,
   1.125 +    (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) 
   1.126 +							PK11_DigestFinal,
   1.127 +    SHA1_BLOCK_LENGTH,
   1.128 +    HASH_AlgSHA1
   1.129 +  },
   1.130 +  { SHA256_LENGTH,
   1.131 +    (void * (*)(void)) sha256_NewContext,
   1.132 +    (void * (*)(void *)) PK11_CloneContext,
   1.133 +    (void (*)(void *, PRBool)) PK11_DestroyContext,
   1.134 +    (void (*)(void *)) PK11_DigestBegin,
   1.135 +    (void (*)(void *, const unsigned char *, unsigned int)) PK11_DigestOp,
   1.136 +    (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) 
   1.137 +							PK11_DigestFinal,
   1.138 +    SHA256_BLOCK_LENGTH,
   1.139 +    HASH_AlgSHA256
   1.140 +  },
   1.141 +  { SHA384_LENGTH,
   1.142 +    (void * (*)(void)) sha384_NewContext,
   1.143 +    (void * (*)(void *)) PK11_CloneContext,
   1.144 +    (void (*)(void *, PRBool)) PK11_DestroyContext,
   1.145 +    (void (*)(void *)) PK11_DigestBegin,
   1.146 +    (void (*)(void *, const unsigned char *, unsigned int)) PK11_DigestOp,
   1.147 +    (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) 
   1.148 +							PK11_DigestFinal,
   1.149 +    SHA384_BLOCK_LENGTH,
   1.150 +    HASH_AlgSHA384
   1.151 +  },
   1.152 +  { SHA512_LENGTH,
   1.153 +    (void * (*)(void)) sha512_NewContext,
   1.154 +    (void * (*)(void *)) PK11_CloneContext,
   1.155 +    (void (*)(void *, PRBool)) PK11_DestroyContext,
   1.156 +    (void (*)(void *)) PK11_DigestBegin,
   1.157 +    (void (*)(void *, const unsigned char *, unsigned int)) PK11_DigestOp,
   1.158 +    (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) 
   1.159 +							PK11_DigestFinal,
   1.160 +    SHA512_BLOCK_LENGTH,
   1.161 +    HASH_AlgSHA512
   1.162 +  },
   1.163 +  { SHA224_LENGTH,
   1.164 +    (void * (*)(void)) sha224_NewContext,
   1.165 +    (void * (*)(void *)) PK11_CloneContext,
   1.166 +    (void (*)(void *, PRBool)) PK11_DestroyContext,
   1.167 +    (void (*)(void *)) PK11_DigestBegin,
   1.168 +    (void (*)(void *, const unsigned char *, unsigned int)) PK11_DigestOp,
   1.169 +    (void (*)(void *, unsigned char *, unsigned int *, unsigned int))
   1.170 +							PK11_DigestFinal,
   1.171 +    SHA224_BLOCK_LENGTH,
   1.172 +    HASH_AlgSHA224
   1.173 +  },
   1.174 +};
   1.175 +
   1.176 +const SECHashObject * 
   1.177 +HASH_GetHashObject(HASH_HashType type)
   1.178 +{
   1.179 +    return &SECHashObjects[type];
   1.180 +}
   1.181 +
   1.182 +HASH_HashType
   1.183 +HASH_GetHashTypeByOidTag(SECOidTag hashOid)
   1.184 +{
   1.185 +    HASH_HashType ht	= HASH_AlgNULL;
   1.186 +
   1.187 +    switch(hashOid) {
   1.188 +    case SEC_OID_MD2:	 ht = HASH_AlgMD2;    break;
   1.189 +    case SEC_OID_MD5:	 ht = HASH_AlgMD5;    break;
   1.190 +    case SEC_OID_SHA1:	 ht = HASH_AlgSHA1;   break;
   1.191 +    case SEC_OID_SHA224: ht = HASH_AlgSHA224; break;
   1.192 +    case SEC_OID_SHA256: ht = HASH_AlgSHA256; break;
   1.193 +    case SEC_OID_SHA384: ht = HASH_AlgSHA384; break;
   1.194 +    case SEC_OID_SHA512: ht = HASH_AlgSHA512; break;
   1.195 +    default:             ht = HASH_AlgNULL;   
   1.196 +	PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
   1.197 +	break;
   1.198 +    }
   1.199 +    return ht;
   1.200 +}
   1.201 +
   1.202 +SECOidTag
   1.203 +HASH_GetHashOidTagByHMACOidTag(SECOidTag hmacOid)
   1.204 +{
   1.205 +    SECOidTag hashOid = SEC_OID_UNKNOWN;
   1.206 +
   1.207 +    switch(hmacOid) {
   1.208 +    /* no oid exists for HMAC_MD2 */
   1.209 +    /* NSS does not define a oid for HMAC_MD4 */
   1.210 +    case SEC_OID_HMAC_SHA1:   hashOid = SEC_OID_SHA1;   break;
   1.211 +    case SEC_OID_HMAC_SHA224: hashOid = SEC_OID_SHA224; break;
   1.212 +    case SEC_OID_HMAC_SHA256: hashOid = SEC_OID_SHA256; break;
   1.213 +    case SEC_OID_HMAC_SHA384: hashOid = SEC_OID_SHA384; break;
   1.214 +    case SEC_OID_HMAC_SHA512: hashOid = SEC_OID_SHA512; break;
   1.215 +    default:                  hashOid = SEC_OID_UNKNOWN;   
   1.216 +	PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
   1.217 +	break;
   1.218 +    }
   1.219 +    return hashOid;
   1.220 +}
   1.221 +
   1.222 +SECOidTag
   1.223 +HASH_GetHMACOidTagByHashOidTag(SECOidTag hashOid)
   1.224 +{
   1.225 +    SECOidTag hmacOid = SEC_OID_UNKNOWN;
   1.226 +
   1.227 +    switch(hashOid) {
   1.228 +    /* no oid exists for HMAC_MD2 */
   1.229 +    /* NSS does not define a oid for HMAC_MD4 */
   1.230 +    case SEC_OID_SHA1:   hmacOid = SEC_OID_HMAC_SHA1;   break;
   1.231 +    case SEC_OID_SHA224: hmacOid = SEC_OID_HMAC_SHA224; break;
   1.232 +    case SEC_OID_SHA256: hmacOid = SEC_OID_HMAC_SHA256; break;
   1.233 +    case SEC_OID_SHA384: hmacOid = SEC_OID_HMAC_SHA384; break;
   1.234 +    case SEC_OID_SHA512: hmacOid = SEC_OID_HMAC_SHA512; break;
   1.235 +    default:             hmacOid = SEC_OID_UNKNOWN;   
   1.236 +	PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
   1.237 +	break;
   1.238 +    }
   1.239 +    return hmacOid;
   1.240 +}
   1.241 +
   1.242 +const SECHashObject * 
   1.243 +HASH_GetHashObjectByOidTag(SECOidTag hashOid)
   1.244 +{
   1.245 +    HASH_HashType ht	= HASH_GetHashTypeByOidTag(hashOid);
   1.246 +
   1.247 +    return (ht == HASH_AlgNULL) ? NULL : &SECHashObjects[ht];
   1.248 +}
   1.249 +
   1.250 +/* returns zero for unknown hash OID */
   1.251 +unsigned int
   1.252 +HASH_ResultLenByOidTag(SECOidTag hashOid)
   1.253 +{
   1.254 +    const SECHashObject * hashObject = HASH_GetHashObjectByOidTag(hashOid);
   1.255 +    unsigned int          resultLen = 0;
   1.256 +
   1.257 +    if (hashObject)
   1.258 +    	resultLen = hashObject->length;
   1.259 +    return resultLen;
   1.260 +}
   1.261 +
   1.262 +/* returns zero if hash type invalid. */
   1.263 +unsigned int
   1.264 +HASH_ResultLen(HASH_HashType type)
   1.265 +{
   1.266 +    if ( ( type < HASH_AlgNULL ) || ( type >= HASH_AlgTOTAL ) ) {
   1.267 +	PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
   1.268 +	return(0);
   1.269 +    }
   1.270 +    
   1.271 +    return(SECHashObjects[type].length);
   1.272 +}
   1.273 +
   1.274 +unsigned int
   1.275 +HASH_ResultLenContext(HASHContext *context)
   1.276 +{
   1.277 +    return(context->hashobj->length);
   1.278 +}
   1.279 +
   1.280 +
   1.281 +
   1.282 +SECStatus
   1.283 +HASH_HashBuf(HASH_HashType type,
   1.284 +	     unsigned char *dest,
   1.285 +	     const unsigned char *src,
   1.286 +	     PRUint32 src_len)
   1.287 +{
   1.288 +    HASHContext *cx;
   1.289 +    unsigned int part;
   1.290 +    
   1.291 +    if ( ( type < HASH_AlgNULL ) || ( type >= HASH_AlgTOTAL ) ) {
   1.292 +	return(SECFailure);
   1.293 +    }
   1.294 +    
   1.295 +    cx = HASH_Create(type);
   1.296 +    if ( cx == NULL ) {
   1.297 +	return(SECFailure);
   1.298 +    }
   1.299 +    HASH_Begin(cx);
   1.300 +    HASH_Update(cx, src, src_len);
   1.301 +    HASH_End(cx, dest, &part, HASH_ResultLenContext(cx));
   1.302 +    HASH_Destroy(cx);
   1.303 +
   1.304 +    return(SECSuccess);
   1.305 +}
   1.306 +
   1.307 +HASHContext *
   1.308 +HASH_Create(HASH_HashType type)
   1.309 +{
   1.310 +    void *hash_context = NULL;
   1.311 +    HASHContext *ret = NULL;
   1.312 +    
   1.313 +    if ( ( type < HASH_AlgNULL ) || ( type >= HASH_AlgTOTAL ) ) {
   1.314 +	return(NULL);
   1.315 +    }
   1.316 +    
   1.317 +    hash_context = (* SECHashObjects[type].create)();
   1.318 +    if ( hash_context == NULL ) {
   1.319 +	goto loser;
   1.320 +    }
   1.321 +
   1.322 +    ret = (HASHContext *)PORT_Alloc(sizeof(HASHContext));
   1.323 +    if ( ret == NULL ) {
   1.324 +	goto loser;
   1.325 +    }
   1.326 +
   1.327 +    ret->hash_context = hash_context;
   1.328 +    ret->hashobj = &SECHashObjects[type];
   1.329 +    
   1.330 +    return(ret);
   1.331 +    
   1.332 +loser:
   1.333 +    if ( hash_context != NULL ) {
   1.334 +	(* SECHashObjects[type].destroy)(hash_context, PR_TRUE);
   1.335 +    }
   1.336 +    
   1.337 +    return(NULL);
   1.338 +}
   1.339 +
   1.340 +
   1.341 +HASHContext *
   1.342 +HASH_Clone(HASHContext *context)
   1.343 +{
   1.344 +    void *hash_context = NULL;
   1.345 +    HASHContext *ret = NULL;
   1.346 +    
   1.347 +    hash_context = (* context->hashobj->clone)(context->hash_context);
   1.348 +    if ( hash_context == NULL ) {
   1.349 +	goto loser;
   1.350 +    }
   1.351 +
   1.352 +    ret = (HASHContext *)PORT_Alloc(sizeof(HASHContext));
   1.353 +    if ( ret == NULL ) {
   1.354 +	goto loser;
   1.355 +    }
   1.356 +
   1.357 +    ret->hash_context = hash_context;
   1.358 +    ret->hashobj = context->hashobj;
   1.359 +    
   1.360 +    return(ret);
   1.361 +    
   1.362 +loser:
   1.363 +    if ( hash_context != NULL ) {
   1.364 +	(* context->hashobj->destroy)(hash_context, PR_TRUE);
   1.365 +    }
   1.366 +    
   1.367 +    return(NULL);
   1.368 +
   1.369 +}
   1.370 +
   1.371 +void
   1.372 +HASH_Destroy(HASHContext *context)
   1.373 +{
   1.374 +    (* context->hashobj->destroy)(context->hash_context, PR_TRUE);
   1.375 +    PORT_Free(context);
   1.376 +    return;
   1.377 +}
   1.378 +
   1.379 +
   1.380 +void
   1.381 +HASH_Begin(HASHContext *context)
   1.382 +{
   1.383 +    (* context->hashobj->begin)(context->hash_context);
   1.384 +    return;
   1.385 +}
   1.386 +
   1.387 +
   1.388 +void
   1.389 +HASH_Update(HASHContext *context,
   1.390 +	    const unsigned char *src,
   1.391 +	    unsigned int len)
   1.392 +{
   1.393 +    (* context->hashobj->update)(context->hash_context, src, len);
   1.394 +    return;
   1.395 +}
   1.396 +
   1.397 +void
   1.398 +HASH_End(HASHContext *context,
   1.399 +	 unsigned char *result,
   1.400 +	 unsigned int *result_len,
   1.401 +	 unsigned int max_result_len)
   1.402 +{
   1.403 +    (* context->hashobj->end)(context->hash_context, result, result_len,
   1.404 +			      max_result_len);
   1.405 +    return;
   1.406 +}
   1.407 +
   1.408 +HASH_HashType
   1.409 +HASH_GetType(HASHContext *context)
   1.410 +{
   1.411 +    return(context->hashobj->type);
   1.412 +}

mercurial