sechash.c (9544B)
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 { 13 return NULL; 14 } 15 16 static void * 17 null_hash_clone_context(void *v) 18 { 19 PORT_Assert(v == NULL); 20 return NULL; 21 } 22 23 static void 24 null_hash_begin(void *v) 25 { 26 } 27 28 static void 29 null_hash_update(void *v, const unsigned char *input, unsigned int length) 30 { 31 } 32 33 static void 34 null_hash_end(void *v, unsigned char *output, unsigned int *outLen, 35 unsigned int maxOut) 36 { 37 *outLen = 0; 38 } 39 40 static void 41 null_hash_destroy_context(void *v, PRBool b) 42 { 43 PORT_Assert(v == NULL); 44 } 45 46 static void * 47 md2_NewContext(void) 48 { 49 return (void *)PK11_CreateDigestContext(SEC_OID_MD2); 50 } 51 52 static void * 53 md5_NewContext(void) 54 { 55 return (void *)PK11_CreateDigestContext(SEC_OID_MD5); 56 } 57 58 static void * 59 sha1_NewContext(void) 60 { 61 return (void *)PK11_CreateDigestContext(SEC_OID_SHA1); 62 } 63 64 static void * 65 sha224_NewContext(void) 66 { 67 return (void *)PK11_CreateDigestContext(SEC_OID_SHA224); 68 } 69 70 static void * 71 sha256_NewContext(void) 72 { 73 return (void *)PK11_CreateDigestContext(SEC_OID_SHA256); 74 } 75 76 static void * 77 sha384_NewContext(void) 78 { 79 return (void *)PK11_CreateDigestContext(SEC_OID_SHA384); 80 } 81 82 static void * 83 sha512_NewContext(void) 84 { 85 return (void *)PK11_CreateDigestContext(SEC_OID_SHA512); 86 } 87 88 static void * 89 sha3_224_NewContext(void) 90 { 91 return (void *)PK11_CreateDigestContext(SEC_OID_SHA3_224); 92 } 93 94 static void * 95 sha3_256_NewContext(void) 96 { 97 return (void *)PK11_CreateDigestContext(SEC_OID_SHA3_256); 98 } 99 100 static void * 101 sha3_384_NewContext(void) 102 { 103 return (void *)PK11_CreateDigestContext(SEC_OID_SHA3_384); 104 } 105 106 static void * 107 sha3_512_NewContext(void) 108 { 109 return (void *)PK11_CreateDigestContext(SEC_OID_SHA3_512); 110 } 111 112 static void * 113 SECHash_PK11_CloneContext(void *ctx) 114 { 115 PK11Context *pctx = ctx; 116 return PK11_CloneContext(pctx); 117 } 118 119 static void 120 SECHash_PK11_DestroyContext(void *ctx, PRBool freeit) 121 { 122 PK11Context *pctx = ctx; 123 PK11_DestroyContext(pctx, freeit); 124 } 125 126 void 127 SECHash_PK11_DigestBegin(void *ctx) 128 { 129 PK11Context *pctx = ctx; 130 SECStatus rv = PK11_DigestBegin(pctx); 131 PORT_Assert(rv == SECSuccess); 132 (void)rv; 133 } 134 135 void 136 SECHash_PK11_DigestOp(void *ctx, const unsigned char *in, unsigned inLen) 137 { 138 PK11Context *pctx = ctx; 139 SECStatus rv = PK11_DigestOp(pctx, in, inLen); 140 PORT_Assert(rv == SECSuccess); 141 (void)rv; 142 } 143 144 void 145 SECHash_PK11_DigestFinal(void *ctx, unsigned char *data, 146 unsigned int *outLen, unsigned int length) 147 { 148 PK11Context *pctx = ctx; 149 SECStatus rv = PK11_DigestFinal(pctx, data, outLen, length); 150 PORT_Assert(rv == SECSuccess); 151 (void)rv; 152 } 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 { 268 return &SECHashObjects[type]; 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 SECStatus 310 HASH_HashBuf(HASH_HashType type, 311 unsigned char *dest, 312 const unsigned char *src, 313 PRUint32 src_len) 314 { 315 HASHContext *cx; 316 unsigned int part; 317 318 if ((type < HASH_AlgNULL) || (type >= HASH_AlgTOTAL)) { 319 return (SECFailure); 320 } 321 322 cx = HASH_Create(type); 323 if (cx == NULL) { 324 return (SECFailure); 325 } 326 HASH_Begin(cx); 327 HASH_Update(cx, src, src_len); 328 HASH_End(cx, dest, &part, HASH_ResultLenContext(cx)); 329 HASH_Destroy(cx); 330 331 return (SECSuccess); 332 } 333 334 HASHContext * 335 HASH_Create(HASH_HashType type) 336 { 337 void *hash_context = NULL; 338 HASHContext *ret = NULL; 339 340 if ((type < HASH_AlgNULL) || (type >= HASH_AlgTOTAL)) { 341 return (NULL); 342 } 343 344 hash_context = (*SECHashObjects[type].create)(); 345 if (hash_context == NULL) { 346 goto loser; 347 } 348 349 ret = (HASHContext *)PORT_Alloc(sizeof(HASHContext)); 350 if (ret == NULL) { 351 goto loser; 352 } 353 354 ret->hash_context = hash_context; 355 ret->hashobj = &SECHashObjects[type]; 356 357 return (ret); 358 359 loser: 360 if (hash_context != NULL) { 361 (*SECHashObjects[type].destroy)(hash_context, PR_TRUE); 362 } 363 364 return (NULL); 365 } 366 367 HASHContext * 368 HASH_Clone(HASHContext *context) 369 { 370 void *hash_context = NULL; 371 HASHContext *ret = NULL; 372 373 hash_context = (*context->hashobj->clone)(context->hash_context); 374 if (hash_context == NULL) { 375 goto loser; 376 } 377 378 ret = (HASHContext *)PORT_Alloc(sizeof(HASHContext)); 379 if (ret == NULL) { 380 goto loser; 381 } 382 383 ret->hash_context = hash_context; 384 ret->hashobj = context->hashobj; 385 386 return (ret); 387 388 loser: 389 if (hash_context != NULL) { 390 (*context->hashobj->destroy)(hash_context, PR_TRUE); 391 } 392 393 return (NULL); 394 } 395 396 void 397 HASH_Destroy(HASHContext *context) 398 { 399 (*context->hashobj->destroy)(context->hash_context, PR_TRUE); 400 PORT_Free(context); 401 return; 402 } 403 404 void 405 HASH_Begin(HASHContext *context) 406 { 407 (*context->hashobj->begin)(context->hash_context); 408 return; 409 } 410 411 void 412 HASH_Update(HASHContext *context, 413 const unsigned char *src, 414 unsigned int len) 415 { 416 (*context->hashobj->update)(context->hash_context, src, len); 417 return; 418 } 419 420 void 421 HASH_End(HASHContext *context, 422 unsigned char *result, 423 unsigned int *result_len, 424 unsigned int max_result_len) 425 { 426 (*context->hashobj->end)(context->hash_context, result, result_len, 427 max_result_len); 428 return; 429 } 430 431 HASH_HashType 432 HASH_GetType(HASHContext *context) 433 { 434 return (context->hashobj->type); 435 }