tor-browser

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

md2.c (7310B)


      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 
      5 #ifdef FREEBL_NO_DEPEND
      6 #include "stubs.h"
      7 #endif
      8 
      9 #include "prerr.h"
     10 #include "secerr.h"
     11 
     12 #include "prtypes.h"
     13 
     14 #include "blapi.h"
     15 
     16 #define MD2_DIGEST_LEN 16
     17 #define MD2_BUFSIZE 16
     18 #define MD2_X_SIZE 48  /* The X array, [CV | INPUT | TMP VARS] */
     19 #define MD2_CV 0       /* index into X for chaining variables */
     20 #define MD2_INPUT 16   /* index into X for input */
     21 #define MD2_TMPVARS 32 /* index into X for temporary variables */
     22 #define MD2_CHECKSUM_SIZE 16
     23 
     24 struct MD2ContextStr {
     25    unsigned char checksum[MD2_BUFSIZE];
     26    unsigned char X[MD2_X_SIZE];
     27    PRUint8 unusedBuffer;
     28 };
     29 
     30 static const PRUint8 MD2S[256] = {
     31    0051, 0056, 0103, 0311, 0242, 0330, 0174, 0001,
     32    0075, 0066, 0124, 0241, 0354, 0360, 0006, 0023,
     33    0142, 0247, 0005, 0363, 0300, 0307, 0163, 0214,
     34    0230, 0223, 0053, 0331, 0274, 0114, 0202, 0312,
     35    0036, 0233, 0127, 0074, 0375, 0324, 0340, 0026,
     36    0147, 0102, 0157, 0030, 0212, 0027, 0345, 0022,
     37    0276, 0116, 0304, 0326, 0332, 0236, 0336, 0111,
     38    0240, 0373, 0365, 0216, 0273, 0057, 0356, 0172,
     39    0251, 0150, 0171, 0221, 0025, 0262, 0007, 0077,
     40    0224, 0302, 0020, 0211, 0013, 0042, 0137, 0041,
     41    0200, 0177, 0135, 0232, 0132, 0220, 0062, 0047,
     42    0065, 0076, 0314, 0347, 0277, 0367, 0227, 0003,
     43    0377, 0031, 0060, 0263, 0110, 0245, 0265, 0321,
     44    0327, 0136, 0222, 0052, 0254, 0126, 0252, 0306,
     45    0117, 0270, 0070, 0322, 0226, 0244, 0175, 0266,
     46    0166, 0374, 0153, 0342, 0234, 0164, 0004, 0361,
     47    0105, 0235, 0160, 0131, 0144, 0161, 0207, 0040,
     48    0206, 0133, 0317, 0145, 0346, 0055, 0250, 0002,
     49    0033, 0140, 0045, 0255, 0256, 0260, 0271, 0366,
     50    0034, 0106, 0141, 0151, 0064, 0100, 0176, 0017,
     51    0125, 0107, 0243, 0043, 0335, 0121, 0257, 0072,
     52    0303, 0134, 0371, 0316, 0272, 0305, 0352, 0046,
     53    0054, 0123, 0015, 0156, 0205, 0050, 0204, 0011,
     54    0323, 0337, 0315, 0364, 0101, 0201, 0115, 0122,
     55    0152, 0334, 0067, 0310, 0154, 0301, 0253, 0372,
     56    0044, 0341, 0173, 0010, 0014, 0275, 0261, 0112,
     57    0170, 0210, 0225, 0213, 0343, 0143, 0350, 0155,
     58    0351, 0313, 0325, 0376, 0073, 0000, 0035, 0071,
     59    0362, 0357, 0267, 0016, 0146, 0130, 0320, 0344,
     60    0246, 0167, 0162, 0370, 0353, 0165, 0113, 0012,
     61    0061, 0104, 0120, 0264, 0217, 0355, 0037, 0032,
     62    0333, 0231, 0215, 0063, 0237, 0021, 0203, 0024
     63 };
     64 
     65 SECStatus
     66 MD2_Hash(unsigned char *dest, const char *src)
     67 {
     68    unsigned int len;
     69    MD2Context *cx = MD2_NewContext();
     70    if (!cx) {
     71        PORT_SetError(PR_OUT_OF_MEMORY_ERROR);
     72        return SECFailure;
     73    }
     74    MD2_Begin(cx);
     75    MD2_Update(cx, (const unsigned char *)src, PORT_Strlen(src));
     76    MD2_End(cx, dest, &len, MD2_DIGEST_LEN);
     77    MD2_DestroyContext(cx, PR_TRUE);
     78    return SECSuccess;
     79 }
     80 
     81 MD2Context *
     82 MD2_NewContext(void)
     83 {
     84    MD2Context *cx = (MD2Context *)PORT_ZAlloc(sizeof(MD2Context));
     85    if (cx == NULL) {
     86        PORT_SetError(PR_OUT_OF_MEMORY_ERROR);
     87        return NULL;
     88    }
     89    return cx;
     90 }
     91 
     92 void
     93 MD2_DestroyContext(MD2Context *cx, PRBool freeit)
     94 {
     95    if (freeit)
     96        PORT_ZFree(cx, sizeof(*cx));
     97 }
     98 
     99 void
    100 MD2_Begin(MD2Context *cx)
    101 {
    102    memset(cx, 0, sizeof(*cx));
    103    cx->unusedBuffer = MD2_BUFSIZE;
    104 }
    105 
    106 static void
    107 md2_compress(MD2Context *cx)
    108 {
    109    int j;
    110    unsigned char P;
    111    P = cx->checksum[MD2_CHECKSUM_SIZE - 1];
    112 /* Compute the running checksum, and set the tmp variables to be
    113 * CV[i] XOR input[i]
    114 */
    115 #define CKSUMFN(n)                                        \
    116    P = cx->checksum[n] ^ MD2S[cx->X[MD2_INPUT + n] ^ P]; \
    117    cx->checksum[n] = P;                                  \
    118    cx->X[MD2_TMPVARS + n] = cx->X[n] ^ cx->X[MD2_INPUT + n];
    119    CKSUMFN(0);
    120    CKSUMFN(1);
    121    CKSUMFN(2);
    122    CKSUMFN(3);
    123    CKSUMFN(4);
    124    CKSUMFN(5);
    125    CKSUMFN(6);
    126    CKSUMFN(7);
    127    CKSUMFN(8);
    128    CKSUMFN(9);
    129    CKSUMFN(10);
    130    CKSUMFN(11);
    131    CKSUMFN(12);
    132    CKSUMFN(13);
    133    CKSUMFN(14);
    134    CKSUMFN(15);
    135 /* The compression function. */
    136 #define COMPRESS(n)         \
    137    P = cx->X[n] ^ MD2S[P]; \
    138    cx->X[n] = P;
    139    P = 0x00;
    140    for (j = 0; j < 18; j++) {
    141        COMPRESS(0);
    142        COMPRESS(1);
    143        COMPRESS(2);
    144        COMPRESS(3);
    145        COMPRESS(4);
    146        COMPRESS(5);
    147        COMPRESS(6);
    148        COMPRESS(7);
    149        COMPRESS(8);
    150        COMPRESS(9);
    151        COMPRESS(10);
    152        COMPRESS(11);
    153        COMPRESS(12);
    154        COMPRESS(13);
    155        COMPRESS(14);
    156        COMPRESS(15);
    157        COMPRESS(16);
    158        COMPRESS(17);
    159        COMPRESS(18);
    160        COMPRESS(19);
    161        COMPRESS(20);
    162        COMPRESS(21);
    163        COMPRESS(22);
    164        COMPRESS(23);
    165        COMPRESS(24);
    166        COMPRESS(25);
    167        COMPRESS(26);
    168        COMPRESS(27);
    169        COMPRESS(28);
    170        COMPRESS(29);
    171        COMPRESS(30);
    172        COMPRESS(31);
    173        COMPRESS(32);
    174        COMPRESS(33);
    175        COMPRESS(34);
    176        COMPRESS(35);
    177        COMPRESS(36);
    178        COMPRESS(37);
    179        COMPRESS(38);
    180        COMPRESS(39);
    181        COMPRESS(40);
    182        COMPRESS(41);
    183        COMPRESS(42);
    184        COMPRESS(43);
    185        COMPRESS(44);
    186        COMPRESS(45);
    187        COMPRESS(46);
    188        COMPRESS(47);
    189        P = (P + j) % 256;
    190    }
    191    cx->unusedBuffer = MD2_BUFSIZE;
    192 }
    193 
    194 void
    195 MD2_Update(MD2Context *cx, const unsigned char *input, unsigned int inputLen)
    196 {
    197    PRUint32 bytesToConsume;
    198 
    199    /* Fill the remaining input buffer. */
    200    if (cx->unusedBuffer != MD2_BUFSIZE) {
    201        bytesToConsume = PR_MIN(inputLen, cx->unusedBuffer);
    202        memcpy(&cx->X[MD2_INPUT + (MD2_BUFSIZE - cx->unusedBuffer)],
    203               input, bytesToConsume);
    204        if (cx->unusedBuffer + bytesToConsume >= MD2_BUFSIZE)
    205            md2_compress(cx);
    206        inputLen -= bytesToConsume;
    207        input += bytesToConsume;
    208    }
    209 
    210    /* Iterate over 16-byte chunks of the input. */
    211    while (inputLen >= MD2_BUFSIZE) {
    212        memcpy(&cx->X[MD2_INPUT], input, MD2_BUFSIZE);
    213        md2_compress(cx);
    214        inputLen -= MD2_BUFSIZE;
    215        input += MD2_BUFSIZE;
    216    }
    217 
    218    /* Copy any input that remains into the buffer. */
    219    if (inputLen)
    220        memcpy(&cx->X[MD2_INPUT], input, inputLen);
    221    cx->unusedBuffer = MD2_BUFSIZE - inputLen;
    222 }
    223 
    224 void
    225 MD2_End(MD2Context *cx, unsigned char *digest,
    226        unsigned int *digestLen, unsigned int maxDigestLen)
    227 {
    228    PRUint8 padStart;
    229    if (maxDigestLen < MD2_BUFSIZE) {
    230        PORT_SetError(SEC_ERROR_INVALID_ARGS);
    231        return;
    232    }
    233    padStart = MD2_BUFSIZE - cx->unusedBuffer;
    234    memset(&cx->X[MD2_INPUT + padStart], cx->unusedBuffer,
    235           cx->unusedBuffer);
    236    md2_compress(cx);
    237    memcpy(&cx->X[MD2_INPUT], cx->checksum, MD2_BUFSIZE);
    238    md2_compress(cx);
    239    *digestLen = MD2_DIGEST_LEN;
    240    memcpy(digest, &cx->X[MD2_CV], MD2_DIGEST_LEN);
    241 }
    242 
    243 unsigned int
    244 MD2_FlattenSize(MD2Context *cx)
    245 {
    246    return sizeof(*cx);
    247 }
    248 
    249 SECStatus
    250 MD2_Flatten(MD2Context *cx, unsigned char *space)
    251 {
    252    memcpy(space, cx, sizeof(*cx));
    253    return SECSuccess;
    254 }
    255 
    256 MD2Context *
    257 MD2_Resurrect(unsigned char *space, void *arg)
    258 {
    259    MD2Context *cx = MD2_NewContext();
    260    if (cx)
    261        memcpy(cx, space, sizeof(*cx));
    262    return cx;
    263 }
    264 
    265 void
    266 MD2_Clone(MD2Context *dest, MD2Context *src)
    267 {
    268    memcpy(dest, src, sizeof *dest);
    269 }