Commit f8b9564e by Sebastian Renner

Doc aka. my road of pain for the gapuino integration

parent f1a11334
# User Test # User Test
#------------------------------------------ #------------------------------------------
# Uncomment this to (try to) use the flash
#PLPBRIDGE_FLAGS += -f -hyper
INC += include/ INC += include/
VPATH = src/ VPATH = src/
TEST_CXX = main.cpp TEST_CXX = main.cpp
...@@ -17,4 +21,5 @@ TEST_C = uartp.c \ ...@@ -17,4 +21,5 @@ TEST_C = uartp.c \
# recordWlf=YES # recordWlf=YES
# vsimDo="-do ~/wave_uart.do" # vsimDo="-do ~/wave_uart.do"
include $(GAP_SDK_HOME)/tools/rules/mbed_rules.mk include $(GAP_SDK_HOME)/tools/rules/mbed_rules.mk
## How to have fun with the GAPuino on Linux
In general, follow this README: https://github.com/GreenWaves-Technologies/gap_sdk/blob/master/README.md
PLUS
### Fix the -Werror flag to make openocd compile
Comment this line in gap_sdk/tools/gap8-openocd
`GCC_WARNINGS="${GCC_WARNINGS} -Werror"`
### Fix libmpfr version bug
`sudo ln -s /usr/lib/libmpfr.so.6 /usr/lib/libmpfr.so.4`
### Fix bug in load_jtag_hyper function
* Grep for `load_jtag_hyper` in the source directory of the SDK
* Make sure all function definitions have the signature `load_jtag_hyper(self)`
### Enable hyperflash boot
* This is supposed to be a one-time operation
* Run the following commands
`source ~/gap_sdk/configs/gapuino_v2.sh`
`openocd -f interface/ftdi/gapuino_ftdi.cfg -f target/gap8revb.tcl -f ./tcl/jtag_boot.tcl -f ./tcl/fuser.tcl`
* Open a second terminal and continue with
`source ~/gap_sdk/configs/gapuino_v2.sh`
`telnet localhost 4444`
* In the openocd terminal run (adapt path to directory if necessary)
`fuse_hyperflash_boot /home/$USER/gap_sdk/tools/gap8-openocd-tools`
* Unplug the gapuino, it SHOULD now boot from hyperflash
* Add `PLPBRIDGE_FLAGS += -f -hyper` to your Makefile
* I could only boot from flash, when I hit `make` and the `openocd` command after every flash
/*
TinyJAMBU-256: 256-bit key, 96-bit IV
Reference Implementation for 32-bit processor
The state consists of four 32-bit registers
state[3] || state[2] || state[1] || state[0]
Implemented by Hongjun Wu
*/
#include <string.h>
#include <stdio.h>
#include "crypto_aead.h"
#define FrameBitsIV 0x10
#define FrameBitsAD 0x30
#define FrameBitsPC 0x50 //Framebits for plaintext/ciphertext
#define FrameBitsFinalization 0x70
#define NROUND1 128*3
#define NROUND2 128*10
/*non-optimized state update function*/
void state_update(unsigned int *state, const unsigned char *key, unsigned int number_of_steps)
{
unsigned int i;
unsigned int t1, t2, t3, t4, feedback;
//in each iteration, we compute 256 steps of the state update function.
for (i = 0; i < (number_of_steps >> 5); i++)
{
t1 = (state[1] >> 15) | (state[2] << 17); // 47 = 1*32+15
t2 = (state[2] >> 6) | (state[3] << 26); // 47 + 23 = 70 = 2*32 + 6
t3 = (state[2] >> 21) | (state[3] << 11); // 47 + 23 + 15 = 85 = 2*32 + 21
t4 = (state[2] >> 27) | (state[3] << 5); // 47 + 23 + 15 + 6 = 91 = 2*32 + 27
feedback = state[0] ^ t1 ^ (~(t2 & t3)) ^ t4 ^ ((unsigned int*)key)[i & 7];
// shift 32 bit positions
state[0] = state[1]; state[1] = state[2]; state[2] = state[3];
state[3] = feedback;
}
}
// The initialization
/* The input to initialization is the 128-bit key; 96-bit IV;*/
void initialization(const unsigned char *key, const unsigned char *iv, unsigned int *state)
{
int i;
//initialize the state as 0
for (i = 0; i < 4; i++) state[i] = 0;
//update the state with the key
state_update(state, key, NROUND2);
//introduce IV into the state
for (i = 0; i < 3; i++)
{
state[1] ^= FrameBitsIV;
state_update(state, key, NROUND1);
state[3] ^= ((unsigned int*)iv)[i];
}
}
//process the associated data
void process_ad(const unsigned char *k, const unsigned char *ad, unsigned long long adlen, unsigned int *state)
{
unsigned long long i;
unsigned int j;
for (i = 0; i < (adlen >> 2); i++)
{
state[1] ^= FrameBitsAD;
state_update(state, k, NROUND1);
state[3] ^= ((unsigned int*)ad)[i];
}
// if adlen is not a multiple of 4, we process the remaining bytes
if ((adlen & 3) > 0)
{
state[1] ^= FrameBitsAD;
state_update(state, k, NROUND1);
for (j = 0; j < (adlen & 3); j++) ((unsigned char*)state)[12 + j] ^= ad[(i << 2) + j];
state[1] ^= adlen & 3;
}
}
//encrypt a message
int crypto_aead_encrypt(
unsigned char *c,unsigned long long *clen,
const unsigned char *m,unsigned long long mlen,
const unsigned char *ad,unsigned long long adlen,
const unsigned char *nsec,
const unsigned char *npub,
const unsigned char *k
)
{
unsigned long long i;
unsigned int j;
unsigned char mac[8];
unsigned int state[4];
//initialization stage
initialization(k, npub, state);
//process the associated data
process_ad(k, ad, adlen, state);
//process the plaintext
for (i = 0; i < (mlen >> 2); i++)
{
state[1] ^= FrameBitsPC;
state_update(state, k, NROUND2);
state[3] ^= ((unsigned int*)m)[i];
((unsigned int*)c)[i] = state[2] ^ ((unsigned int*)m)[i];
}
// if mlen is not a multiple of 4, we process the remaining bytes
if ((mlen & 3) > 0)
{
state[1] ^= FrameBitsPC;
state_update(state, k, NROUND2);
for (j = 0; j < (mlen & 3); j++)
{
((unsigned char*)state)[12 + j] ^= m[(i << 2) + j];
c[(i << 2) + j] = ((unsigned char*)state)[8 + j] ^ m[(i << 2) + j];
}
state[1] ^= mlen & 3;
}
//finalization stage, we assume that the tag length is 8 bytes
state[1] ^= FrameBitsFinalization;
state_update(state, k, NROUND2);
((unsigned int*)mac)[0] = state[2];
state[1] ^= FrameBitsFinalization;
state_update(state, k, NROUND1);
((unsigned int*)mac)[1] = state[2];
*clen = mlen + 8;
memcpy(c + mlen, mac, 8);
return 0;
}
//decrypt a message
int crypto_aead_decrypt(
unsigned char *m,unsigned long long *mlen,
unsigned char *nsec,
const unsigned char *c,unsigned long long clen,
const unsigned char *ad,unsigned long long adlen,
const unsigned char *npub,
const unsigned char *k
)
{
unsigned long long i;
unsigned int j, check = 0;
unsigned char mac[8];
unsigned int state[4];
*mlen = clen - 8;
//initialization stage
initialization(k, npub, state);
//process the associated data
process_ad(k, ad, adlen, state);
//process the ciphertext
for (i = 0; i < (*mlen >> 2); i++)
{
state[1] ^= FrameBitsPC;
state_update(state, k, NROUND2);
((unsigned int*)m)[i] = state[2] ^ ((unsigned int*)c)[i];
state[3] ^= ((unsigned int*)m)[i];
}
// if mlen is not a multiple of 4, we process the remaining bytes
if ((*mlen & 3) > 0)
{
state[1] ^= FrameBitsPC;
state_update(state, k, NROUND2);
for (j = 0; j < (*mlen & 3); j++)
{
m[(i << 2) + j] = c[(i << 2) + j] ^ ((unsigned char*)state)[8 + j];
((unsigned char*)state)[12 + j] ^= m[(i << 2) + j];
}
state[1] ^= *mlen & 3;
}
//finalization stage, we assume that the tag length is 8 bytes
state[1] ^= FrameBitsFinalization;
state_update(state, k, NROUND2);
((unsigned int*)mac)[0] = state[2];
state[1] ^= FrameBitsFinalization;
state_update(state, k, NROUND1);
((unsigned int*)mac)[1] = state[2];
//verification of the authentication tag
for (j = 0; j < 8; j++) { check |= (mac[j] ^ c[clen - 8 + j]); }
if (check == 0) return 0;
else return -1;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment