forked from 3devo/ChildbusBootloader
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathSelfProgramCommon.cpp
69 lines (54 loc) · 1.95 KB
/
SelfProgramCommon.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include "SelfProgram.h"
#include <cstring>
#include "sha256.h"
uint8_t SelfProgram::eraseCount = 0;
bool SelfProgram::appFwFingerprintValid = false;
unsigned char SelfProgram::appFwFingerprint[32] = {0};
uint32_t SelfProgram::appFwFingerprintSalt = 0;
void SelfProgram::readFlash(uint32_t address, uint8_t *data, uint16_t len) {
for (uint8_t i=0; i < len; i++) {
data[i] = readByte(address + i);
}
}
uint8_t SelfProgram::readByte(uint32_t address) {
uint8_t *ptr = (uint8_t*)FLASH_BASE + FLASH_APP_OFFSET + address;
return *ptr;
}
void SelfProgram::calculateSaltedFingerprint(uint32_t salt) {
uintptr_t start = FLASH_BASE + FLASH_APP_OFFSET;
size_t size = applicationSize;
//Helper to free sha context on return
struct Context {
mbedtls_sha256_context ctx;
Context() {
mbedtls_sha256_init(&ctx);
}
~Context() {
mbedtls_sha256_free(&ctx);
}
};
Context context;
if (mbedtls_sha256_starts_ret(&context.ctx, false) != 0) {
return;
}
if (mbedtls_sha256_update_ret(&context.ctx, reinterpret_cast<uint8_t *>(&salt), sizeof(salt)) != 0) { // Salt
return;
}
if (mbedtls_sha256_update_ret(&context.ctx, (const unsigned char *)start, size) != 0) { // Firmware
return;
}
if (mbedtls_sha256_finish_ret(&context.ctx, appFwFingerprint) != 0) {
return;
}
appFwFingerprintValid = true;
}
bool SelfProgram::checkUnsaltedFingerprint(const unsigned char fingerprint[32])
{
uintptr_t start = FLASH_BASE + FLASH_APP_OFFSET;
size_t size = applicationSize - FW_DESCRIPTOR_SIZE; // this is size of entire application flash area without the fw descriptor
unsigned char calculatedFingerprint[32] = {0};
if (mbedtls_sha256_ret((const unsigned char *)start, size, calculatedFingerprint, false) != 0) {
return false; // Couldn't check = check failed
}
return (memcmp(calculatedFingerprint, fingerprint, sizeof(calculatedFingerprint)) == 0);
}