Coverage Report

Created: 2024-11-21 07:03

/src/trezor-firmware/crypto/pbkdf2.c
Line
Count
Source (jump to first uncovered line)
1
/**
2
 * Copyright (c) 2013-2014 Tomas Dzetkulic
3
 * Copyright (c) 2013-2014 Pavol Rusnak
4
 *
5
 * Permission is hereby granted, free of charge, to any person obtaining
6
 * a copy of this software and associated documentation files (the "Software"),
7
 * to deal in the Software without restriction, including without limitation
8
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9
 * and/or sell copies of the Software, and to permit persons to whom the
10
 * Software is furnished to do so, subject to the following conditions:
11
 *
12
 * The above copyright notice and this permission notice shall be included
13
 * in all copies or substantial portions of the Software.
14
 *
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
19
 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21
 * OTHER DEALINGS IN THE SOFTWARE.
22
 */
23
24
#include "pbkdf2.h"
25
#include <string.h>
26
#include "hmac.h"
27
#include "memzero.h"
28
#include "sha2.h"
29
30
void pbkdf2_hmac_sha256_Init(PBKDF2_HMAC_SHA256_CTX *pctx, const uint8_t *pass,
31
                             int passlen, const uint8_t *salt, int saltlen,
32
1.01k
                             uint32_t blocknr) {
33
1.01k
  SHA256_CTX ctx = {0};
34
1.01k
#if BYTE_ORDER == LITTLE_ENDIAN
35
1.01k
  REVERSE32(blocknr, blocknr);
36
1.01k
#endif
37
38
1.01k
  hmac_sha256_prepare(pass, passlen, pctx->odig, pctx->idig);
39
1.01k
  memzero(pctx->g, sizeof(pctx->g));
40
1.01k
  pctx->g[8] = 0x80000000;
41
1.01k
  pctx->g[15] = (SHA256_BLOCK_LENGTH + SHA256_DIGEST_LENGTH) * 8;
42
43
1.01k
  memcpy(ctx.state, pctx->idig, sizeof(pctx->idig));
44
1.01k
  ctx.bitcount = SHA256_BLOCK_LENGTH * 8;
45
1.01k
  sha256_Update(&ctx, salt, saltlen);
46
1.01k
  sha256_Update(&ctx, (uint8_t *)&blocknr, sizeof(blocknr));
47
1.01k
  sha256_Final(&ctx, (uint8_t *)pctx->g);
48
1.01k
#if BYTE_ORDER == LITTLE_ENDIAN
49
9.12k
  for (uint32_t k = 0; k < SHA256_DIGEST_LENGTH / sizeof(uint32_t); k++) {
50
8.11k
    REVERSE32(pctx->g[k], pctx->g[k]);
51
8.11k
  }
52
1.01k
#endif
53
1.01k
  sha256_Transform(pctx->odig, pctx->g, pctx->g);
54
1.01k
  memcpy(pctx->f, pctx->g, SHA256_DIGEST_LENGTH);
55
1.01k
  pctx->first = 1;
56
1.01k
}
57
58
void pbkdf2_hmac_sha256_Update(PBKDF2_HMAC_SHA256_CTX *pctx,
59
1.01k
                               uint32_t iterations) {
60
2.24k
  for (uint32_t i = pctx->first; i < iterations; i++) {
61
1.23k
    sha256_Transform(pctx->idig, pctx->g, pctx->g);
62
1.23k
    sha256_Transform(pctx->odig, pctx->g, pctx->g);
63
11.0k
    for (uint32_t j = 0; j < SHA256_DIGEST_LENGTH / sizeof(uint32_t); j++) {
64
9.86k
      pctx->f[j] ^= pctx->g[j];
65
9.86k
    }
66
1.23k
  }
67
1.01k
  pctx->first = 0;
68
1.01k
}
69
70
1.01k
void pbkdf2_hmac_sha256_Final(PBKDF2_HMAC_SHA256_CTX *pctx, uint8_t *key) {
71
1.01k
#if BYTE_ORDER == LITTLE_ENDIAN
72
9.12k
  for (uint32_t k = 0; k < SHA256_DIGEST_LENGTH / sizeof(uint32_t); k++) {
73
8.11k
    REVERSE32(pctx->f[k], pctx->f[k]);
74
8.11k
  }
75
1.01k
#endif
76
1.01k
  memcpy(key, pctx->f, SHA256_DIGEST_LENGTH);
77
1.01k
  memzero(pctx, sizeof(PBKDF2_HMAC_SHA256_CTX));
78
1.01k
}
79
80
void pbkdf2_hmac_sha256(const uint8_t *pass, int passlen, const uint8_t *salt,
81
                        int saltlen, uint32_t iterations, uint8_t *key,
82
73
                        int keylen) {
83
73
  uint32_t last_block_size = keylen % SHA256_DIGEST_LENGTH;
84
73
  uint32_t blocks_count = keylen / SHA256_DIGEST_LENGTH;
85
73
  if (last_block_size) {
86
73
    blocks_count++;
87
73
  } else {
88
0
    last_block_size = SHA256_DIGEST_LENGTH;
89
0
  }
90
1.08k
  for (uint32_t blocknr = 1; blocknr <= blocks_count; blocknr++) {
91
1.01k
    PBKDF2_HMAC_SHA256_CTX pctx = {0};
92
1.01k
    pbkdf2_hmac_sha256_Init(&pctx, pass, passlen, salt, saltlen, blocknr);
93
1.01k
    pbkdf2_hmac_sha256_Update(&pctx, iterations);
94
1.01k
    uint8_t digest[SHA256_DIGEST_LENGTH] = {0};
95
1.01k
    pbkdf2_hmac_sha256_Final(&pctx, digest);
96
1.01k
    uint32_t key_offset = (blocknr - 1) * SHA256_DIGEST_LENGTH;
97
1.01k
    if (blocknr < blocks_count) {
98
941
      memcpy(key + key_offset, digest, SHA256_DIGEST_LENGTH);
99
941
    } else {
100
73
      memcpy(key + key_offset, digest, last_block_size);
101
73
    }
102
1.01k
  }
103
73
}
104
105
void pbkdf2_hmac_sha512_Init(PBKDF2_HMAC_SHA512_CTX *pctx, const uint8_t *pass,
106
                             int passlen, const uint8_t *salt, int saltlen,
107
547
                             uint32_t blocknr) {
108
547
  SHA512_CTX ctx = {0};
109
547
#if BYTE_ORDER == LITTLE_ENDIAN
110
547
  REVERSE32(blocknr, blocknr);
111
547
#endif
112
113
547
  hmac_sha512_prepare(pass, passlen, pctx->odig, pctx->idig);
114
547
  memzero(pctx->g, sizeof(pctx->g));
115
547
  pctx->g[8] = 0x8000000000000000;
116
547
  pctx->g[15] = (SHA512_BLOCK_LENGTH + SHA512_DIGEST_LENGTH) * 8;
117
118
547
  memcpy(ctx.state, pctx->idig, sizeof(pctx->idig));
119
547
  ctx.bitcount[0] = SHA512_BLOCK_LENGTH * 8;
120
547
  ctx.bitcount[1] = 0;
121
547
  sha512_Update(&ctx, salt, saltlen);
122
547
  sha512_Update(&ctx, (uint8_t *)&blocknr, sizeof(blocknr));
123
547
  sha512_Final(&ctx, (uint8_t *)pctx->g);
124
547
#if BYTE_ORDER == LITTLE_ENDIAN
125
4.92k
  for (uint32_t k = 0; k < SHA512_DIGEST_LENGTH / sizeof(uint64_t); k++) {
126
4.37k
    REVERSE64(pctx->g[k], pctx->g[k]);
127
4.37k
  }
128
547
#endif
129
547
  sha512_Transform(pctx->odig, pctx->g, pctx->g);
130
547
  memcpy(pctx->f, pctx->g, SHA512_DIGEST_LENGTH);
131
547
  pctx->first = 1;
132
547
}
133
134
void pbkdf2_hmac_sha512_Update(PBKDF2_HMAC_SHA512_CTX *pctx,
135
547
                               uint32_t iterations) {
136
1.28k
  for (uint32_t i = pctx->first; i < iterations; i++) {
137
737
    sha512_Transform(pctx->idig, pctx->g, pctx->g);
138
737
    sha512_Transform(pctx->odig, pctx->g, pctx->g);
139
6.63k
    for (uint32_t j = 0; j < SHA512_DIGEST_LENGTH / sizeof(uint64_t); j++) {
140
5.89k
      pctx->f[j] ^= pctx->g[j];
141
5.89k
    }
142
737
  }
143
547
  pctx->first = 0;
144
547
}
145
146
547
void pbkdf2_hmac_sha512_Final(PBKDF2_HMAC_SHA512_CTX *pctx, uint8_t *key) {
147
547
#if BYTE_ORDER == LITTLE_ENDIAN
148
4.92k
  for (uint32_t k = 0; k < SHA512_DIGEST_LENGTH / sizeof(uint64_t); k++) {
149
4.37k
    REVERSE64(pctx->f[k], pctx->f[k]);
150
4.37k
  }
151
547
#endif
152
547
  memcpy(key, pctx->f, SHA512_DIGEST_LENGTH);
153
547
  memzero(pctx, sizeof(PBKDF2_HMAC_SHA512_CTX));
154
547
}
155
156
void pbkdf2_hmac_sha512(const uint8_t *pass, int passlen, const uint8_t *salt,
157
                        int saltlen, uint32_t iterations, uint8_t *key,
158
79
                        int keylen) {
159
79
  uint32_t last_block_size = keylen % SHA512_DIGEST_LENGTH;
160
79
  uint32_t blocks_count = keylen / SHA512_DIGEST_LENGTH;
161
79
  if (last_block_size) {
162
71
    blocks_count++;
163
71
  } else {
164
8
    last_block_size = SHA512_DIGEST_LENGTH;
165
8
  }
166
626
  for (uint32_t blocknr = 1; blocknr <= blocks_count; blocknr++) {
167
547
    PBKDF2_HMAC_SHA512_CTX pctx = {0};
168
547
    pbkdf2_hmac_sha512_Init(&pctx, pass, passlen, salt, saltlen, blocknr);
169
547
    pbkdf2_hmac_sha512_Update(&pctx, iterations);
170
547
    uint8_t digest[SHA512_DIGEST_LENGTH] = {0};
171
547
    pbkdf2_hmac_sha512_Final(&pctx, digest);
172
547
    uint32_t key_offset = (blocknr - 1) * SHA512_DIGEST_LENGTH;
173
547
    if (blocknr < blocks_count) {
174
471
      memcpy(key + key_offset, digest, SHA512_DIGEST_LENGTH);
175
471
    } else {
176
76
      memcpy(key + key_offset, digest, last_block_size);
177
76
    }
178
547
  }
179
79
}