Coverage Report

Created: 2024-09-11 06:39

/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
0
                             uint32_t blocknr) {
33
0
  SHA256_CTX ctx = {0};
34
0
#if BYTE_ORDER == LITTLE_ENDIAN
35
0
  REVERSE32(blocknr, blocknr);
36
0
#endif
37
38
0
  hmac_sha256_prepare(pass, passlen, pctx->odig, pctx->idig);
39
0
  memzero(pctx->g, sizeof(pctx->g));
40
0
  pctx->g[8] = 0x80000000;
41
0
  pctx->g[15] = (SHA256_BLOCK_LENGTH + SHA256_DIGEST_LENGTH) * 8;
42
43
0
  memcpy(ctx.state, pctx->idig, sizeof(pctx->idig));
44
0
  ctx.bitcount = SHA256_BLOCK_LENGTH * 8;
45
0
  sha256_Update(&ctx, salt, saltlen);
46
0
  sha256_Update(&ctx, (uint8_t *)&blocknr, sizeof(blocknr));
47
0
  sha256_Final(&ctx, (uint8_t *)pctx->g);
48
0
#if BYTE_ORDER == LITTLE_ENDIAN
49
0
  for (uint32_t k = 0; k < SHA256_DIGEST_LENGTH / sizeof(uint32_t); k++) {
50
0
    REVERSE32(pctx->g[k], pctx->g[k]);
51
0
  }
52
0
#endif
53
0
  sha256_Transform(pctx->odig, pctx->g, pctx->g);
54
0
  memcpy(pctx->f, pctx->g, SHA256_DIGEST_LENGTH);
55
0
  pctx->first = 1;
56
0
}
57
58
void pbkdf2_hmac_sha256_Update(PBKDF2_HMAC_SHA256_CTX *pctx,
59
0
                               uint32_t iterations) {
60
0
  for (uint32_t i = pctx->first; i < iterations; i++) {
61
0
    sha256_Transform(pctx->idig, pctx->g, pctx->g);
62
0
    sha256_Transform(pctx->odig, pctx->g, pctx->g);
63
0
    for (uint32_t j = 0; j < SHA256_DIGEST_LENGTH / sizeof(uint32_t); j++) {
64
0
      pctx->f[j] ^= pctx->g[j];
65
0
    }
66
0
  }
67
0
  pctx->first = 0;
68
0
}
69
70
0
void pbkdf2_hmac_sha256_Final(PBKDF2_HMAC_SHA256_CTX *pctx, uint8_t *key) {
71
0
#if BYTE_ORDER == LITTLE_ENDIAN
72
0
  for (uint32_t k = 0; k < SHA256_DIGEST_LENGTH / sizeof(uint32_t); k++) {
73
0
    REVERSE32(pctx->f[k], pctx->f[k]);
74
0
  }
75
0
#endif
76
0
  memcpy(key, pctx->f, SHA256_DIGEST_LENGTH);
77
0
  memzero(pctx, sizeof(PBKDF2_HMAC_SHA256_CTX));
78
0
}
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
0
                        int keylen) {
83
0
  uint32_t last_block_size = keylen % SHA256_DIGEST_LENGTH;
84
0
  uint32_t blocks_count = keylen / SHA256_DIGEST_LENGTH;
85
0
  if (last_block_size) {
86
0
    blocks_count++;
87
0
  } else {
88
0
    last_block_size = SHA256_DIGEST_LENGTH;
89
0
  }
90
0
  for (uint32_t blocknr = 1; blocknr <= blocks_count; blocknr++) {
91
0
    PBKDF2_HMAC_SHA256_CTX pctx = {0};
92
0
    pbkdf2_hmac_sha256_Init(&pctx, pass, passlen, salt, saltlen, blocknr);
93
0
    pbkdf2_hmac_sha256_Update(&pctx, iterations);
94
0
    uint8_t digest[SHA256_DIGEST_LENGTH] = {0};
95
0
    pbkdf2_hmac_sha256_Final(&pctx, digest);
96
0
    uint32_t key_offset = (blocknr - 1) * SHA256_DIGEST_LENGTH;
97
0
    if (blocknr < blocks_count) {
98
0
      memcpy(key + key_offset, digest, SHA256_DIGEST_LENGTH);
99
0
    } else {
100
0
      memcpy(key + key_offset, digest, last_block_size);
101
0
    }
102
0
  }
103
0
}
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
0
                             uint32_t blocknr) {
108
0
  SHA512_CTX ctx = {0};
109
0
#if BYTE_ORDER == LITTLE_ENDIAN
110
0
  REVERSE32(blocknr, blocknr);
111
0
#endif
112
113
0
  hmac_sha512_prepare(pass, passlen, pctx->odig, pctx->idig);
114
0
  memzero(pctx->g, sizeof(pctx->g));
115
0
  pctx->g[8] = 0x8000000000000000;
116
0
  pctx->g[15] = (SHA512_BLOCK_LENGTH + SHA512_DIGEST_LENGTH) * 8;
117
118
0
  memcpy(ctx.state, pctx->idig, sizeof(pctx->idig));
119
0
  ctx.bitcount[0] = SHA512_BLOCK_LENGTH * 8;
120
0
  ctx.bitcount[1] = 0;
121
0
  sha512_Update(&ctx, salt, saltlen);
122
0
  sha512_Update(&ctx, (uint8_t *)&blocknr, sizeof(blocknr));
123
0
  sha512_Final(&ctx, (uint8_t *)pctx->g);
124
0
#if BYTE_ORDER == LITTLE_ENDIAN
125
0
  for (uint32_t k = 0; k < SHA512_DIGEST_LENGTH / sizeof(uint64_t); k++) {
126
0
    REVERSE64(pctx->g[k], pctx->g[k]);
127
0
  }
128
0
#endif
129
0
  sha512_Transform(pctx->odig, pctx->g, pctx->g);
130
0
  memcpy(pctx->f, pctx->g, SHA512_DIGEST_LENGTH);
131
0
  pctx->first = 1;
132
0
}
133
134
void pbkdf2_hmac_sha512_Update(PBKDF2_HMAC_SHA512_CTX *pctx,
135
0
                               uint32_t iterations) {
136
0
  for (uint32_t i = pctx->first; i < iterations; i++) {
137
0
    sha512_Transform(pctx->idig, pctx->g, pctx->g);
138
0
    sha512_Transform(pctx->odig, pctx->g, pctx->g);
139
0
    for (uint32_t j = 0; j < SHA512_DIGEST_LENGTH / sizeof(uint64_t); j++) {
140
0
      pctx->f[j] ^= pctx->g[j];
141
0
    }
142
0
  }
143
0
  pctx->first = 0;
144
0
}
145
146
0
void pbkdf2_hmac_sha512_Final(PBKDF2_HMAC_SHA512_CTX *pctx, uint8_t *key) {
147
0
#if BYTE_ORDER == LITTLE_ENDIAN
148
0
  for (uint32_t k = 0; k < SHA512_DIGEST_LENGTH / sizeof(uint64_t); k++) {
149
0
    REVERSE64(pctx->f[k], pctx->f[k]);
150
0
  }
151
0
#endif
152
0
  memcpy(key, pctx->f, SHA512_DIGEST_LENGTH);
153
0
  memzero(pctx, sizeof(PBKDF2_HMAC_SHA512_CTX));
154
0
}
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
0
                        int keylen) {
159
0
  uint32_t last_block_size = keylen % SHA512_DIGEST_LENGTH;
160
0
  uint32_t blocks_count = keylen / SHA512_DIGEST_LENGTH;
161
0
  if (last_block_size) {
162
0
    blocks_count++;
163
0
  } else {
164
0
    last_block_size = SHA512_DIGEST_LENGTH;
165
0
  }
166
0
  for (uint32_t blocknr = 1; blocknr <= blocks_count; blocknr++) {
167
0
    PBKDF2_HMAC_SHA512_CTX pctx = {0};
168
0
    pbkdf2_hmac_sha512_Init(&pctx, pass, passlen, salt, saltlen, blocknr);
169
0
    pbkdf2_hmac_sha512_Update(&pctx, iterations);
170
0
    uint8_t digest[SHA512_DIGEST_LENGTH] = {0};
171
0
    pbkdf2_hmac_sha512_Final(&pctx, digest);
172
0
    uint32_t key_offset = (blocknr - 1) * SHA512_DIGEST_LENGTH;
173
0
    if (blocknr < blocks_count) {
174
0
      memcpy(key + key_offset, digest, SHA512_DIGEST_LENGTH);
175
0
    } else {
176
0
      memcpy(key + key_offset, digest, last_block_size);
177
0
    }
178
0
  }
179
0
}