Min 6 anni fa
commit
15319e5590
7 ha cambiato i file con 460 aggiunte e 0 eliminazioni
  1. 1 0
      .gitignore
  2. 125 0
      Makefile
  3. 119 0
      crypto.c
  4. 32 0
      crypto.h
  5. 79 0
      rng.c
  6. 19 0
      rng.h
  7. 85 0
      tracker.cpp

+ 1 - 0
.gitignore

@@ -0,0 +1 @@
+build/

+ 125 - 0
Makefile

@@ -0,0 +1,125 @@
+# default energia software directory, check software exists
+ifndef ENERGIADIR
+ENERGIADIR := $(firstword $(wildcard ~/energia /usr/share/energia /opt/energia))
+endif
+ifeq "$(wildcard $(ENERGIADIR)/hardware/msp430/boards.txt)" ""
+$(error ENERGIADIR is not set correctly; energia software not found)
+endif
+
+# default versions
+ARDUINOCONST ?= 101
+ENERGIACONST ?= 17
+
+TOOLDIR := $(ENERGIADIR)/hardware/tools/lm4f/bin
+COMPILER := $(TOOLDIR)/arm-none-eabi
+UPLOADER := $(TOOLDIR)/cc3200prog
+BOARD := cc3200
+ENERGIABOARD := lpcc3200
+SERIALDEV := /dev/serial/by-id/usb-FTDI_USB__-__JTAG_SWD_cc3101-if01-port0
+# Compiled files output
+BUILDDIR := build
+SRCDIR := .
+# Project name
+NAME := tracker
+
+
+### LOADING BOARD PARAMETERS
+BOARDS_FILE := $(ENERGIADIR)/hardware/$(BOARD)/boards.txt
+BOARD_BUILD_MCU 	:= $(shell sed -ne "s/$(ENERGIABOARD).build.mcu=\(.*\)/\1/p" $(BOARDS_FILE))
+BOARD_BUILD_FCPU 	:= $(shell sed -ne "s/$(ENERGIABOARD).build.f_cpu=\(.*\)/\1/p" $(BOARDS_FILE))
+BOARD_BUILD_VARIANT 	:= $(shell sed -ne "s/$(ENERGIABOARD).build.variant=\(.*\)/\1/p" $(BOARDS_FILE))
+BOARD_UPLOAD_SPEED 	:= $(shell sed -ne "s/$(ENERGIABOARD).upload.speed=\(.*\)/\1/p" $(BOARDS_FILE))
+BOARD_UPLOAD_PROTOCOL 	:= $(shell sed -ne "s/$(ENERGIABOARD).upload.protocol=\(.*\)/\1/p" $(BOARDS_FILE))
+BOARD_FLASH_SIZE 	:= $(shell sed -ne "s/$(ENERGIABOARD).upload.maximum_size=\(.*\)/\1/p" $(BOARDS_FILE))
+BOARD_LDSCRIPT 		:= $(shell sed -ne "s/$(ENERGIABOARD).ldscript=\(.*\)/\1/p" $(BOARDS_FILE))
+
+### DIRECTORY STRUCTURE
+ENERGIALIB := $(ENERGIADIR)/hardware/$(BOARD)/libraries
+VARIANTLIB := $(ENERGIADIR)/hardware/$(BOARD)/variants/$(BOARD_BUILD_VARIANT)
+COREDIR := $(ENERGIADIR)/hardware/$(BOARD)/cores/$(BOARD)
+CORELIB := $(BUILDDIR)/core.a
+SOURCES := $(wildcard *.c *.cc *.cpp)
+LIBDIRS := $(COREDIR) $(COREDIR)/driverlib $(COREDIR)/avr
+
+LIBSOURCES := $(foreach dir, $(LIBDIRS),  $(wildcard $(addprefix $(dir)/, *.c *.cpp)))
+SRCOBJS = $(addprefix $(BUILDDIR)/, $(notdir $(addsuffix .o, $(SOURCES))))
+LIBOBJS = $(addprefix $(BUILDDIR)/, $(notdir $(addsuffix .o, $(LIBSOURCES))))
+OBJECTS = $(addprefix $(BUILDDIR)/, $(notdir $(addsuffix .o, $(SOURCES) $(LIBSOURCES))))
+
+VPATH = $(LIBDIRS) $(SRCDIR)
+
+BIN := $(BUILDDIR)/$(NAME).bin
+EFI := $(BUILDDIR)/$(NAME).efi
+
+### COMPILER OPTIONS
+CC := $(COMPILER)-gcc
+CXX := $(COMPILER)-g++
+LD := $(COMPILER)-ld
+AR := $(COMPILER)-ar
+OBJCOPY := $(COMPILER)-objcopy
+GDB := $(COMPILER)-gdb
+SIZE := $(COMPILER)-size
+
+CFLAGS := -c -Os -Wall -ffunction-sections -fdata-sections -mthumb
+CFLAGS += -mcpu=$(BOARD_BUILD_MCU) -DF_CPU=$(BOARD_BUILD_FCPU) -MMD -DARDUINO=$(ARDUINOCONST) -DENERGIA=$(ENERGIACONST)
+CXXFLAGS := -c -Os -Wall -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections -mthumb
+CXXFLAGS += -mcpu=$(BOARD_BUILD_MCU) -DF_CPU=$(BOARD_BUILD_FCPU) -MMD -DARDUINO=$(ARDUINOCONST) -DENERGIA=$(ENERGIACONST)
+LINKFLAGS := -Os -nostartfiles -nostdlib -Wl,--gc-sections -T$(COREDIR)/$(BOARD_LDSCRIPT) -Wl,--entry=ResetISR -mthumb -mcpu=$(BOARD_BUILD_MCU)
+
+### INCLUDES AND LIBRARIES
+INCLUDES := -I$(COREDIR) -I$(VARIANTLIB) -I$(ENERGIALIB)
+
+# default rule
+.DEFAULT_GOAL := all
+#_______________________________________________________________________________
+#                                                                          RULES
+
+.PHONY:	all binary upload clean boards monitor size
+
+all: binary
+
+binary: $(BIN)
+
+upload: binary size
+	@echo "Uploading to board..."
+	$(UPLOADER) $(SERIALDEV) $(BIN)
+
+
+clean:
+	rm -irf $(BUILDDIR) 
+
+boards:
+	@echo Available values for BOARD:
+	@sed -ne '/^#/d; /^[^.]\+\.name=/p' $(BOARDS_FILE) | \
+		sed -e 's/\([^.]\+\)\.name=\(.*\)/\1            \2/' \
+			-e 's/\(.\{14\}\) *\(.*\)/\1 \2/'
+
+monitor:
+	@echo Escape typing ~.
+	cu -s 9600 -l /dev/ttyUSB0 $(SERIALDEV)
+
+size: $(EFI)
+	$(info Binary sketch size: $(word 7, $(shell $(SIZE) $(EFI))) bytes (of a $(BOARD_FLASH_SIZE) byte maximum))
+
+
+# building the target
+$(BIN): $(EFI)
+	@mkdir -p $(BUILDDIR)
+	$(OBJCOPY) -O binary $< $@
+
+$(EFI): $(CORELIB)
+	@mkdir -p $(BUILDDIR)
+	$(CXX) $(LINKFLAGS) $(SRCOBJS) $< -L$(BUILDDIR) -lm -lc -lgcc -o $@
+
+$(CORELIB): $(OBJECTS)
+	@mkdir -p $(BUILDDIR)
+	$(AR) rcs $@ $(LIBOBJS)
+
+$(BUILDDIR)/%.c.o: %.c
+	@mkdir -p $(BUILDDIR)
+	$(CC) $(CFLAGS) $(INCLUDES) $< -o $@
+
+$(BUILDDIR)/%.cpp.o: %.cpp
+	@mkdir -p $(BUILDDIR)
+	$(CXX) $(CXXFLAGS) $(INCLUDES) $< -o $@
+

+ 119 - 0
crypto.c

@@ -0,0 +1,119 @@
+
+#include "crypto.h"
+#include "rng.h"
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "inc/hw_types.h"
+#include "inc/hw_aes.h"
+#include "inc/hw_memmap.h"
+
+#include "driverlib/aes.h"
+#include "driverlib/rom_map.h"
+#include "driverlib/prcm.h"
+
+
+static volatile bool g_bContextInIntFlag;
+static volatile bool g_bDataInIntFlag;
+static volatile bool g_bContextOutIntFlag;
+static volatile bool g_bDataOutIntFlag;
+
+static uint32_t aes_mode=AES_CFG_MODE_CBC, aes_key_size, aes_blocksize;
+static uint8_t *aes_key;
+
+void AESCrypt(uint32_t dir, uint8_t *iv,
+              uint8_t *data, uint8_t *result,
+              uint32_t dataLength) {
+    // Step1:  Enable Interrupts
+    // Step2:  Wait for Context Ready Interrupt
+    // Step3:  Set the Configuration Parameters (Direction,AES Mode and Key Size)
+    // Step4:  Set the Initialisation Vector
+    // Step5:  Write Key
+    // Step6:  Start the crypt process
+
+    // Clear the flags.
+    g_bContextInIntFlag = false;
+    g_bDataInIntFlag = false;
+    g_bContextOutIntFlag = false;
+    g_bDataOutIntFlag = false;
+
+    // Enable all interrupts.
+    MAP_AESIntEnable(AES_BASE, AES_INT_CONTEXT_IN | AES_INT_CONTEXT_OUT | AES_INT_DATA_IN | AES_INT_DATA_OUT);
+    // Wait for the context in flag, the flag will be set in the Interrupt handler.
+    while(!g_bContextInIntFlag) {}
+    MAP_AESConfigSet(AES_BASE, dir | aes_mode | aes_key_size);
+    MAP_AESIVSet(AES_BASE, iv);
+    MAP_AESKey1Set(AES_BASE, aes_key, aes_key_size);
+    MAP_AESDataProcess(AES_BASE, (unsigned char *) data, (unsigned char *) result, dataLength);
+}
+
+uint8_t * AESEncrypt(uint8_t *message, uint32_t messageLength) {
+    uint32_t msgLen = messageLength + aes_blocksize;
+    uint32_t ivblocks = aes_blocksize/4;
+    uint8_t *result = (uint8_t *) malloc(msgLen);
+    uint32_t *IVrand = (uint32_t *) result;
+    uint8_t *data = &result[aes_blocksize];
+    int i;
+    for(i=0;i<ivblocks;i++) {
+        IVrand[i] = random();
+    }
+    AESCrypt(AES_DIR_ENCRYPT, result, message, data, messageLength);
+    return result;
+}
+
+// Message must be larger than 2 * aes_key_length (in bytes)
+uint8_t * AESDecrypt(uint8_t *message, uint32_t messageLength) {
+    uint8_t *data = &message[aes_blocksize];
+    uint32_t msgLen = messageLength - aes_blocksize;
+    uint8_t *result = (uint8_t *) malloc(msgLen);
+    AESCrypt(AES_DIR_DECRYPT, message, data, result, msgLen);
+    return result;
+}
+
+void AESIntHandler(void){
+    uint32_t uiIntStatus;
+    // Read the AES masked interrupt status.
+    uiIntStatus = MAP_AESIntStatus(AES_BASE, true);
+
+    // Set Different flags depending on the interrupt source.
+    if(uiIntStatus & AES_INT_CONTEXT_IN) {
+        MAP_AESIntDisable(AES_BASE, AES_INT_CONTEXT_IN);
+        g_bContextInIntFlag = true;
+    }
+    if(uiIntStatus & AES_INT_DATA_IN) {
+        MAP_AESIntDisable(AES_BASE, AES_INT_DATA_IN);
+        g_bDataInIntFlag = true;
+    }
+    if(uiIntStatus & AES_INT_CONTEXT_OUT) {
+        MAP_AESIntDisable(AES_BASE, AES_INT_CONTEXT_OUT);
+        g_bContextOutIntFlag = true;
+    }
+    if(uiIntStatus & AES_INT_DATA_OUT) {
+        MAP_AESIntDisable(AES_BASE, AES_INT_DATA_OUT);
+        g_bDataOutIntFlag = true;
+    }
+}
+
+uint32_t getBlockSize(void) {
+    return aes_blocksize;
+}
+
+void AESSetup(uint32_t key_size, uint8_t *key){
+    aes_key_size = key_size;
+    switch(key_size) {
+    case AES_KEY_128BIT:
+        aes_blocksize = 16;
+        break;
+    case AES_KEY_192BIT:
+        aes_blocksize = 24;
+        break;
+    case AES_KEY_256BIT:
+        aes_blocksize = 32;
+        break;
+    }
+    aes_key = key;
+    // Enable AES Module
+    MAP_PRCMPeripheralClkEnable(PRCM_DTHE, PRCM_RUN_MODE_CLK);
+    // Enable AES interrupts
+    MAP_AESIntRegister(AES_BASE, AESIntHandler);
+}

+ 32 - 0
crypto.h

@@ -0,0 +1,32 @@
+
+#ifndef __ELEC0017_CRYPTO_H__
+#define __ELEC0017_CRYPTO_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdint.h>
+
+#define AES_DIR_ENCRYPT     0x00000004
+#define AES_DIR_DECRYPT     0x00000000
+
+#define AES_KEY_128BIT  0x00000008
+#define AES_KEY_192BIT  0x00000010
+#define AES_KEY_256BIT  0x00000018
+
+void AESCrypt(uint32_t dir, uint8_t  *iv,
+              uint8_t *data, uint8_t *result,
+              uint32_t dataLength);
+uint8_t * AESEncrypt(uint8_t *message, uint32_t messageLength);
+uint8_t * AESDecrypt(uint8_t *message, uint32_t messageLength);
+void AESIntHandler(void);                // Interrupt handler
+void AESSetup(uint32_t key_size, uint8_t *key);    // Setup AES module
+uint32_t getBlockSize(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 79 - 0
rng.c

@@ -0,0 +1,79 @@
+// Based on https://github.com/manitou48/CC3200/blob/master/rng.ino
+//#include <rng.h>
+
+#include "rng.h"
+#include <stdint.h>
+#include <Energia.h>
+
+#include <driverlib/prcm.h>
+#include <driverlib/systick.h>
+
+#define DTICKS 200
+#define gWDT_buffer_SIZE 32
+#define WDT_POOL_SIZE 8
+
+//const uint8_t gWDT_buffer_SIZE=32;
+//const uint8_t WDT_POOL_SIZE=8;
+
+uint8_t gWDT_buffer[gWDT_buffer_SIZE];
+uint8_t gWDT_buffer_position;
+uint8_t gWDT_loop_counter;
+volatile uint8_t gWDT_pool_start;
+volatile uint8_t gWDT_pool_end;
+volatile uint8_t gWDT_pool_count;
+volatile uint32_t gWDT_entropy_pool[WDT_POOL_SIZE];
+
+uint32_t random(void) {
+  uint32_t retVal;
+  uint8_t waiting;
+  while (gWDT_pool_count < 1) waiting += 1;
+  noInterrupts();  // crtical section
+    retVal = gWDT_entropy_pool[gWDT_pool_start];
+    gWDT_pool_start = (gWDT_pool_start + 1) % WDT_POOL_SIZE;
+    --gWDT_pool_count;
+  interrupts();
+  return(retVal);
+}
+
+void tick(void) {
+  long long t = PRCMSlowClkCtrGet();
+  PRCMSlowClkCtrMatchSet(t + DTICKS); // next interrupt time
+  PRCMIntStatus(); // clear
+
+  gWDT_buffer[gWDT_buffer_position] = SysTickValueGet();
+  gWDT_buffer_position++;                     // every time the WDT interrupt is triggered
+  if (gWDT_buffer_position >= gWDT_buffer_SIZE)
+  {
+    gWDT_pool_end = (gWDT_pool_start + gWDT_pool_count) % WDT_POOL_SIZE;
+    // The following code is an implementation of Jenkin's one at a time hash
+    // This hash function has had preliminary testing to verify that it
+    // produces reasonably uniform random results when using WDT jitter
+    // on a variety of Arduino platforms
+    for(gWDT_loop_counter = 0; gWDT_loop_counter < gWDT_buffer_SIZE; ++gWDT_loop_counter)
+      {
+    gWDT_entropy_pool[gWDT_pool_end] += gWDT_buffer[gWDT_loop_counter];
+    gWDT_entropy_pool[gWDT_pool_end] += (gWDT_entropy_pool[gWDT_pool_end] << 10);
+    gWDT_entropy_pool[gWDT_pool_end] ^= (gWDT_entropy_pool[gWDT_pool_end] >> 6);
+      }
+    gWDT_entropy_pool[gWDT_pool_end] += (gWDT_entropy_pool[gWDT_pool_end] << 3);
+    gWDT_entropy_pool[gWDT_pool_end] ^= (gWDT_entropy_pool[gWDT_pool_end] >> 11);
+    gWDT_entropy_pool[gWDT_pool_end] += (gWDT_entropy_pool[gWDT_pool_end] << 15);
+    gWDT_entropy_pool[gWDT_pool_end] = gWDT_entropy_pool[gWDT_pool_end];
+    gWDT_buffer_position = 0; // Start collecting the next 32 bytes of Timer 1 counts
+    if (gWDT_pool_count == WDT_POOL_SIZE) // The entropy pool is full
+      gWDT_pool_start = (gWDT_pool_start + 1) % WDT_POOL_SIZE;
+    else // Add another unsigned long (32 bits) to the entropy pool
+      ++gWDT_pool_count;
+  }
+}
+
+void RNGSetup(void) {
+    long t = PRCMSlowClkCtrGet();
+    PRCMSlowClkCtrMatchSet(t + DTICKS); // next interrupt time
+    PRCMIntRegister(tick);
+    PRCMIntEnable(PRCM_INT_SLOW_CLK_CTR);
+    gWDT_buffer_position=0;
+    gWDT_pool_start = 0;
+    gWDT_pool_end = 0;
+    gWDT_pool_count = 0;
+}

+ 19 - 0
rng.h

@@ -0,0 +1,19 @@
+#ifndef __ELEC0017_RNG_H__
+#define __ELEC0017_RNG_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdint.h>
+
+uint32_t random(void);
+//static void tick(void);
+void RNGSetup(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 85 - 0
tracker.cpp

@@ -0,0 +1,85 @@
+// Local imports
+#include "crypto.h"
+#include "rng.h"
+
+#define MLEN 32
+
+// Energia constructors
+#include "Arduino.h"
+//#include "Energia.h"
+void setup();
+void loop();
+
+uint8_t aes_key[16] = {
+        0x03, 0x02, 0x01, 0x00,
+        0x07, 0x06, 0x05, 0x04,
+        0x0b, 0x0a, 0x09, 0x08,
+        0x0f, 0x0e, 0x0d, 0x0c
+};
+
+uint8_t AESData[MLEN], *AESResult, AESResult2[MLEN];
+uint32_t AESDataLength=MLEN;
+
+void setup() {
+    // initialising
+    Serial.begin(9600);
+
+    Serial.print("Setup RNG ..");
+    RNGSetup();
+    Serial.println("OK");
+
+    Serial.print("Setup AES ..");
+    AESSetup(AES_KEY_128BIT, aes_key);
+    Serial.println("OK");
+
+    String msg = "This is secret!";
+    msg.toCharArray((char *)AESData, MLEN);
+//
+//    Serial.print("KEY: ");
+//    for(int i=0;i<16;i++) {
+//        Serial.print(aes_key[i], HEX);
+//        Serial.print(' ');
+//    }
+//    Serial.println();
+//
+//    Serial.print("IV: ");
+//    for(int i=0;i<16;i++) {
+//        Serial.print(aes_iv[i], HEX);
+//        Serial.print(' ');
+//    }
+//    Serial.println();
+//
+//    Serial.print("Message: ");
+//    for(int i=0;i<MLEN;i++) {
+//        Serial.print(AESData[i], HEX);
+//        Serial.print(' ');
+//    }
+//    Serial.println();
+//
+    AESResult = AESEncrypt(AESData, AESDataLength);
+
+
+//    AESCrypt(AES_DIR_ENCRYPT, aes_iv, AESData, AESResult, AESDataLength);
+    Serial.print("Encrypted: ");
+    for(uint32_t i=0;i<AESDataLength+getBlockSize();i++) {
+        Serial.print(AESResult[i], HEX);
+        Serial.print(' ');
+    }
+    Serial.println();
+
+//    AESCrypt(AES_DIR_DECRYPT, &aesv, AESResult, AESResult2, AESDataLength);
+//    Serial.print("Decrypted: ");
+//    for(int i=0;i<MLEN;i++) {
+//        Serial.print(AESResult2[i], HEX);
+//        Serial.print(' ');
+//    }
+//    Serial.println();
+}
+
+void loop() {
+    while (Serial.available() > 0) {
+        Serial.println(random(), HEX);
+    }
+}
+
+