security/nss/lib/cryptohi/sechash.c

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

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

mercurial