Usage with Arduino¶
Contents
General¶
Optimization and Disabling Code Objects¶
Code objects eat up your precious flash memory. It is therefore important to disable all the code you do not need.
This can be done using the file config.h in the library
folder of cryptosuite2. This file includes the module
configuration first so you can overwrite the module
configuration.
The first thing one should do is to disable modules you do
not need. This is done by defining SHA256_DISABLED or
SHA1_DISABLED. All code for these modules will then be
excluded.
Also you can disable HMAC to save both flash memory and
RAM using #undef SHA256_ENABLE_HMAC and
#undef SHA1_ENABLE_HMAC.
The last thing one can do is to disable the C++
interface (see the sections below about how to use the C
interface) by defining SHA256_DISABLE_WRAPPER and
SHA1_DISABLE_WRAPPER.
Sha256¶
Simple Usage¶
cryptosuite2 brings a C++ interface that can be used by Arduino users easily.
After including the header one can use the class
Sha256Wrapper with the methods
init(void): voidInitializes the
Sha256Wrapperfor hashing. Must be invoked before hashing.result(void): uint8_t *Returns a reference to the hash. Once this method has been called
initmust be invoked again.write(various types): size_tWrite data into the hasher.
If the preprocessor macro SHA256_ENABLE_HMAC in
config.h is set (which it is by default) 1 the
following methods are available:
initHmac(const uint8_t * secret, unsigned int secretLength): voidInitializes the
Sha256Wrapperfor HMAC.resultHmac(void): uint8_t *Returns a reference to the hash. Once this method has been called
initmust be invoked again.
sha256.h also brings a global hasher: Sha256.
Example:
#include "sha256.h"
// read data from the serial interface and print the
// hash to the serial
void setup(void)
{
Serial.begin(9600);
}
void loop(void)
{
if(!Serial.available())
{
return;
}
Sha256.init();
Sha256.print(Serial.read());
uint8_t * result = Sha256.result();
Serial.print("Hash:\n");
for (int i = 0; i < 32; i++) {
Serial.print("0123456789abcdef"[result[i] >> 4]);
Serial.print("0123456789abcdef"[result[i] & 0xf]);
}
Serial.print("\n");
}
The same way HMAC can be used:
#include "sha256.h"
void setup(void)
{
Serial.begin(9600);
// this is actually the RFC4231 4.3 test
Sha256.initHmac((uint8_t * ) "Jefe", 4);
Sha256.print("what do ya want for nothing?");
uint8_t * result = Sha256.resultHmac();
Serial.println("Expect: 5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843");
Serial.print( "Got : ");
for (int i = 0; i < 32; i++) {
Serial.print("0123456789abcdef"[result[i] >> 4]);
Serial.print("0123456789abcdef"[result[i] & 0xf]);
}
Serial.print("\n");
}
void loop(void)
{}
Extended¶
Disabling the C++ Wrapper¶
The C++ wrapper increases the overhead and eats up some
RAM. So one can disable the wrapper by defining
SHA256_DISABLE_WRAPPER in config.h
#define SHA256_DISABLE_WRAPPER
Instantiating a new Hasher¶
A new hasher can be created by calling sha256_hasher_new:
#define SHA256_DISABLE_WRAPPER
#include "sha256.h"
sha256_hasher_t hasher;
void setup(void)
{
hasher = sha256_hasher_new();
Serial.begin(9600);
}
Writing to the Hasher¶
Before one writes to the hasher he should invoke
sha256_hasher_init, although this function has been
called by sha256_hasher_new. Then he can write safely:
void loop(void)
{
sha256_hasher_init(hasher);
sha256_hasher_write(hasher, "abc", 3);
}
Obtaining the Result and free’ing the Hasher¶
void loop(void)
{
sha256_hasher_init(hasher);
sha256_hasher_write(hasher, "abc", 3);
uint8_t * result;
result = sha256_hasher_gethash(hasher);
Serial.print("EXPECT: ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad\n");
Serial.print("GOT : ");
for (int i = 0; i < 32; i++) {
Serial.print("0123456789abcdef"[result[i] >> 4]);
Serial.print("0123456789abcdef"[result[i] & 0xf]);
}
Serial.print("\n");
// do not actually delete the hasher
// we are inside loop
// sha256_hasher_del(hasher);
}
API Doc¶
sha256_hasher_new(void): sha256_hasher_tAllocate and initialize a new hasher.
sha256_hasher_del(sha256_hasher_t hasher): voidFree the hasher.
sha256_hasher_init(sha256_hasher_t hasher)(Re-) Initialize the hasher for hashing.
sha256_hasher_putc(sha256_hasher_t hasher, uint8_t byte): intPut
byteto the hasher. Follows the standardputcconventions.sha256_hasher_gethash(sha256_hasher_t hasher): uint8_t *Returns a reference of the hash. One must not free the result. This modifies the state of the hasher. Once this function has been called,
sha256_hasher_initmust be invoked orsha256_hasher_putcwill fail.sha256_hasher_write(sha256_hasher_t hasher, const void * buf, size_t count): ssize_tWrites to the hasher. Follows the standard
writeconventions and usessha256_hasher_putc.
If SHA256_ENABLE_HMAC is defined in config.h
also the following functions are available:
sha256_hasher_init_hmac(sha256_hasher_t hasher, const uint8_t * key, size_t key_len): voidInitialize the hasher for HMAC. Invokes
sha256_hasher_init.sha256_hasher_gethmac(sha256_hasher_t hasher): uint8_t *Returns a reference of the hash. One must not free the result. This modifies the state of the hasher. Once this function has been called,
sha256_hasher_initmust be invoked orsha256_hasher_putcwill fail.
Sha1¶
Simple Usage¶
cryptosuite2 brings a C++ interface that can be used by Arduino users easily.
After including the header one can use the class
Sha1Wrapper with the methods
init(void): voidInitializes the
Sha1Wrapperfor hashing. Must be invoked before hashing.result(void): uint8_t *Returns a reference to the hash. Once this method has been called
initmust be invoked again.write(various types): size_tWrite data into the hasher.
If the preprocessor macro SHA1_ENABLE_HMAC in
config.h is set (which it is by default) 1 the
following methods are available:
initHmac(const uint8_t * secret, unsigned int secretLength): voidInitializes the
Sha1Wrapperfor HMAC.resultHmac(void): uint8_t *Returns a reference to the hash. Once this method has been called
initmust be invoked again.
sha1.h also brings a global hasher: Sha1.
Example:
#include "sha1.h"
// read data from the serial interface and print the
// hash to the serial
void setup(void)
{
Serial.begin(9600);
}
void loop(void)
{
if(!Serial.available())
{
return;
}
Sha1.init();
Sha1.print(Serial.read());
uint8_t * result = Sha1.result();
Serial.print("Hash:\n");
for (int i = 0; i < 10; i++) {
Serial.print("0123456789abcdef"[result[i] >> 4]);
Serial.print("0123456789abcdef"[result[i] & 0xf]);
}
Serial.print("\n");
}
The same way HMAC can be used:
#include "sha1.h"
void setup(void)
{
Serial.begin(9600);
// this is actually the RFC4231 4.3 test
Sha1.initHmac((uint8_t * ) "Jefe", 4);
Sha1.print("what do ya want for nothing?");
uint8_t * result = Sha1.resultHmac();
Serial.println("Expect: b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7");
Serial.print( "Got : ");
for (int i = 0; i < 10; i++) {
Serial.print("0123456789abcdef"[result[i] >> 4]);
Serial.print("0123456789abcdef"[result[i] & 0xf]);
}
Serial.print("\n");
}
void loop(void)
{}
Extended¶
Disabling the C++ Wrapper¶
The C++ wrapper increases the overhead and eats up some
RAM. So one can disable the wrapper by defining
SHA1_DISABLE_WRAPPER in config.h:
#define SHA1_DISABLE_WRAPPER
Instantiating a new Hasher¶
A new hasher can be created by calling sha1_hasher_new:
#define SHA1_DISABLE_WRAPPER
#include "sha1.h"
sha1_hasher_t hasher;
void setup(void)
{
hasher = sha1_hasher_new();
Serial.begin(9600);
}
Writing to the Hasher¶
Before one writes to the hasher he should invoke
sha1_hasher_init, although this function has been
called by sha1_hasher_new. Then he can write safely:
void loop(void)
{
sha1_hasher_init(hasher);
sha1_hasher_write(hasher, "abc", 3);
}
Obtaining the Result and free’ing the Hasher¶
void loop(void)
{
sha1_hasher_init(hasher);
sha1_hasher_write(hasher, "abc", 3);
uint8_t * result;
result = sha1_hasher_gethash(hasher);
Serial.print("EXPECT: ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad\n");
Serial.print("GOT : ");
for (int i = 0; i < 10; i++) {
Serial.print("0123456789abcdef"[result[i] >> 4]);
Serial.print("0123456789abcdef"[result[i] & 0xf]);
}
Serial.print("\n");
// do not actually delete the hasher
// we are inside loop
// sha1_hasher_del(hasher);
}
API Doc¶
sha1_hasher_new(void): sha1_hasher_tAllocate and initialize a new hasher.
sha1_hasher_del(sha1_hasher_t hasher): voidFree the hasher.
sha1_hasher_init(sha1_hasher_t hasher)(Re-) Initialize the hasher for hashing.
sha1_hasher_putc(sha1_hasher_t hasher, uint8_t byte): intPut
byteto the hasher. Follows the standardputcconventions.sha1_hasher_gethash(sha1_hasher_t hasher): uint8_t *Returns a reference of the hash. One must not free the result. This modifies the state of the hasher. Once this function has been called,
sha1_hasher_initmust be invoked orsha1_hasher_putcwill fail.sha1_hasher_write(sha1_hasher_t hasher, const void * buf, size_t count): ssize_tWrites to the hasher. Follows the standard
writeconventions and usessha1_hasher_putc.
If SHA1_ENABLE_HMAC is defined in config.h
also the following functions are available:
sha1_hasher_init_hmac(sha1_hasher_t hasher, const uint8_t * key, size_t key_len): voidInitialize the hasher for HMAC. Invokes
sha1_hasher_init.sha1_hasher_gethmac(sha1_hasher_t hasher): uint8_t *Returns a reference of the hash. One must not free the result. This modifies the state of the hasher. Once this function has been called,
sha1_hasher_initmust be invoked orsha1_hasher_putcwill fail.