Skip to content

Add primitives to compute provisioningID #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Nov 20, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions examples/boardID/boardID.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
This file is part of the Arduino_CloudUtils library.

Copyright (c) 2024 Arduino SA

This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#include <Arduino_BPId.h>

void setup() {
Serial.begin(9600);
while (!Serial);

#ifdef ARDUINO_OPTA
Ethernet.begin(NULL,0,0);
#endif

}

void loop() {
Serial.println(arduino::bpid::get());
delay(2000);
}
43 changes: 43 additions & 0 deletions examples/sha256/buffer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#pragma once

/*
* The following buffer is an hex dump of 1k of random data generated as
* head -c 1k /dev/urandom > /tmp/test
* and dumped with the following command `hexdump extras/test/test_files/test-1k -e '32/1 "0x%02X, ""\n"'`
* The SHA256 is known 1a7004279b162a6321de07de9d0362a66833b16f9acf870a69331e219eeafc7c /tmp/test
*/

uint8_t buffer[] = {
0x58, 0x1A, 0x10, 0xDD, 0x00, 0xBE, 0xE1, 0x2B, 0xE5, 0xA9, 0x62, 0xAF, 0x59, 0x66, 0x9C, 0x84, 0x50, 0x91, 0x30, 0x8E, 0x8F, 0xE4, 0x82, 0xE7, 0xDA, 0x9F, 0x90, 0x7A, 0xA2, 0x78, 0xCF, 0x7D,
0x40, 0x0E, 0x15, 0x5D, 0x2E, 0xF8, 0x6F, 0xA2, 0xEC, 0x50, 0xF1, 0xC9, 0x20, 0x71, 0xB9, 0xB7, 0xE8, 0x54, 0x06, 0x9E, 0x9E, 0xD7, 0x81, 0x31, 0x37, 0x56, 0x54, 0xD7, 0x37, 0xBE, 0x64, 0xAF,
0x9E, 0xC8, 0xFA, 0x67, 0x99, 0x4E, 0xFD, 0x58, 0xB6, 0x27, 0xAF, 0x06, 0xDE, 0xCD, 0x00, 0x40, 0xA7, 0x45, 0x3D, 0x2F, 0x0F, 0x91, 0x93, 0x88, 0x06, 0xDF, 0xC3, 0x60, 0x6F, 0x61, 0x26, 0x36,
0xF9, 0x19, 0xB0, 0x6F, 0x00, 0xAC, 0x73, 0xC2, 0x46, 0xC2, 0xC2, 0x96, 0xF0, 0xF3, 0xF7, 0xEE, 0x3D, 0x4E, 0x97, 0x64, 0xDC, 0x6A, 0x4F, 0xF5, 0xFC, 0x29, 0x05, 0x60, 0xA8, 0x0F, 0x9C, 0xF6,
0x16, 0xF1, 0xDC, 0xF1, 0x84, 0xFF, 0x47, 0xE1, 0x2A, 0x55, 0x36, 0xC5, 0xB3, 0x1F, 0x8B, 0x38, 0x64, 0xA8, 0x67, 0x31, 0xE2, 0xB9, 0x15, 0x23, 0x6F, 0xD9, 0x9B, 0x68, 0xC8, 0x89, 0xB9, 0xB4,
0x52, 0xCD, 0x10, 0xAA, 0xC9, 0x94, 0xFF, 0x13, 0xD2, 0x10, 0x7D, 0x03, 0x83, 0x13, 0xD5, 0xD7, 0x23, 0x86, 0xD9, 0x4A, 0x60, 0xDD, 0xA6, 0x24, 0x3E, 0x4E, 0x0F, 0x3B, 0x46, 0xFD, 0x3C, 0xD9,
0x3B, 0xD7, 0xEC, 0xE4, 0xD1, 0xF5, 0xA4, 0xAF, 0x40, 0xCF, 0x35, 0x76, 0x0F, 0x8F, 0xDC, 0x7D, 0x12, 0x92, 0x0B, 0x79, 0xD9, 0x1E, 0x5C, 0xA7, 0xD7, 0x79, 0x46, 0xA3, 0xC1, 0x42, 0x50, 0x11,
0x52, 0x77, 0x26, 0xFE, 0x6B, 0x6E, 0xCF, 0xC4, 0x28, 0x64, 0xB2, 0xB2, 0xD8, 0x59, 0xAC, 0x46, 0xB2, 0x0E, 0xAF, 0xD1, 0xC1, 0x3C, 0x02, 0x6A, 0x6E, 0x1C, 0xED, 0xCC, 0x95, 0xCE, 0x1B, 0xFD,
0x9E, 0xDB, 0x83, 0xBE, 0xBA, 0xAF, 0xC5, 0x98, 0x98, 0x01, 0x71, 0xE1, 0xD3, 0x6E, 0xF4, 0x26, 0x3C, 0x40, 0x5E, 0x84, 0x24, 0xF7, 0x62, 0x31, 0x3C, 0x8E, 0xF1, 0xE6, 0xCF, 0xB5, 0x29, 0x4B,
0x22, 0xA1, 0xA3, 0xB6, 0xE1, 0x7D, 0xFD, 0xEE, 0x7C, 0x5D, 0x84, 0x4D, 0x7E, 0x94, 0x3A, 0x85, 0x82, 0x19, 0x76, 0xBC, 0x66, 0xD7, 0x91, 0x81, 0x9E, 0x34, 0x5C, 0x05, 0x44, 0xE5, 0x10, 0x06,
0x24, 0xAC, 0xC7, 0xEF, 0x6D, 0xFB, 0x3E, 0xEB, 0x51, 0x35, 0xD2, 0x51, 0xB1, 0x0D, 0xFD, 0x36, 0x1C, 0x1D, 0x05, 0xE9, 0x7B, 0x99, 0x00, 0x01, 0x57, 0xC9, 0xEF, 0x29, 0xAF, 0x55, 0xBF, 0xC3,
0x4F, 0x21, 0x6F, 0x18, 0x9F, 0x02, 0x69, 0x1A, 0x1F, 0xD1, 0xAA, 0x97, 0x7B, 0xBA, 0x5D, 0x47, 0xDD, 0xBA, 0x62, 0xD7, 0xB7, 0x07, 0x67, 0x84, 0x75, 0xE4, 0x66, 0x2A, 0xBA, 0x64, 0xDF, 0x7B,
0x12, 0x1B, 0x2D, 0xC7, 0x16, 0xBC, 0xC4, 0x2A, 0xCD, 0x22, 0xE7, 0xCA, 0x11, 0x21, 0x70, 0x44, 0x9B, 0xA7, 0x61, 0xD7, 0x95, 0x0C, 0x87, 0xE6, 0xBF, 0x27, 0x52, 0xED, 0x5C, 0x14, 0x2C, 0xE6,
0xBA, 0x00, 0xD4, 0x2E, 0xE7, 0xD6, 0xAA, 0x9E, 0x45, 0x78, 0xA7, 0x21, 0x86, 0xD9, 0x2F, 0x9F, 0x8A, 0x95, 0x42, 0xE0, 0x21, 0x18, 0xBE, 0xDD, 0xD4, 0xF8, 0x9F, 0x13, 0x82, 0xDC, 0xCE, 0x16,
0x79, 0x22, 0xFA, 0xF9, 0xDC, 0x1C, 0xE2, 0x6F, 0x84, 0xA2, 0x88, 0x82, 0xCE, 0x51, 0xC8, 0x07, 0x61, 0x90, 0x2E, 0x91, 0x69, 0x94, 0x5E, 0xC3, 0xCA, 0x40, 0x7C, 0xE8, 0x14, 0xC2, 0x53, 0xD7,
0x9D, 0xC5, 0x5A, 0x70, 0x45, 0xF7, 0xD1, 0x15, 0xEB, 0x21, 0xBB, 0x86, 0x03, 0xBB, 0x8A, 0xC3, 0x49, 0x6B, 0x42, 0x7A, 0x50, 0x2A, 0x62, 0x33, 0x36, 0xD4, 0xB7, 0xE3, 0xA9, 0x66, 0xD8, 0x96,
0x21, 0x34, 0x9F, 0xEF, 0xBA, 0x4D, 0xB2, 0xAE, 0x66, 0x32, 0xFD, 0x3D, 0xD5, 0x47, 0x07, 0x17, 0x4D, 0x55, 0x63, 0x49, 0x54, 0xF8, 0xC6, 0xC4, 0x04, 0xF3, 0xCD, 0xC3, 0x6D, 0xCB, 0x8E, 0x34,
0x04, 0x86, 0xC0, 0xFA, 0x1F, 0xB7, 0x1E, 0x86, 0x2D, 0xAB, 0xC4, 0xA5, 0x37, 0xEC, 0xD9, 0x77, 0x39, 0x59, 0x98, 0xFF, 0xDF, 0x1D, 0x27, 0xAB, 0xED, 0xA2, 0xF0, 0x7E, 0x4C, 0xF0, 0x2C, 0x74,
0x73, 0x4E, 0x3B, 0x7D, 0x1D, 0xA6, 0x02, 0x65, 0xB5, 0xE7, 0x5D, 0x09, 0x74, 0x0F, 0x5A, 0xCF, 0x82, 0xF9, 0x74, 0x25, 0xEB, 0x39, 0xA9, 0xC2, 0x01, 0x69, 0x5F, 0x8E, 0xAD, 0x7F, 0x67, 0xC7,
0x82, 0xB2, 0xC6, 0x72, 0xE7, 0x73, 0xAB, 0xA4, 0x64, 0x9C, 0x0D, 0x2E, 0x28, 0x0D, 0x30, 0x9B, 0x76, 0x54, 0x12, 0xC6, 0xB4, 0xB5, 0xDC, 0xCC, 0x10, 0xB7, 0x12, 0x10, 0x69, 0x0F, 0xE0, 0x14,
0x6C, 0xD4, 0x2C, 0x56, 0xA8, 0xCB, 0xDC, 0x7B, 0xD5, 0xFE, 0x32, 0x13, 0x99, 0x32, 0x58, 0xA8, 0x89, 0x79, 0xBD, 0x00, 0x87, 0xF0, 0x15, 0xC0, 0xD8, 0xD9, 0x17, 0x55, 0xD1, 0x83, 0xD3, 0xF1,
0x2E, 0x83, 0x02, 0x81, 0x73, 0xE8, 0xE8, 0x0F, 0x99, 0x50, 0xB5, 0x79, 0x1E, 0x7C, 0x17, 0x21, 0xE9, 0xFA, 0x7C, 0x97, 0x4F, 0xC7, 0x3F, 0x3A, 0x36, 0x12, 0x1B, 0x83, 0xA3, 0x44, 0x82, 0x59,
0xBE, 0x6B, 0x91, 0xCF, 0xC5, 0x11, 0xBA, 0xB1, 0xF6, 0x77, 0x1E, 0xFC, 0x16, 0x2F, 0x4A, 0x40, 0xDB, 0x9B, 0x16, 0x5D, 0x8D, 0xBB, 0x86, 0x54, 0x15, 0x13, 0x13, 0x15, 0x27, 0x26, 0x2B, 0x4A,
0x0A, 0xBE, 0x5E, 0x5A, 0xF8, 0xBF, 0xBF, 0x71, 0xB1, 0xA8, 0xD1, 0x03, 0x8F, 0xE4, 0xB3, 0xA4, 0x82, 0x1F, 0x9C, 0x43, 0x57, 0x7B, 0x90, 0x04, 0x5D, 0x69, 0xCB, 0x48, 0x6D, 0x0C, 0x85, 0x0A,
0xC7, 0x3F, 0x19, 0x18, 0x92, 0xD0, 0x20, 0x49, 0xB2, 0x3D, 0xD8, 0xBD, 0x5E, 0xF8, 0x42, 0x73, 0x14, 0xF3, 0xD5, 0xD1, 0xFE, 0xFD, 0xDB, 0xCA, 0x28, 0x15, 0x86, 0xE4, 0x50, 0x99, 0xD2, 0x7E,
0xF9, 0x95, 0xAC, 0xBE, 0x8C, 0xC9, 0xEB, 0x1D, 0x85, 0xB7, 0x76, 0x35, 0x0F, 0xF4, 0x68, 0xD7, 0x50, 0x40, 0xF9, 0xBD, 0x72, 0x03, 0x92, 0x4E, 0x16, 0x21, 0x0D, 0x58, 0x8F, 0x63, 0xFB, 0x4F,
0x1E, 0xD7, 0x36, 0x19, 0x5A, 0xFD, 0xF2, 0x57, 0x59, 0x14, 0x8D, 0x1D, 0x66, 0x47, 0x7E, 0xF9, 0x02, 0x52, 0x3C, 0xA8, 0x9C, 0x36, 0x11, 0x76, 0x1C, 0x41, 0x84, 0xB2, 0x16, 0xD6, 0xCF, 0x38,
0x3E, 0xB0, 0x40, 0xD9, 0x51, 0x44, 0x73, 0x35, 0x93, 0x39, 0x0A, 0xE9, 0x2C, 0x77, 0x4A, 0x02, 0xDD, 0x07, 0xCE, 0x7A, 0xAD, 0xA5, 0x34, 0x03, 0xFD, 0x08, 0x21, 0x61, 0x82, 0xB7, 0xC5, 0x0D,
0xC0, 0xEF, 0x2B, 0xB9, 0x90, 0xED, 0x06, 0xF0, 0xA8, 0xC9, 0xB9, 0xCB, 0xF7, 0x38, 0xB9, 0x16, 0x6D, 0x6C, 0x64, 0x8A, 0x18, 0x81, 0x96, 0x31, 0x70, 0xD9, 0x5B, 0xAE, 0x51, 0xBF, 0xC4, 0xED,
0x7B, 0x6C, 0xAF, 0x14, 0x29, 0xB6, 0x0A, 0x6F, 0xBB, 0xDE, 0x9D, 0xA0, 0x49, 0x5B, 0x39, 0xB4, 0xC0, 0x83, 0x3E, 0x56, 0x18, 0xE8, 0x03, 0xEE, 0xB0, 0x9B, 0x94, 0xF4, 0x70, 0x94, 0xF3, 0x25,
0xA5, 0x42, 0xC5, 0x2E, 0xD3, 0x09, 0xF1, 0x3B, 0x8E, 0x6C, 0x30, 0x29, 0xD0, 0xD4, 0x62, 0x8C, 0xA3, 0x40, 0x21, 0xFA, 0x93, 0x0E, 0x48, 0x81, 0x20, 0x32, 0x1D, 0xF7, 0xD5, 0xF4, 0x50, 0x64,
0x68, 0x15, 0x98, 0xFF, 0x3B, 0xD9, 0x64, 0x50, 0x9C, 0x74, 0x0C, 0x25, 0x1E, 0xED, 0xFF, 0x87, 0x84, 0x0B, 0x6D, 0x0F, 0xF3, 0x5E, 0xF9, 0xB6, 0x84, 0x6E, 0x3D, 0xF4, 0x00, 0x37, 0x4D, 0x68,
};
43 changes: 43 additions & 0 deletions examples/sha256/sha256.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
This file is part of the Arduino_CloudUtils library.

Copyright (c) 2024 Arduino SA

This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#include <Arduino_SHA256.h>
#include "buffer.h"

void setup() {
Serial.begin(9600);
while(!Serial);

uint8_t sha[SHA256::HASH_SIZE];

SHA256 sha256;
sha256.begin();
sha256.update(buffer, sizeof(buffer));
sha256.finalize(sha);

Serial.println(hexEncode(sha, sizeof(sha)));

/* One-shot */
arduino::sha256::oneshot(buffer, sizeof(buffer), sha);
Serial.println(hexEncode(sha, sizeof(sha)));
}

static String hexEncode(uint8_t* in, uint32_t size) {
String out;
out.reserve((size * 2) + 1);

char* ptr = out.begin();
for (uint32_t i = 0; i < size; i++) {
ptr += sprintf(ptr, "%02X", in[i]);
}
return String(out.c_str());
}

void loop() { }
12 changes: 12 additions & 0 deletions src/Arduino_BPId.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
This file is part of the Arduino_CloudUtils library.

Copyright (c) 2024 Arduino SA

This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#pragma once

#include "./bpid/bpid.h"
12 changes: 12 additions & 0 deletions src/Arduino_HEX.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
This file is part of the Arduino_CloudUtils library.

Copyright (c) 2024 Arduino SA

This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#pragma once

#include "./hex/hex.h"
12 changes: 12 additions & 0 deletions src/Arduino_SHA256.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
This file is part of the Arduino_CloudUtils library.

Copyright (c) 2024 Arduino SA

This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#pragma once

#include "./sha256/SHA256.h"
46 changes: 46 additions & 0 deletions src/bpid/bpid.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
This file is part of the Arduino_CloudUtils library.

Copyright (c) 2024 Arduino SA

This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#include "bpid.h"
#include "../sha256/SHA256.h"
#include "../hex/hex.h"

namespace arduino { namespace bpid {

bool get(uint8_t* in, uint32_t size) {
if (size < BOARD_PROVISIONING_ID_SIZE) {
return false;
}
uint8_t offset = 0;
if (!arduino::ucid::get(&in[offset], size)) {
return false;
}
offset += arduino::ucid::UC_UID_SIZE;
if (!arduino::mac::get(&in[offset], size - offset)) {
return false;
}
offset += arduino::mac::IFACE_MAC_SIZE;
if (!arduino::csn::get(&in[offset], size - offset)) {
return false;
}
return true;
}

String get() {
uint8_t data[BOARD_PROVISIONING_ID_SIZE];
if (!get(data, sizeof(data))) {
return String("");
}
uint8_t out[SHA256::HASH_SIZE];
arduino::sha256::oneshot(data, sizeof(data), out);
return arduino::hex::encode(out, sizeof(out));
}

}} // arduino::bpid
30 changes: 30 additions & 0 deletions src/bpid/bpid.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
This file is part of the Arduino_CloudUtils library.

Copyright (c) 2024 Arduino SA

This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#pragma once

#include <Arduino.h>
#include "ucid.h"
#include "mac.h"
#include "csn.h"

namespace arduino { namespace bpid {
/*
* This library contains the methods to get board provisioning id
*/

constexpr int BOARD_PROVISIONING_ID_SIZE = arduino::ucid::UC_UID_SIZE +
arduino::mac::IFACE_MAC_SIZE +
arduino::csn::CRYPTO_SN_SIZE;

bool get(uint8_t* in, uint32_t size);
String get();

}} // arduino::bpid
26 changes: 26 additions & 0 deletions src/bpid/csn.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
This file is part of the Arduino_CloudUtils library.

Copyright (c) 2024 Arduino SA

This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#include "csn.h"

namespace arduino { namespace csn {

bool get(uint8_t *in, uint32_t size) {
if (size < CRYPTO_SN_SIZE) {
return false;
}
SecureElement se;
if (!se.begin() || !se.serialNumber(in)) {
return false;
}
return true;
}

}} // arduino::csn
39 changes: 39 additions & 0 deletions src/bpid/csn.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
This file is part of the Arduino_CloudUtils library.

Copyright (c) 2024 Arduino SA

This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#pragma once

#include <Arduino.h>
#include <Arduino_SecureElement.h>

namespace arduino { namespace csn {
/*
* This library contains the methods to get board microcontroller id
*/

#if defined(ARDUINO_NANO_RP2040_CONNECT) || \
defined(ARDUINO_SAMD_MKRWIFI1010) || \
defined(ARDUINO_SAMD_NANO_33_IOT) || \
defined(ARDUINO_PORTENTA_H7_M7) || \
defined(ARDUINO_OPTA) || \
defined(ARDUINO_GIGA)
constexpr int CRYPTO_SN_SIZE = 9;
#elif defined(ARDUINO_PORTENTA_C33) || \
defined(ARDUINO_NICLA_VISION)
constexpr int CRYPTO_SN_SIZE = SE05X_SN_LENGTH;
#elif defined(ARDUINO_UNOR4_WIFI)
constexpr int CRYPTO_SN_SIZE = 6;
#else
#error "Unknown board"
#endif

bool get(uint8_t *in, uint32_t size);

}} // arduino::csn
37 changes: 37 additions & 0 deletions src/bpid/mac.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
This file is part of the Arduino_CloudUtils library.

Copyright (c) 2024 Arduino SA

This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#include "mac.h"

namespace arduino { namespace mac {

bool get(uint8_t *in, uint32_t size) {
if (size < IFACE_MAC_SIZE) {
return false;
}
#if defined(ARDUINO_SAMD_MKRWIFI1010) || \
defined(ARDUINO_SAMD_NANO_33_IOT)
WiFi.macAddress(in);
#elif defined(ARDUINO_PORTENTA_H7_M7) || \
defined(ARDUINO_NICLA_VISION) || \
defined(ARDUINO_GIGA)
WiFi.macAddress(in);
#elif defined(ARDUINO_PORTENTA_C33) || \
defined(ARDUINO_UNOR4_WIFI)
WiFi.macAddress(in);
#elif defined(ARDUINO_NANO_RP2040_CONNECT)
WiFi.macAddress(in);
#elif defined(ARDUINO_OPTA)
Ethernet.MACAddress(in);
#endif
return true;
}

}} // arduino::mac
52 changes: 52 additions & 0 deletions src/bpid/mac.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
This file is part of the Arduino_CloudUtils library.

Copyright (c) 2024 Arduino SA

This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#pragma once

#if defined(ARDUINO_NANO_RP2040_CONNECT) || \
defined(ARDUINO_SAMD_MKRWIFI1010) || \
defined(ARDUINO_SAMD_NANO_33_IOT) || \
defined(ARDUINO_PORTENTA_H7_M7) || \
defined(ARDUINO_NICLA_VISION) || \
defined(ARDUINO_GIGA)
#include <WiFi.h>
#define IFACE_MAC_ADDR_LENGTH WL_MAC_ADDR_LENGTH
#elif defined(ARDUINO_PORTENTA_C33)
#include <WiFiC3.h>
#define IFACE_MAC_ADDR_LENGTH WL_MAC_ADDR_LENGTH
#elif defined(ARDUINO_UNOR4_WIFI)
#include <WiFi.h>
#define IFACE_MAC_ADDR_LENGTH WL_MAC_ADDR_LENGTH
#elif defined(ARDUINO_OPTA)
#include <Ethernet.h>
#define IFACE_MAC_ADDR_LENGTH 6
#else
#error "Unknown board"
#endif

namespace arduino { namespace mac {
/*
* This library contains the methods to get board mac address
* ARDUINO_NANO_RP2040_CONNECT: reversed
* ARDUINO_SAMD_MKRWIFI1010: reversed
* ARDUINO_SAMD_NANO_33_IOT: reversed
* ARDUINO_PORTENTA_H7_M7: WiFi.setTimeout(0);WiFi.begin("In33dm4c4ddr35", "In33dm4c4ddr35", ENC_TYPE_TKIP) reversed
* ARDUINO_NICLA_VISION:
* ARDUINO_GIGA:
* ARDUINO_PORTENTA_C33: Interface.begin() not reversed
* ARDUINO_UNOR4_WIFI: not reversed
* ARDUINO_OPTA: Ethernet.begin(NULL,0,0); reversed
*/

constexpr int IFACE_MAC_SIZE = IFACE_MAC_ADDR_LENGTH;

bool get(uint8_t *in, uint32_t size);

}} // arduino::mac
48 changes: 48 additions & 0 deletions src/bpid/ucid.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
This file is part of the Arduino_CloudUtils library.
Copyright (c) 2024 Arduino SA
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#include "ucid.h"

namespace arduino { namespace ucid {

bool get(uint8_t *in, uint32_t size) {
if (size < UC_UID_SIZE) {
return false;
}
#if defined(ARDUINO_SAMD_MKRWIFI1010) || \
defined(ARDUINO_SAMD_NANO_33_IOT)
(*(uint32_t*)(&in[0x0])) = __builtin_bswap32(*(volatile uint32_t*)(0x0080A00C));
(*(uint32_t*)(&in[0x4])) = __builtin_bswap32(*(volatile uint32_t*)(0x0080A040));
(*(uint32_t*)(&in[0x8])) = __builtin_bswap32(*(volatile uint32_t*)(0x0080A044));
(*(uint32_t*)(&in[0xC])) = __builtin_bswap32(*(volatile uint32_t*)(0x0080A048));
#elif defined(ARDUINO_PORTENTA_H7_M7) || \
defined(ARDUINO_NICLA_VISION) || \
defined(ARDUINO_OPTA) || \
defined(ARDUINO_GIGA)
(*(uint32_t*)(&in[0x0])) = __builtin_bswap32(HAL_GetUIDw0());
(*(uint32_t*)(&in[0x4])) = __builtin_bswap32(HAL_GetUIDw1());
(*(uint32_t*)(&in[0x8])) = __builtin_bswap32(HAL_GetUIDw2());
#elif defined(ARDUINO_PORTENTA_C33) || \
defined(ARDUINO_UNOR4_WIFI)
const bsp_unique_id_t* t = R_BSP_UniqueIdGet();
(*(uint32_t*)(&in[0x0])) = __builtin_bswap32(t->unique_id_words[0x0]);
(*(uint32_t*)(&in[0x4])) = __builtin_bswap32(t->unique_id_words[0x1]);
(*(uint32_t*)(&in[0x8])) = __builtin_bswap32(t->unique_id_words[0x2]);
(*(uint32_t*)(&in[0xC])) = __builtin_bswap32(t->unique_id_words[0x3]);
#elif defined(ARDUINO_NANO_RP2040_CONNECT)
uint8_t id[UC_UID_SIZE];
flash_get_unique_id(id);
(*(uint32_t*)(&in[0x0])) = __builtin_bswap32(*(uint32_t*)&id[0x0]);
(*(uint32_t*)(&in[0x4])) = __builtin_bswap32(*(uint32_t*)&id[0x4]);
#endif
return true;
}

}} // arduino::ucid
42 changes: 42 additions & 0 deletions src/bpid/ucid.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
This file is part of the Arduino_CloudUtils library.
Copyright (c) 2024 Arduino SA
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#pragma once

#include <Arduino.h>

namespace arduino { namespace ucid {
/*
* This library contains the methods to get board microcontroller id
*/

#if defined(ARDUINO_SAMD_MKRWIFI1010) || \
defined(ARDUINO_SAMD_NANO_33_IOT)
constexpr int UC_UID_SIZE = 16;
#elif defined(ARDUINO_PORTENTA_H7_M7) || \
defined(ARDUINO_NICLA_VISION) || \
defined(ARDUINO_OPTA) || \
defined(ARDUINO_GIGA)
constexpr int UC_UID_SIZE = 12;
#elif defined(ARDUINO_PORTENTA_C33) || \
defined(ARDUINO_UNOR4_WIFI)
constexpr int UC_UID_SIZE = 16;
#elif defined(ARDUINO_NANO_RP2040_CONNECT)
extern "C" {
#include "hardware/flash.h"
}
constexpr int UC_UID_SIZE = FLASH_UNIQUE_ID_SIZE_BYTES;
#else
#error "Unknown board"
#endif

bool get(uint8_t *in, uint32_t size);

}} // arduino::ucid
26 changes: 26 additions & 0 deletions src/hex/hex.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
This file is part of the Arduino_CloudUtils library.
Copyright (c) 2024 Arduino SA
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#include "hex.h"

namespace arduino { namespace hex {

String encode(uint8_t* in, uint32_t size) {
String out;
out.reserve((size * 2) + 1);

char *ptr = out.begin();
for (uint32_t i = 0; i < size; i++) {
ptr += sprintf(ptr, "%02X", in[i]);
}
return String(out.c_str());
}

}} // arduino::hex
22 changes: 22 additions & 0 deletions src/hex/hex.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
This file is part of the Arduino_CloudUtils library.
Copyright (c) 2024 Arduino SA
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#pragma once

#include <Arduino.h>

namespace arduino { namespace hex {
/*
* This library contains the methods to get board provisioning id
*/

String encode(uint8_t* in, uint32_t size);

}} // arduino::hex
23 changes: 23 additions & 0 deletions src/sha256/SHA256.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
This file is part of the Arduino_CloudUtils library.
Copyright (c) 2024 Arduino SA
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#include "SHA256.h"

void SHA256::begin() {
sha256_init(&_ctx);
}

void SHA256::update(uint8_t const * data, uint32_t const len) {
sha256_update(&_ctx, data, len);
}

void SHA256::finalize(uint8_t * hash) {
sha256_final(&_ctx, hash);
}
45 changes: 45 additions & 0 deletions src/sha256/SHA256.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
This file is part of the Arduino_CloudUtils library.
Copyright (c) 2024 Arduino SA
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#pragma once

#include "sha256.h"

class SHA256 {

public:

static constexpr uint32_t HASH_SIZE = SHA256_DIGEST_SIZE;

void begin();
void update(uint8_t const * data, uint32_t const len);
void finalize(uint8_t * hash);

private:

sha256_ctx _ctx;
};

namespace arduino { namespace sha256 {

inline void begin(sha256_ctx * ctx) {
return sha256_init(ctx);
}
inline void update(sha256_ctx *ctx, const uint8_t *input, uint32_t length) {
return sha256_update(ctx, input, length);
}
inline void finalize(sha256_ctx * ctx, uint8_t digest[SHA256_DIGEST_SIZE]) {
return sha256_final(ctx, digest);
}
inline void oneshot(const unsigned char *input, unsigned int ilen, unsigned char *output) {
::sha256(input, ilen, output);
}

}} // arduino::sha256
347 changes: 347 additions & 0 deletions src/sha256/sha256.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,347 @@
/*
* FIPS 180-2 256 implementation based on code by Oliver Gay
* under a BSD-style license. http://ouah.org/ogay/sha2/
*
* Copyright (C) 2005-2023 Olivier Gay <olivier.gay@a3.epfl.ch>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/

#if 0
#define UNROLL_LOOPS /* Enable loops unrolling */
#endif

#include "sha256.h"

#define SHFR(x, n) (x >> n)
#define ROTR(x, n) ((x >> n) | (x << ((sizeof (x) << 3) - n)))
#define ROTL(x, n) ((x << n) | (x >> ((sizeof (x) << 3) - n)))
#define CH(x, y, z) ((x & y) ^ (~x & z))
#define MAJ(x, y, z) ((x & y) ^ (x & z) ^ (y & z))

#define SHA256_F1(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
#define SHA256_F2(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
#define SHA256_F3(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHFR(x, 3))
#define SHA256_F4(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHFR(x, 10))

#define UNPACK32(x, str) \
{ \
*((str) + 3) = (uint8_t) ((x) ); \
*((str) + 2) = (uint8_t) ((x) >> 8); \
*((str) + 1) = (uint8_t) ((x) >> 16); \
*((str) + 0) = (uint8_t) ((x) >> 24); \
}

#define PACK32(str, x) \
{ \
*(x) = ((uint32_t) *((str) + 3) ) \
| ((uint32_t) *((str) + 2) << 8) \
| ((uint32_t) *((str) + 1) << 16) \
| ((uint32_t) *((str) + 0) << 24); \
}

#define UNPACK64(x, str) \
{ \
*((str) + 7) = (uint8_t) ((x) ); \
*((str) + 6) = (uint8_t) ((x) >> 8); \
*((str) + 5) = (uint8_t) ((x) >> 16); \
*((str) + 4) = (uint8_t) ((x) >> 24); \
*((str) + 3) = (uint8_t) ((x) >> 32); \
*((str) + 2) = (uint8_t) ((x) >> 40); \
*((str) + 1) = (uint8_t) ((x) >> 48); \
*((str) + 0) = (uint8_t) ((x) >> 56); \
}

#define PACK64(str, x) \
{ \
*(x) = ((uint64_t) *((str) + 7) ) \
| ((uint64_t) *((str) + 6) << 8) \
| ((uint64_t) *((str) + 5) << 16) \
| ((uint64_t) *((str) + 4) << 24) \
| ((uint64_t) *((str) + 3) << 32) \
| ((uint64_t) *((str) + 2) << 40) \
| ((uint64_t) *((str) + 1) << 48) \
| ((uint64_t) *((str) + 0) << 56); \
}

/* Macros used for loops unrolling */

#define SHA256_SCR(i) \
{ \
w[i] = SHA256_F4(w[i - 2]) + w[i - 7] \
+ SHA256_F3(w[i - 15]) + w[i - 16]; \
}

#define SHA256_EXP(a, b, c, d, e, f, g, h, j) \
{ \
t1 = wv[h] + SHA256_F2(wv[e]) + CH(wv[e], wv[f], wv[g]) \
+ sha256_k[j] + w[j]; \
t2 = SHA256_F1(wv[a]) + MAJ(wv[a], wv[b], wv[c]); \
wv[d] += t1; \
wv[h] = t1 + t2; \
}

static const uint32_t sha256_h0[8] =
{0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};

static const uint32_t sha256_k[64] =
{0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2};

/* SHA-2 internal function */

static void sha256_transf(sha256_ctx *ctx, const uint8_t *message,
uint64_t block_nb)
{
uint32_t w[64];
uint32_t wv[8];
uint32_t t1, t2;
const uint8_t *sub_block;
uint64_t i;

#ifndef UNROLL_LOOPS
int j;
#endif

for (i = 0; i < block_nb; i++) {
sub_block = message + (i << 6);

#ifndef UNROLL_LOOPS
for (j = 0; j < 16; j++) {
PACK32(&sub_block[j << 2], &w[j]);
}

for (j = 16; j < 64; j++) {
SHA256_SCR(j);
}

for (j = 0; j < 8; j++) {
wv[j] = ctx->h[j];
}

for (j = 0; j < 64; j++) {
t1 = wv[7] + SHA256_F2(wv[4]) + CH(wv[4], wv[5], wv[6])
+ sha256_k[j] + w[j];
t2 = SHA256_F1(wv[0]) + MAJ(wv[0], wv[1], wv[2]);
wv[7] = wv[6];
wv[6] = wv[5];
wv[5] = wv[4];
wv[4] = wv[3] + t1;
wv[3] = wv[2];
wv[2] = wv[1];
wv[1] = wv[0];
wv[0] = t1 + t2;
}

for (j = 0; j < 8; j++) {
ctx->h[j] += wv[j];
}
#else
PACK32(&sub_block[ 0], &w[ 0]); PACK32(&sub_block[ 4], &w[ 1]);
PACK32(&sub_block[ 8], &w[ 2]); PACK32(&sub_block[12], &w[ 3]);
PACK32(&sub_block[16], &w[ 4]); PACK32(&sub_block[20], &w[ 5]);
PACK32(&sub_block[24], &w[ 6]); PACK32(&sub_block[28], &w[ 7]);
PACK32(&sub_block[32], &w[ 8]); PACK32(&sub_block[36], &w[ 9]);
PACK32(&sub_block[40], &w[10]); PACK32(&sub_block[44], &w[11]);
PACK32(&sub_block[48], &w[12]); PACK32(&sub_block[52], &w[13]);
PACK32(&sub_block[56], &w[14]); PACK32(&sub_block[60], &w[15]);

SHA256_SCR(16); SHA256_SCR(17); SHA256_SCR(18); SHA256_SCR(19);
SHA256_SCR(20); SHA256_SCR(21); SHA256_SCR(22); SHA256_SCR(23);
SHA256_SCR(24); SHA256_SCR(25); SHA256_SCR(26); SHA256_SCR(27);
SHA256_SCR(28); SHA256_SCR(29); SHA256_SCR(30); SHA256_SCR(31);
SHA256_SCR(32); SHA256_SCR(33); SHA256_SCR(34); SHA256_SCR(35);
SHA256_SCR(36); SHA256_SCR(37); SHA256_SCR(38); SHA256_SCR(39);
SHA256_SCR(40); SHA256_SCR(41); SHA256_SCR(42); SHA256_SCR(43);
SHA256_SCR(44); SHA256_SCR(45); SHA256_SCR(46); SHA256_SCR(47);
SHA256_SCR(48); SHA256_SCR(49); SHA256_SCR(50); SHA256_SCR(51);
SHA256_SCR(52); SHA256_SCR(53); SHA256_SCR(54); SHA256_SCR(55);
SHA256_SCR(56); SHA256_SCR(57); SHA256_SCR(58); SHA256_SCR(59);
SHA256_SCR(60); SHA256_SCR(61); SHA256_SCR(62); SHA256_SCR(63);

wv[0] = ctx->h[0]; wv[1] = ctx->h[1];
wv[2] = ctx->h[2]; wv[3] = ctx->h[3];
wv[4] = ctx->h[4]; wv[5] = ctx->h[5];
wv[6] = ctx->h[6]; wv[7] = ctx->h[7];

SHA256_EXP(0,1,2,3,4,5,6,7, 0); SHA256_EXP(7,0,1,2,3,4,5,6, 1);
SHA256_EXP(6,7,0,1,2,3,4,5, 2); SHA256_EXP(5,6,7,0,1,2,3,4, 3);
SHA256_EXP(4,5,6,7,0,1,2,3, 4); SHA256_EXP(3,4,5,6,7,0,1,2, 5);
SHA256_EXP(2,3,4,5,6,7,0,1, 6); SHA256_EXP(1,2,3,4,5,6,7,0, 7);
SHA256_EXP(0,1,2,3,4,5,6,7, 8); SHA256_EXP(7,0,1,2,3,4,5,6, 9);
SHA256_EXP(6,7,0,1,2,3,4,5,10); SHA256_EXP(5,6,7,0,1,2,3,4,11);
SHA256_EXP(4,5,6,7,0,1,2,3,12); SHA256_EXP(3,4,5,6,7,0,1,2,13);
SHA256_EXP(2,3,4,5,6,7,0,1,14); SHA256_EXP(1,2,3,4,5,6,7,0,15);
SHA256_EXP(0,1,2,3,4,5,6,7,16); SHA256_EXP(7,0,1,2,3,4,5,6,17);
SHA256_EXP(6,7,0,1,2,3,4,5,18); SHA256_EXP(5,6,7,0,1,2,3,4,19);
SHA256_EXP(4,5,6,7,0,1,2,3,20); SHA256_EXP(3,4,5,6,7,0,1,2,21);
SHA256_EXP(2,3,4,5,6,7,0,1,22); SHA256_EXP(1,2,3,4,5,6,7,0,23);
SHA256_EXP(0,1,2,3,4,5,6,7,24); SHA256_EXP(7,0,1,2,3,4,5,6,25);
SHA256_EXP(6,7,0,1,2,3,4,5,26); SHA256_EXP(5,6,7,0,1,2,3,4,27);
SHA256_EXP(4,5,6,7,0,1,2,3,28); SHA256_EXP(3,4,5,6,7,0,1,2,29);
SHA256_EXP(2,3,4,5,6,7,0,1,30); SHA256_EXP(1,2,3,4,5,6,7,0,31);
SHA256_EXP(0,1,2,3,4,5,6,7,32); SHA256_EXP(7,0,1,2,3,4,5,6,33);
SHA256_EXP(6,7,0,1,2,3,4,5,34); SHA256_EXP(5,6,7,0,1,2,3,4,35);
SHA256_EXP(4,5,6,7,0,1,2,3,36); SHA256_EXP(3,4,5,6,7,0,1,2,37);
SHA256_EXP(2,3,4,5,6,7,0,1,38); SHA256_EXP(1,2,3,4,5,6,7,0,39);
SHA256_EXP(0,1,2,3,4,5,6,7,40); SHA256_EXP(7,0,1,2,3,4,5,6,41);
SHA256_EXP(6,7,0,1,2,3,4,5,42); SHA256_EXP(5,6,7,0,1,2,3,4,43);
SHA256_EXP(4,5,6,7,0,1,2,3,44); SHA256_EXP(3,4,5,6,7,0,1,2,45);
SHA256_EXP(2,3,4,5,6,7,0,1,46); SHA256_EXP(1,2,3,4,5,6,7,0,47);
SHA256_EXP(0,1,2,3,4,5,6,7,48); SHA256_EXP(7,0,1,2,3,4,5,6,49);
SHA256_EXP(6,7,0,1,2,3,4,5,50); SHA256_EXP(5,6,7,0,1,2,3,4,51);
SHA256_EXP(4,5,6,7,0,1,2,3,52); SHA256_EXP(3,4,5,6,7,0,1,2,53);
SHA256_EXP(2,3,4,5,6,7,0,1,54); SHA256_EXP(1,2,3,4,5,6,7,0,55);
SHA256_EXP(0,1,2,3,4,5,6,7,56); SHA256_EXP(7,0,1,2,3,4,5,6,57);
SHA256_EXP(6,7,0,1,2,3,4,5,58); SHA256_EXP(5,6,7,0,1,2,3,4,59);
SHA256_EXP(4,5,6,7,0,1,2,3,60); SHA256_EXP(3,4,5,6,7,0,1,2,61);
SHA256_EXP(2,3,4,5,6,7,0,1,62); SHA256_EXP(1,2,3,4,5,6,7,0,63);

ctx->h[0] += wv[0]; ctx->h[1] += wv[1];
ctx->h[2] += wv[2]; ctx->h[3] += wv[3];
ctx->h[4] += wv[4]; ctx->h[5] += wv[5];
ctx->h[6] += wv[6]; ctx->h[7] += wv[7];
#endif /* !UNROLL_LOOPS */
}
}

/* SHA-256 functions */

void sha256(const uint8_t *message, uint64_t len, uint8_t *digest)
{
sha256_ctx ctx;

sha256_init(&ctx);
sha256_update(&ctx, message, len);
sha256_final(&ctx, digest);
}

void sha256_init(sha256_ctx *ctx)
{
#ifndef UNROLL_LOOPS
int i;
for (i = 0; i < 8; i++) {
ctx->h[i] = sha256_h0[i];
}
#else
ctx->h[0] = sha256_h0[0]; ctx->h[1] = sha256_h0[1];
ctx->h[2] = sha256_h0[2]; ctx->h[3] = sha256_h0[3];
ctx->h[4] = sha256_h0[4]; ctx->h[5] = sha256_h0[5];
ctx->h[6] = sha256_h0[6]; ctx->h[7] = sha256_h0[7];
#endif /* !UNROLL_LOOPS */

ctx->len = 0;
ctx->tot_len = 0;
}

void sha256_update(sha256_ctx *ctx, const uint8_t *message, uint64_t len)
{
uint64_t block_nb;
uint64_t new_len, rem_len, tmp_len;
const uint8_t *shifted_message;

tmp_len = SHA256_BLOCK_SIZE - ctx->len;
rem_len = len < tmp_len ? len : tmp_len;

memcpy(&ctx->block[ctx->len], message, rem_len);

if (ctx->len + len < SHA256_BLOCK_SIZE) {
ctx->len += len;
return;
}

new_len = len - rem_len;
block_nb = new_len / SHA256_BLOCK_SIZE;

shifted_message = message + rem_len;

sha256_transf(ctx, ctx->block, 1);
sha256_transf(ctx, shifted_message, block_nb);

rem_len = new_len % SHA256_BLOCK_SIZE;

memcpy(ctx->block, &shifted_message[block_nb << 6], rem_len);

ctx->len = rem_len;
ctx->tot_len += (block_nb + 1) << 6;
}

void sha256_final(sha256_ctx *ctx, uint8_t *digest)
{
uint64_t block_nb;
uint64_t pm_len;
uint64_t len_b;
uint64_t tot_len;

#ifndef UNROLL_LOOPS
int i;
#endif

block_nb = (1 + ((SHA256_BLOCK_SIZE - 9)
< (ctx->len % SHA256_BLOCK_SIZE)));

tot_len = ctx->tot_len + ctx->len;
ctx->tot_len = tot_len;

len_b = tot_len << 3;
pm_len = block_nb << 6;

memset(ctx->block + ctx->len, 0, pm_len - ctx->len);
ctx->block[ctx->len] = 0x80;
UNPACK64(len_b, ctx->block + pm_len - 8);

sha256_transf(ctx, ctx->block, block_nb);

#ifndef UNROLL_LOOPS
for (i = 0 ; i < 8; i++) {
UNPACK32(ctx->h[i], &digest[i << 2]);
}
#else
UNPACK32(ctx->h[0], &digest[ 0]);
UNPACK32(ctx->h[1], &digest[ 4]);
UNPACK32(ctx->h[2], &digest[ 8]);
UNPACK32(ctx->h[3], &digest[12]);
UNPACK32(ctx->h[4], &digest[16]);
UNPACK32(ctx->h[5], &digest[20]);
UNPACK32(ctx->h[6], &digest[24]);
UNPACK32(ctx->h[7], &digest[28]);
#endif /* !UNROLL_LOOPS */
}
62 changes: 62 additions & 0 deletions src/sha256/sha256.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* FIPS 180-2 256 implementation based on code by Oliver Gay
* under a BSD-style license. http://ouah.org/ogay/sha2/
*
* Copyright (C) 2005-2023 Olivier Gay <olivier.gay@a3.epfl.ch>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/

#ifndef SHA256_H
#define SHA256_H

#include <stdint.h>
#include <stddef.h>

#define SHA256_DIGEST_SIZE ( 256 / 8)
#define SHA256_BLOCK_SIZE ( 512 / 8)

#ifdef __cplusplus
extern "C" {
#endif

typedef struct {
uint64_t tot_len;
uint64_t len;
uint8_t block[2 * SHA256_BLOCK_SIZE];
uint32_t h[8];
} sha256_ctx;

void sha256_init(sha256_ctx * ctx);
void sha256_update(sha256_ctx *ctx, const uint8_t *message, uint64_t len);
void sha256_final(sha256_ctx *ctx, uint8_t *digest);
void sha256(const uint8_t *message, uint64_t len, uint8_t *digest);

#ifdef __cplusplus
}
#endif

#endif /* !SHA256_H */