Coverage Report

Created: 2024-11-21 07:03

/src/boringssl/crypto/blake2/blake2.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (c) 2021, Google Inc.
2
 *
3
 * Permission to use, copy, modify, and/or distribute this software for any
4
 * purpose with or without fee is hereby granted, provided that the above
5
 * copyright notice and this permission notice appear in all copies.
6
 *
7
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
15
#include <openssl/blake2.h>
16
17
#include <assert.h>
18
19
#include "../internal.h"
20
21
// https://tools.ietf.org/html/rfc7693#section-2.6
22
static const uint64_t kIV[8] = {
23
    UINT64_C(0x6a09e667f3bcc908), UINT64_C(0xbb67ae8584caa73b),
24
    UINT64_C(0x3c6ef372fe94f82b), UINT64_C(0xa54ff53a5f1d36f1),
25
    UINT64_C(0x510e527fade682d1), UINT64_C(0x9b05688c2b3e6c1f),
26
    UINT64_C(0x1f83d9abfb41bd6b), UINT64_C(0x5be0cd19137e2179),
27
};
28
29
// https://tools.ietf.org/html/rfc7693#section-2.7
30
static const uint8_t kSigma[10 * 16] = {
31
    // clang-format off
32
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
33
    14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3,
34
    11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4,
35
    7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8,
36
    9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13,
37
    2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9,
38
    12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11,
39
    13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10,
40
    6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5,
41
    10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0,
42
    // clang-format on
43
};
44
45
// https://tools.ietf.org/html/rfc7693#section-3.1
46
static void blake2b_mix(uint64_t v[16], int a, int b, int c, int d, uint64_t x,
47
3.94M
                        uint64_t y) {
48
3.94M
  v[a] = v[a] + v[b] + x;
49
3.94M
  v[d] = CRYPTO_rotr_u64(v[d] ^ v[a], 32);
50
3.94M
  v[c] = v[c] + v[d];
51
3.94M
  v[b] = CRYPTO_rotr_u64(v[b] ^ v[c], 24);
52
3.94M
  v[a] = v[a] + v[b] + y;
53
3.94M
  v[d] = CRYPTO_rotr_u64(v[d] ^ v[a], 16);
54
3.94M
  v[c] = v[c] + v[d];
55
3.94M
  v[b] = CRYPTO_rotr_u64(v[b] ^ v[c], 63);
56
3.94M
}
57
58
7.88M
static uint64_t blake2b_load(const uint8_t block[BLAKE2B_CBLOCK], size_t i) {
59
7.88M
  return CRYPTO_load_u64_le(block + 8 * i);
60
7.88M
}
61
62
static void blake2b_transform(BLAKE2B_CTX *b2b,
63
                              const uint8_t block[BLAKE2B_CBLOCK],
64
41.0k
                              size_t num_bytes, int is_final_block) {
65
  // https://tools.ietf.org/html/rfc7693#section-3.2
66
41.0k
  uint64_t v[16];
67
41.0k
  static_assert(sizeof(v) == sizeof(b2b->h) + sizeof(kIV), "");
68
41.0k
  OPENSSL_memcpy(v, b2b->h, sizeof(b2b->h));
69
41.0k
  OPENSSL_memcpy(&v[8], kIV, sizeof(kIV));
70
71
41.0k
  b2b->t_low += num_bytes;
72
41.0k
  if (b2b->t_low < num_bytes) {
73
0
    b2b->t_high++;
74
0
  }
75
41.0k
  v[12] ^= b2b->t_low;
76
41.0k
  v[13] ^= b2b->t_high;
77
78
41.0k
  if (is_final_block) {
79
2.29k
    v[14] = ~v[14];
80
2.29k
  }
81
82
533k
  for (int round = 0; round < 12; round++) {
83
492k
    const uint8_t *const s = &kSigma[16 * (round % 10)];
84
492k
    blake2b_mix(v, 0, 4, 8, 12, blake2b_load(block, s[0]),
85
492k
                blake2b_load(block, s[1]));
86
492k
    blake2b_mix(v, 1, 5, 9, 13, blake2b_load(block, s[2]),
87
492k
                blake2b_load(block, s[3]));
88
492k
    blake2b_mix(v, 2, 6, 10, 14, blake2b_load(block, s[4]),
89
492k
                blake2b_load(block, s[5]));
90
492k
    blake2b_mix(v, 3, 7, 11, 15, blake2b_load(block, s[6]),
91
492k
                blake2b_load(block, s[7]));
92
492k
    blake2b_mix(v, 0, 5, 10, 15, blake2b_load(block, s[8]),
93
492k
                blake2b_load(block, s[9]));
94
492k
    blake2b_mix(v, 1, 6, 11, 12, blake2b_load(block, s[10]),
95
492k
                blake2b_load(block, s[11]));
96
492k
    blake2b_mix(v, 2, 7, 8, 13, blake2b_load(block, s[12]),
97
492k
                blake2b_load(block, s[13]));
98
492k
    blake2b_mix(v, 3, 4, 9, 14, blake2b_load(block, s[14]),
99
492k
                blake2b_load(block, s[15]));
100
492k
  }
101
102
369k
  for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(b2b->h); i++) {
103
328k
    b2b->h[i] ^= v[i];
104
328k
    b2b->h[i] ^= v[i + 8];
105
328k
  }
106
41.0k
}
107
108
100
void BLAKE2B256_Init(BLAKE2B_CTX *b2b) {
109
100
  OPENSSL_memset(b2b, 0, sizeof(BLAKE2B_CTX));
110
111
100
  static_assert(sizeof(kIV) == sizeof(b2b->h), "");
112
100
  OPENSSL_memcpy(&b2b->h, kIV, sizeof(kIV));
113
114
  // https://tools.ietf.org/html/rfc7693#section-2.5
115
100
  b2b->h[0] ^= 0x01010000 | BLAKE2B256_DIGEST_LENGTH;
116
100
}
117
118
9.04k
void BLAKE2B256_Update(BLAKE2B_CTX *b2b, const void *in_data, size_t len) {
119
9.04k
  if (len == 0) {
120
    // Work around a C language bug. See https://crbug.com/1019588.
121
5.03k
    return;
122
5.03k
  }
123
124
4.01k
  const uint8_t *data = in_data;
125
4.01k
  size_t todo = sizeof(b2b->block) - b2b->block_used;
126
4.01k
  if (todo > len) {
127
943
    todo = len;
128
943
  }
129
4.01k
  OPENSSL_memcpy(&b2b->block[b2b->block_used], data, todo);
130
4.01k
  b2b->block_used += todo;
131
4.01k
  data += todo;
132
4.01k
  len -= todo;
133
134
4.01k
  if (!len) {
135
1.01k
    return;
136
1.01k
  }
137
138
  // More input remains therefore we must have filled |b2b->block|.
139
2.99k
  assert(b2b->block_used == BLAKE2B_CBLOCK);
140
2.99k
  blake2b_transform(b2b, b2b->block, BLAKE2B_CBLOCK,
141
2.99k
                    /*is_final_block=*/0);
142
2.99k
  b2b->block_used = 0;
143
144
38.7k
  while (len > BLAKE2B_CBLOCK) {
145
35.7k
    blake2b_transform(b2b, data, BLAKE2B_CBLOCK, /*is_final_block=*/0);
146
35.7k
    data += BLAKE2B_CBLOCK;
147
35.7k
    len -= BLAKE2B_CBLOCK;
148
35.7k
  }
149
150
2.99k
  OPENSSL_memcpy(b2b->block, data, len);
151
2.99k
  b2b->block_used = len;
152
2.99k
}
153
154
2.29k
void BLAKE2B256_Final(uint8_t out[BLAKE2B256_DIGEST_LENGTH], BLAKE2B_CTX *b2b) {
155
2.29k
  OPENSSL_memset(&b2b->block[b2b->block_used], 0,
156
2.29k
                 sizeof(b2b->block) - b2b->block_used);
157
2.29k
  blake2b_transform(b2b, b2b->block, b2b->block_used,
158
2.29k
                    /*is_final_block=*/1);
159
2.29k
  static_assert(BLAKE2B256_DIGEST_LENGTH <= sizeof(b2b->h), "");
160
2.29k
  memcpy(out, b2b->h, BLAKE2B256_DIGEST_LENGTH);
161
2.29k
}
162
163
void BLAKE2B256(const uint8_t *data, size_t len,
164
0
                uint8_t out[BLAKE2B256_DIGEST_LENGTH]) {
165
0
  BLAKE2B_CTX ctx;
166
0
  BLAKE2B256_Init(&ctx);
167
0
  BLAKE2B256_Update(&ctx, data, len);
168
0
  BLAKE2B256_Final(out, &ctx);
169
0
}