Coverage Report

Created: 2024-11-21 07:03

/src/boringssl/crypto/digest_extra/digest_extra.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2
 * All rights reserved.
3
 *
4
 * This package is an SSL implementation written
5
 * by Eric Young (eay@cryptsoft.com).
6
 * The implementation was written so as to conform with Netscapes SSL.
7
 *
8
 * This library is free for commercial and non-commercial use as long as
9
 * the following conditions are aheared to.  The following conditions
10
 * apply to all code found in this distribution, be it the RC4, RSA,
11
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
12
 * included with this distribution is covered by the same copyright terms
13
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14
 *
15
 * Copyright remains Eric Young's, and as such any Copyright notices in
16
 * the code are not to be removed.
17
 * If this package is used in a product, Eric Young should be given attribution
18
 * as the author of the parts of the library used.
19
 * This can be in the form of a textual message at program startup or
20
 * in documentation (online or textual) provided with the package.
21
 *
22
 * Redistribution and use in source and binary forms, with or without
23
 * modification, are permitted provided that the following conditions
24
 * are met:
25
 * 1. Redistributions of source code must retain the copyright
26
 *    notice, this list of conditions and the following disclaimer.
27
 * 2. Redistributions in binary form must reproduce the above copyright
28
 *    notice, this list of conditions and the following disclaimer in the
29
 *    documentation and/or other materials provided with the distribution.
30
 * 3. All advertising materials mentioning features or use of this software
31
 *    must display the following acknowledgement:
32
 *    "This product includes cryptographic software written by
33
 *     Eric Young (eay@cryptsoft.com)"
34
 *    The word 'cryptographic' can be left out if the rouines from the library
35
 *    being used are not cryptographic related :-).
36
 * 4. If you include any Windows specific code (or a derivative thereof) from
37
 *    the apps directory (application code) you must include an acknowledgement:
38
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39
 *
40
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50
 * SUCH DAMAGE.
51
 *
52
 * The licence and distribution terms for any publically available version or
53
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
54
 * copied and put under another distribution licence
55
 * [including the GNU Public Licence.] */
56
57
#include <openssl/digest.h>
58
59
#include <string.h>
60
61
#include <openssl/blake2.h>
62
#include <openssl/bytestring.h>
63
#include <openssl/obj.h>
64
#include <openssl/md4.h>
65
#include <openssl/md5.h>
66
#include <openssl/nid.h>
67
68
#include "../asn1/internal.h"
69
#include "../internal.h"
70
#include "../fipsmodule/digest/internal.h"
71
72
73
struct nid_to_digest {
74
  int nid;
75
  const EVP_MD* (*md_func)(void);
76
  const char *short_name;
77
  const char *long_name;
78
};
79
80
static const struct nid_to_digest nid_to_digest_mapping[] = {
81
    {NID_md4, EVP_md4, SN_md4, LN_md4},
82
    {NID_md5, EVP_md5, SN_md5, LN_md5},
83
    {NID_sha1, EVP_sha1, SN_sha1, LN_sha1},
84
    {NID_sha224, EVP_sha224, SN_sha224, LN_sha224},
85
    {NID_sha256, EVP_sha256, SN_sha256, LN_sha256},
86
    {NID_sha384, EVP_sha384, SN_sha384, LN_sha384},
87
    {NID_sha512, EVP_sha512, SN_sha512, LN_sha512},
88
    {NID_sha512_256, EVP_sha512_256, SN_sha512_256, LN_sha512_256},
89
    {NID_md5_sha1, EVP_md5_sha1, SN_md5_sha1, LN_md5_sha1},
90
    // As a remnant of signing |EVP_MD|s, OpenSSL returned the corresponding
91
    // hash function when given a signature OID. To avoid unintended lax parsing
92
    // of hash OIDs, this is no longer supported for lookup by OID or NID.
93
    // Node.js, however, exposes |EVP_get_digestbyname|'s full behavior to
94
    // consumers so we retain it there.
95
    {NID_undef, EVP_sha1, SN_dsaWithSHA, LN_dsaWithSHA},
96
    {NID_undef, EVP_sha1, SN_dsaWithSHA1, LN_dsaWithSHA1},
97
    {NID_undef, EVP_sha1, SN_ecdsa_with_SHA1, NULL},
98
    {NID_undef, EVP_md5, SN_md5WithRSAEncryption, LN_md5WithRSAEncryption},
99
    {NID_undef, EVP_sha1, SN_sha1WithRSAEncryption, LN_sha1WithRSAEncryption},
100
    {NID_undef, EVP_sha224, SN_sha224WithRSAEncryption,
101
     LN_sha224WithRSAEncryption},
102
    {NID_undef, EVP_sha256, SN_sha256WithRSAEncryption,
103
     LN_sha256WithRSAEncryption},
104
    {NID_undef, EVP_sha384, SN_sha384WithRSAEncryption,
105
     LN_sha384WithRSAEncryption},
106
    {NID_undef, EVP_sha512, SN_sha512WithRSAEncryption,
107
     LN_sha512WithRSAEncryption},
108
};
109
110
0
const EVP_MD* EVP_get_digestbynid(int nid) {
111
0
  if (nid == NID_undef) {
112
    // Skip the |NID_undef| entries in |nid_to_digest_mapping|.
113
0
    return NULL;
114
0
  }
115
116
0
  for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(nid_to_digest_mapping); i++) {
117
0
    if (nid_to_digest_mapping[i].nid == nid) {
118
0
      return nid_to_digest_mapping[i].md_func();
119
0
    }
120
0
  }
121
122
0
  return NULL;
123
0
}
124
125
static const struct {
126
  uint8_t oid[9];
127
  uint8_t oid_len;
128
  int nid;
129
} kMDOIDs[] = {
130
  // 1.2.840.113549.2.4
131
  { {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x04}, 8, NID_md4 },
132
  // 1.2.840.113549.2.5
133
  { {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05}, 8, NID_md5 },
134
  // 1.3.14.3.2.26
135
  { {0x2b, 0x0e, 0x03, 0x02, 0x1a}, 5, NID_sha1 },
136
  // 2.16.840.1.101.3.4.2.1
137
  { {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01}, 9, NID_sha256 },
138
  // 2.16.840.1.101.3.4.2.2
139
  { {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02}, 9, NID_sha384 },
140
  // 2.16.840.1.101.3.4.2.3
141
  { {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03}, 9, NID_sha512 },
142
  // 2.16.840.1.101.3.4.2.4
143
  { {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04}, 9, NID_sha224 },
144
};
145
146
0
static const EVP_MD *cbs_to_md(const CBS *cbs) {
147
0
  for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kMDOIDs); i++) {
148
0
    if (CBS_len(cbs) == kMDOIDs[i].oid_len &&
149
0
        OPENSSL_memcmp(CBS_data(cbs), kMDOIDs[i].oid, kMDOIDs[i].oid_len) ==
150
0
            0) {
151
0
      return EVP_get_digestbynid(kMDOIDs[i].nid);
152
0
    }
153
0
  }
154
155
0
  return NULL;
156
0
}
157
158
0
const EVP_MD *EVP_get_digestbyobj(const ASN1_OBJECT *obj) {
159
  // Handle objects with no corresponding OID. Note we don't use |OBJ_obj2nid|
160
  // here to avoid pulling in the OID table.
161
0
  if (obj->nid != NID_undef) {
162
0
    return EVP_get_digestbynid(obj->nid);
163
0
  }
164
165
0
  CBS cbs;
166
0
  CBS_init(&cbs, OBJ_get0_data(obj), OBJ_length(obj));
167
0
  return cbs_to_md(&cbs);
168
0
}
169
170
0
const EVP_MD *EVP_parse_digest_algorithm(CBS *cbs) {
171
0
  CBS algorithm, oid;
172
0
  if (!CBS_get_asn1(cbs, &algorithm, CBS_ASN1_SEQUENCE) ||
173
0
      !CBS_get_asn1(&algorithm, &oid, CBS_ASN1_OBJECT)) {
174
0
    OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_DECODE_ERROR);
175
0
    return NULL;
176
0
  }
177
178
0
  const EVP_MD *ret = cbs_to_md(&oid);
179
0
  if (ret == NULL) {
180
0
    OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_UNKNOWN_HASH);
181
0
    return NULL;
182
0
  }
183
184
  // The parameters, if present, must be NULL. Historically, whether the NULL
185
  // was included or omitted was not well-specified. When parsing an
186
  // AlgorithmIdentifier, we allow both. (Note this code is not used when
187
  // verifying RSASSA-PKCS1-v1_5 signatures.)
188
0
  if (CBS_len(&algorithm) > 0) {
189
0
    CBS param;
190
0
    if (!CBS_get_asn1(&algorithm, &param, CBS_ASN1_NULL) ||
191
0
        CBS_len(&param) != 0 ||
192
0
        CBS_len(&algorithm) != 0) {
193
0
      OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_DECODE_ERROR);
194
0
      return NULL;
195
0
    }
196
0
  }
197
198
0
  return ret;
199
0
}
200
201
0
int EVP_marshal_digest_algorithm(CBB *cbb, const EVP_MD *md) {
202
0
  CBB algorithm, oid, null;
203
0
  if (!CBB_add_asn1(cbb, &algorithm, CBS_ASN1_SEQUENCE) ||
204
0
      !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT)) {
205
0
    return 0;
206
0
  }
207
208
0
  int found = 0;
209
0
  int nid = EVP_MD_type(md);
210
0
  for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kMDOIDs); i++) {
211
0
    if (nid == kMDOIDs[i].nid) {
212
0
      if (!CBB_add_bytes(&oid, kMDOIDs[i].oid, kMDOIDs[i].oid_len)) {
213
0
        return 0;
214
0
      }
215
0
      found = 1;
216
0
      break;
217
0
    }
218
0
  }
219
220
0
  if (!found) {
221
0
    OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_UNKNOWN_HASH);
222
0
    return 0;
223
0
  }
224
225
  // TODO(crbug.com/boringssl/710): Is this correct? See RFC 4055, section 2.1.
226
0
  if (!CBB_add_asn1(&algorithm, &null, CBS_ASN1_NULL) ||
227
0
      !CBB_flush(cbb)) {
228
0
    return 0;
229
0
  }
230
231
0
  return 1;
232
0
}
233
234
0
const EVP_MD *EVP_get_digestbyname(const char *name) {
235
0
  for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(nid_to_digest_mapping); i++) {
236
0
    const char *short_name = nid_to_digest_mapping[i].short_name;
237
0
    const char *long_name = nid_to_digest_mapping[i].long_name;
238
0
    if ((short_name && strcmp(short_name, name) == 0) ||
239
0
        (long_name && strcmp(long_name, name) == 0)) {
240
0
      return nid_to_digest_mapping[i].md_func();
241
0
    }
242
0
  }
243
244
0
  return NULL;
245
0
}
246
247
100
static void blake2b256_init(EVP_MD_CTX *ctx) { BLAKE2B256_Init(ctx->md_data); }
248
249
9.04k
static void blake2b256_update(EVP_MD_CTX *ctx, const void *data, size_t len) {
250
9.04k
  BLAKE2B256_Update(ctx->md_data, data, len);
251
9.04k
}
252
253
2.29k
static void blake2b256_final(EVP_MD_CTX *ctx, uint8_t *md) {
254
2.29k
  BLAKE2B256_Final(md, ctx->md_data);
255
2.29k
}
256
257
static const EVP_MD evp_md_blake2b256 = {
258
  NID_undef,
259
  BLAKE2B256_DIGEST_LENGTH,
260
  0,
261
  blake2b256_init,
262
  blake2b256_update,
263
  blake2b256_final,
264
  BLAKE2B_CBLOCK,
265
  sizeof(BLAKE2B_CTX),
266
};
267
268
2
const EVP_MD *EVP_blake2b256(void) { return &evp_md_blake2b256; }
269
270
271
576
static void md4_init(EVP_MD_CTX *ctx) {
272
576
  BSSL_CHECK(MD4_Init(ctx->md_data));
273
576
}
274
275
14.8k
static void md4_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
276
14.8k
  BSSL_CHECK(MD4_Update(ctx->md_data, data, count));
277
14.8k
}
278
279
2.97k
static void md4_final(EVP_MD_CTX *ctx, uint8_t *out) {
280
2.97k
  BSSL_CHECK(MD4_Final(out, ctx->md_data));
281
2.97k
}
282
283
static const EVP_MD evp_md_md4 = {
284
  NID_md4,
285
  MD4_DIGEST_LENGTH,
286
  0,
287
  md4_init,
288
  md4_update,
289
  md4_final,
290
  64,
291
  sizeof(MD4_CTX),
292
};
293
294
6
const EVP_MD *EVP_md4(void) { return &evp_md_md4; }
295
296
179
static void md5_init(EVP_MD_CTX *ctx) {
297
179
  BSSL_CHECK(MD5_Init(ctx->md_data));
298
179
}
299
300
10.8k
static void md5_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
301
10.8k
  BSSL_CHECK(MD5_Update(ctx->md_data, data, count));
302
10.8k
}
303
304
3.26k
static void md5_final(EVP_MD_CTX *ctx, uint8_t *out) {
305
3.26k
  BSSL_CHECK(MD5_Final(out, ctx->md_data));
306
3.26k
}
307
308
static const EVP_MD evp_md_md5 = {
309
  NID_md5,
310
  MD5_DIGEST_LENGTH,
311
  0,
312
  md5_init,
313
  md5_update,
314
  md5_final,
315
  64,
316
  sizeof(MD5_CTX),
317
};
318
319
6
const EVP_MD *EVP_md5(void) { return &evp_md_md5; }
320
321
typedef struct {
322
  MD5_CTX md5;
323
  SHA_CTX sha1;
324
} MD5_SHA1_CTX;
325
326
351
static void md5_sha1_init(EVP_MD_CTX *md_ctx) {
327
351
  MD5_SHA1_CTX *ctx = md_ctx->md_data;
328
351
  BSSL_CHECK(MD5_Init(&ctx->md5) && SHA1_Init(&ctx->sha1));
329
351
}
330
331
static void md5_sha1_update(EVP_MD_CTX *md_ctx, const void *data,
332
4.22k
                            size_t count) {
333
4.22k
  MD5_SHA1_CTX *ctx = md_ctx->md_data;
334
4.22k
  BSSL_CHECK(MD5_Update(&ctx->md5, data, count) &&
335
4.22k
        SHA1_Update(&ctx->sha1, data, count));
336
4.22k
}
337
338
1.74k
static void md5_sha1_final(EVP_MD_CTX *md_ctx, uint8_t *out) {
339
1.74k
  MD5_SHA1_CTX *ctx = md_ctx->md_data;
340
1.74k
  BSSL_CHECK(MD5_Final(out, &ctx->md5) &&
341
1.74k
        SHA1_Final(out + MD5_DIGEST_LENGTH, &ctx->sha1));
342
1.74k
}
343
344
const EVP_MD evp_md_md5_sha1 = {
345
  NID_md5_sha1,
346
  MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH,
347
  0,
348
  md5_sha1_init,
349
  md5_sha1_update,
350
  md5_sha1_final,
351
  64,
352
  sizeof(MD5_SHA1_CTX),
353
};
354
355
6
const EVP_MD *EVP_md5_sha1(void) { return &evp_md_md5_sha1; }