Loading...
Searching...
No Matches
pico_sha256

SHA-256 Hardware Accelerated implementation. More...

Data Structures

struct  pico_sha256_state
 SHA-256 state used by the API. More...
 

Typedefs

typedef struct pico_sha256_state pico_sha256_state_t
 SHA-256 state used by the API.
 

Functions

void pico_sha256_cleanup (pico_sha256_state_t *state)
 Release the internal lock on the SHA-256 hardware.
 
int pico_sha256_try_start (pico_sha256_state_t *state, enum sha256_endianness endianness, bool use_dma)
 Start a SHA-256 calculation returning immediately with an error if the SHA-256 hardware is not available.
 
int pico_sha256_start_blocking_until (pico_sha256_state_t *state, enum sha256_endianness endianness, bool use_dma, absolute_time_t until)
 Start a SHA-256 calculation waiting for a defined period for the SHA-256 hardware to be available.
 
static int pico_sha256_start_blocking (pico_sha256_state_t *state, enum sha256_endianness endianness, bool use_dma)
 Start a SHA-256 calculation, blocking forever waiting until the SHA-256 hardware is available.
 
void pico_sha256_update (pico_sha256_state_t *state, const uint8_t *data, size_t data_size_bytes)
 Add byte data to be SHA-256 calculation.
 
void pico_sha256_update_blocking (pico_sha256_state_t *state, const uint8_t *data, size_t data_size_bytes)
 Add byte data to be SHA-256 calculation.
 
void pico_sha256_finish (pico_sha256_state_t *state, sha256_result_t *out)
 Finish the SHA-256 calculation and return the result.
 

Detailed Description

SHA-256 Hardware Accelerated implementation.

RP2350 is equipped with a hardware accelerated implementation of the SHA-256 hash algorithm. This should be much quicker than performing a SHA-256 checksum in software.

pico_sha256_update(&state, some_data, sizeof(some_data));
pico_sha256_update(&state, some_more_data, sizeof(some_more_data));
pico_sha256_finish(&state, &result);
for (int i = 0; i < SHA256_RESULT_BYTES; i++) {
printf("%02x", result.bytes[i]);
}
}
#define SHA256_RESULT_BYTES
Size of a sha256 result in bytes.
Definition sha256.h:44
@ SHA256_BIG_ENDIAN
Big Endian.
Definition sha256.h:51
@ PICO_OK
No error; the operation succeeded.
Definition error.h:23
void pico_sha256_update(pico_sha256_state_t *state, const uint8_t *data, size_t data_size_bytes)
Add byte data to be SHA-256 calculation.
Definition sha256.c:147
void pico_sha256_finish(pico_sha256_state_t *state, sha256_result_t *out)
Finish the SHA-256 calculation and return the result.
Definition sha256.c:177
int pico_sha256_try_start(pico_sha256_state_t *state, enum sha256_endianness endianness, bool use_dma)
Start a SHA-256 calculation returning immediately with an error if the SHA-256 hardware is not availa...
Definition sha256.c:39
SHA-256 state used by the API.
Definition sha256.h:48
SHA-256 result generated by the API.
Definition sha256.h:57

Example

#include <stdio.h>
#include <string.h>
// Include sys/types.h before inttypes.h to work around issue with
// certain versions of GCC and newlib which causes omission of PRIu64
#include <sys/types.h>
#include <inttypes.h>
#include <stdlib.h>
#include "pico/stdlib.h"
#include "pico/sha256.h"
// This was generated by cmake from sample.txt.inc
#include "sample.txt.inc"
static void sha_example() {
printf("Text: %d bytes\n", sizeof(sample_txt) - 1);
for(int i = 0; i < sizeof(sample_txt) - 1; i++) {
if (i > 0 && i % 128 == 0) printf("\n");
putchar(sample_txt[i]);
}
printf("\n");
// Allocate a state object and start the calculation
int rc = pico_sha256_start_blocking(&state, SHA256_BIG_ENDIAN, true); // using some DMA system resources
hard_assert(rc == PICO_OK);
pico_sha256_update_blocking(&state, (const uint8_t*)sample_txt, sizeof(sample_txt) - 1);
// Get the result of the sha256 calculation
pico_sha256_finish(&state, &result);
// print resulting sha256 result
printf("Result:\n");
for(int i = 0; i < SHA256_RESULT_BYTES; i++) {
printf("%02x ", result.bytes[i]);
if ((i+1) % 16 == 0) printf("\n");
}
// check it's what we expect from "sha256sum sample.txt"
const uint8_t sha_expected[SHA256_RESULT_BYTES] = {
0x2d, 0x8c, 0x2f, 0x6d, 0x97, 0x8c, 0xa2, 0x17, 0x12, 0xb5, 0xf6, 0xde, 0x36, 0xc9, 0xd3, 0x1f,
0xa8, 0xe9, 0x6a, 0x4f, 0xa5, 0xd8, 0xff, 0x8b, 0x01, 0x88, 0xdf, 0xb9, 0xe7, 0xc1, 0x71, 0xbb
};
hard_assert(memcmp(sha_expected, &result, SHA256_RESULT_BYTES) == 0);
}
#define BUFFER_SIZE 10000
// A performance test with a large amount of data
static void nist_test(bool use_dma) {
// nist 3
uint8_t *buffer = malloc(BUFFER_SIZE);
memset(buffer, 0x61, BUFFER_SIZE);
const uint8_t nist_3_expected[] = { \
0xcd, 0xc7, 0x6e, 0x5c, 0x99, 0x14, 0xfb, 0x92, 0x81, 0xa1, 0xc7, 0xe2, 0x84, 0xd7, 0x3e, 0x67,
0xf1, 0x80, 0x9a, 0x48, 0xa4, 0x97, 0x20, 0x0e, 0x04, 0x6d, 0x39, 0xcc, 0xc7, 0x11, 0x2c, 0xd0 };
uint64_t start = time_us_64();
int rc = pico_sha256_start_blocking(&state, SHA256_BIG_ENDIAN, use_dma); // call start once
hard_assert(rc == PICO_OK);
for(int i = 0; i < 1000000; i += BUFFER_SIZE) {
pico_sha256_update_blocking(&state, buffer, BUFFER_SIZE); // call update as many times as required
}
pico_sha256_finish(&state, &result); // Call finish when done to get the result
// Display the time taken
uint64_t pico_time = time_us_64() - start;
printf("Time for sha256 of 1M bytes %s DMA %"PRIu64"ms\n", use_dma ? "with" : "without", pico_time / 1000);
hard_assert(memcmp(nist_3_expected, result.bytes, SHA256_RESULT_BYTES) == 0);
}
int main() {
sha_example();
// performance test with and without DMA
nist_test(false);
nist_test(true);
printf("Success\n");
}
uint64_t time_us_64(void)
Return the current 64 bit timestamp value in microseconds for the default timer instance.
Definition timer.c:125
void pico_sha256_update_blocking(pico_sha256_state_t *state, const uint8_t *data, size_t data_size_bytes)
Add byte data to be SHA-256 calculation.
Definition sha256.c:151
static int pico_sha256_start_blocking(pico_sha256_state_t *state, enum sha256_endianness endianness, bool use_dma)
Start a SHA-256 calculation, blocking forever waiting until the SHA-256 hardware is available.
Definition sha256.h:109
bool stdio_init_all(void)
Initialize all of the present standard stdio types that are linked into the binary.
Definition stdio.c:207

Function Documentation

◆ pico_sha256_cleanup()

void pico_sha256_cleanup ( pico_sha256_state_t *  state)

Release the internal lock on the SHA-256 hardware.

Release the internal lock on the SHA-256 hardware. Does nothing if the internal lock was not claimed.

Parameters
stateA pointer to a pico_sha256_state_t instance

◆ pico_sha256_finish()

void pico_sha256_finish ( pico_sha256_state_t *  state,
sha256_result_t *  out 
)

Finish the SHA-256 calculation and return the result.

Ends the SHA-256 calculation freeing the hardware for use by another caller. You must have called pico_sha256_try_start already.

Parameters
stateA pointer to a pico_sha256_state_t instance
outThe SHA-256 checksum

◆ pico_sha256_start_blocking()

static int pico_sha256_start_blocking ( pico_sha256_state_t *  state,
enum sha256_endianness  endianness,
bool  use_dma 
)
inlinestatic

Start a SHA-256 calculation, blocking forever waiting until the SHA-256 hardware is available.

Initialises the hardware and state ready to start a new SHA-256 calculation. Only one instance can be started at any time.

Parameters
stateA pointer to a pico_sha256_state_t instance
endiannessSHA256_BIG_ENDIAN or SHA256_LITTLE_ENDIAN for data in and data out
use_dmaSet to true to use DMA internally to copy data to hardware. This is quicker at the expense of hardware DMA resources.
Returns
Returns PICO_OK if the hardware was available for use and the sha256 calculation could be started, otherwise an error is returned

◆ pico_sha256_start_blocking_until()

int pico_sha256_start_blocking_until ( pico_sha256_state_t *  state,
enum sha256_endianness  endianness,
bool  use_dma,
absolute_time_t  until 
)

Start a SHA-256 calculation waiting for a defined period for the SHA-256 hardware to be available.

Initialises the hardware and state ready to start a new SHA-256 calculation. Only one instance can be started at any time.

Parameters
stateA pointer to a pico_sha256_state_t instance
endiannessSHA256_BIG_ENDIAN or SHA256_LITTLE_ENDIAN for data in and data out
use_dmaSet to true to use DMA internally to copy data to hardware. This is quicker at the expense of hardware DMA resources.
untilHow long to wait for the SHA hardware to be available
Returns
Returns PICO_OK if the hardware was available for use and the sha256 calculation could be started in time, otherwise an error is returned

◆ pico_sha256_try_start()

int pico_sha256_try_start ( pico_sha256_state_t *  state,
enum sha256_endianness  endianness,
bool  use_dma 
)

Start a SHA-256 calculation returning immediately with an error if the SHA-256 hardware is not available.

Initialises the hardware and state ready to start a new SHA-256 calculation. Only one instance can be started at any time.

Parameters
stateA pointer to a pico_sha256_state_t instance
endiannessSHA256_BIG_ENDIAN or SHA256_LITTLE_ENDIAN for data in and data out
use_dmaSet to true to use DMA internally to copy data to hardware. This is quicker at the expense of hardware DMA resources.
Returns
Returns PICO_OK if the hardware was available for use and the sha256 calculation could be started, otherwise an error is returned

◆ pico_sha256_update()

void pico_sha256_update ( pico_sha256_state_t *  state,
const uint8_t *  data,
size_t  data_size_bytes 
)

Add byte data to be SHA-256 calculation.

Add byte data to be SHA-256 calculation You may call this as many times as required to add all the data needed. You must have called pico_sha256_try_start (or equivalent) already.

Parameters
stateA pointer to a pico_sha256_state_t instance
dataPointer to the data to be added to the calculation
data_size_bytesAmount of data to add
Note
This function may return before the copy has completed in which case the data passed to the function must remain valid and unchanged until a further call to pico_sha256_update or pico_sha256_finish. If this is not done, corrupt data may be used for the SHA-256 calculation giving an unexpected result.

◆ pico_sha256_update_blocking()

void pico_sha256_update_blocking ( pico_sha256_state_t *  state,
const uint8_t *  data,
size_t  data_size_bytes 
)

Add byte data to be SHA-256 calculation.

Add byte data to be SHA-256 calculation You may call this as many times as required to add all the data needed. You must have called pico_sha256_try_start already.

Parameters
stateA pointer to a pico_sha256_state_t instance
dataPointer to the data to be added to the calculation
data_size_bytesAmount of data to add
Note
This function will only return when the data passed in is no longer required, so it can be freed or changed on return.