tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 }