Implemented AES-128 encryption

This commit is contained in:
Mark Qvist 2019-02-07 18:36:40 +01:00
parent 0e24b54657
commit b3b1a9b253
15 changed files with 730 additions and 118 deletions

View file

@ -25,23 +25,26 @@ void crypto_init(void) {
}
if (encryption_enabled) {
// TODO: Set flags for crypto enabled
// TODO: Remove
// for (uint8_t i = 0; i < 130; i++) {
// crypto_test();
// }
LED_indicate_enabled_crypto();
} else {
LED_indicate_error_crypto();
}
}
void crypto_prepare(uint8_t key[CRYPTO_KEY_SIZE], uint8_t initialization_vector[CRYPTO_KEY_SIZE]) {
void crypto_generate_hmac(uint8_t *data, size_t length) {
hmac_md5(crypto_work_block, active_key, CRYPTO_KEY_SIZE_BITS, data, length*8);
}
bool crypto_enabled(void) {
return encryption_enabled;
}
void crypto_prepare(void) {
// Initialise the context with the key
aes_128_init(&context, key);
aes_128_init(&context, active_key);
// Copy the IV into the current vector array
memcpy(current_vector, initialization_vector, CRYPTO_KEY_SIZE);
memcpy(current_vector, active_iv, CRYPTO_KEY_SIZE);
}
void crypto_encrypt_block(uint8_t block[CRYPTO_KEY_SIZE]) {
@ -82,7 +85,6 @@ bool load_entropy_index(void) {
if (sd_mounted()) {
crypto_fr = f_open(&crypto_fp, PATH_ENTROPY_INDEX, FA_READ);
if (crypto_fr == FR_NO_FILE) {
//printf("Entropy index file does not exist\r\n");
f_close(&crypto_fp);
crypto_fr = f_open(&crypto_fp, PATH_ENTROPY_INDEX, FA_CREATE_NEW | FA_WRITE);
@ -99,27 +101,20 @@ bool load_entropy_index(void) {
} else {
//printf("Could not write index to index file\r\n");
}
} else {
//printf("Could not create index file\r\n");
}
crypto_fr = f_open(&crypto_fp, PATH_ENTROPY_INDEX, FA_READ);
}
if (crypto_fr == FR_OK) {
//printf("Opened entropy index file\r\n");
UINT read = 0;
crypto_fr = f_read(&crypto_fp, crypto_fb, sizeof(entropy_index), &read);
f_close(&crypto_fp);
if (crypto_fr == FR_OK && read == sizeof(entropy_index)) {
memcpy(&entropy_index, crypto_fb, sizeof(entropy_index));
//printf("Entropy index is now: %lX\r\n", entropy_index);
return true;
}
} else {
//printf("Error opening entropy index file\r\n");
}
}
f_close(&crypto_fp);
@ -148,15 +143,8 @@ bool load_entropy(void) {
crypto_fr = f_open(&crypto_fp, PATH_ENTROPY_SOURCE, FA_READ);
if (crypto_fr == FR_OK) {
uint32_t fsize = f_size(&crypto_fp);
//uint32_t fpoint = crypto_fp.fptr;
//printf("Opened entropy file\r\n\tSize is %lu\r\n\tPointer is at %lX \r\n\tSeeking to index: %lX\r\n", fsize, fpoint, entropy_index);
crypto_fr = f_lseek(&crypto_fp, entropy_index);
//fpoint = crypto_fp.fptr;
//printf("After seek, pointer is now at %lX\r\n", fpoint);
if (crypto_fr == FR_OK && crypto_fp.fptr < fsize-sizeof(entropy)) {
UINT read = 0;
crypto_fr = f_read(&crypto_fp, crypto_fb, sizeof(entropy), &read);
@ -164,18 +152,14 @@ bool load_entropy(void) {
if (crypto_fr == FR_OK) {
memcpy(&entropy, crypto_fb, sizeof(entropy));
//printf("Read entropy from SD: %lX\r\n", entropy);
srandom(entropy);
entropy_loaded = true;
ivs_generated = 0;
return true;
} else {
//printf("Could not read entropy data from SD\r\n");
}
} else {
f_close(&crypto_fp);
//printf("Could not seek in index file, entropy exhausted\r\n");
LED_indicate_error_crypto();
}
}
@ -190,46 +174,30 @@ bool load_key(void) {
if (sd_mounted()) {
crypto_fr = f_open(&crypto_fp, PATH_AES_128_KEY, FA_READ);
if (crypto_fr == FR_OK) {
//printf("File open\r\n");
UINT read = 0;
crypto_fr = f_read(&crypto_fp, crypto_fb, CRYPTO_KEY_SIZE, &read);
f_close(&crypto_fp);
if (crypto_fr == FR_OK && read == CRYPTO_KEY_SIZE) {
//printf("Loaded AES-128 Key: ");
for (uint8_t i = 0; i < 16; i++) {
active_key[i] = crypto_fb[i];
//printf("%X ", crypto_fb[i]);
}
//printf("\r\n");
return true;
} else {
//printf("Error %d reading file, read %d bytes.\r\n", crypto_fr, read);
}
} else {
//printf("Could not open file\r\n");
}
} else {
//printf("SD not mounted\r\n");
}
return false;
}
bool generate_iv(void) {
bool crypto_generate_iv(void) {
if (entropy_loaded) {
for (uint8_t i = 0; i < 16; i++) {
active_iv[i] = (uint8_t)random();
}
ivs_generated++;
// TODO: remove
/*printf("Generated IV: ");
for (uint8_t i = 0; i < 16; i++) {
printf("%X ", active_iv[i]);
}
printf("\r\n");*/
if (ivs_generated >= MAX_IVS_PER_ENTROPY_BLOCK) {
load_entropy();
}
@ -240,24 +208,12 @@ bool generate_iv(void) {
}
}
// TODO: Remove this
void crypto_test(void) {
generate_iv();
uint8_t work_block[16];
memset(work_block, 0x70, 16);
work_block[15] = 0x00;
//printf("Work block plaintext: ===%s===\r\n", work_block);
crypto_prepare(active_key, active_iv);
crypto_encrypt_block(work_block);
//printf("Work block ciphertext: ===%s===\r\n", work_block);
crypto_prepare(active_key, active_iv);
crypto_decrypt_block(work_block);
printf("Work block plaintext: ===%s===\r\n", work_block);
uint8_t *crypto_get_iv(void) {
return active_iv;
}
void crypto_set_iv_from_workblock(void) {
memcpy(active_iv, crypto_work_block, CRYPTO_KEY_SIZE);
}
// TODO: test entropy exhaustion

View file

@ -5,7 +5,8 @@
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include "hardware/crypto/aes.h"
#include "hardware/crypto/AES.h"
#include "hardware/crypto/HMAC_MD5.h"
#include "hardware/LED.h"
#include "hardware/SD.h"
@ -15,9 +16,23 @@
#define CRYPTO_KEY_SIZE_BITS 128
#define CRYPTO_KEY_SIZE (CRYPTO_KEY_SIZE_BITS/8)
#define CRYPTO_HMAC_SIZE_BITS 128
#define CRYPTO_HMAC_SIZE (CRYPTO_HMAC_SIZE_BITS/8)
#define MAX_IVS_PER_ENTROPY_BLOCK 128
uint8_t crypto_work_block[CRYPTO_KEY_SIZE];
void crypto_init(void);
bool crypto_enabled(void);
bool crypto_generate_iv(void);
uint8_t* crypto_get_iv(void);
void crypto_set_iv_from_workblock(void);
void crypto_generate_hmac(uint8_t *data, size_t length);
void crypto_prepare(void);
void crypto_encrypt_block(uint8_t block[CRYPTO_KEY_SIZE]);
void crypto_decrypt_block(uint8_t block[CRYPTO_KEY_SIZE]);
void crypto_test(void);
bool load_key(void);

View file

@ -1,6 +1,8 @@
#include "LED.h"
#include "util/time.h"
bool LED_softblock_enabled = false;
uint8_t ledIntensity = CONFIG_LED_INTENSITY;
ticks_t led_status_ticks_top = 0;
ticks_t led_status_ticks = 0;
@ -28,6 +30,13 @@ void LED_init(void) {
OCR0A = ledIntensity;
}
void LED_softblock_on(void) {
LED_softblock_enabled = true;
}
void LED_softblock_off(void) {
LED_softblock_enabled = false;
}
void LED_setIntensity(uint8_t value) {
ledIntensity = value;
@ -35,11 +44,22 @@ void LED_setIntensity(uint8_t value) {
}
void LED_COM_ON(void) {
if (!LED_softblock_enabled) {
LED_PORT |= _BV(4);
com_led_timeout = timer_clock() + ms_to_ticks(CONFIG_COM_LED_TIMEOUT_MS);
}
}
void LED_COM_OFF(void) {
if (!LED_softblock_enabled) LED_PORT &= ~_BV(4);
}
void LED_F_COM_ON(void) {
LED_PORT |= _BV(4);
com_led_timeout = timer_clock() + ms_to_ticks(CONFIG_COM_LED_TIMEOUT_MS);
}
void LED_COM_OFF(void) {
void LED_F_COM_OFF(void) {
LED_PORT &= ~_BV(4);
}
@ -54,6 +74,37 @@ void update_led_status(void) {
}
}
#define LED_DELAY_E_C_1 200
#define LED_DELAY_E_C_2 50
void LED_indicate_enabled_crypto(void) {
LED_softblock_on();
LED_F_STATUS_OFF();
LED_F_COM_OFF();
LED_F_TX_OFF();
LED_F_RX_OFF();
delay_ms(LED_DELAY_E_C_1);
for (uint8_t i = 0; i < 2; i++) {
LED_F_STATUS_ON();
delay_ms(LED_DELAY_E_C_2);
LED_F_STATUS_OFF();
LED_F_COM_ON();
delay_ms(LED_DELAY_E_C_2);
LED_F_COM_OFF();
LED_F_RX_ON();
delay_ms(LED_DELAY_E_C_2);
LED_F_RX_OFF();
LED_F_TX_ON();
delay_ms(LED_DELAY_E_C_2);
LED_F_TX_OFF();
delay_ms(LED_DELAY_E_C_2);
}
LED_F_STATUS_ON();
LED_softblock_off();
}
void LED_indicate_error_crypto(void) {
while (true) {
LED_COM_ON();

View file

@ -2,18 +2,29 @@
#define LED_H
#include <avr/io.h>
#include <stdbool.h>
#include "device.h"
extern bool LED_softblock_enabled;
void LED_init(void);
void LED_setIntensity(uint8_t value);
#define LED_STATUS_ON() do { LED_PORT |= _BV(2); } while (0)
#define LED_STATUS_OFF() do { LED_PORT &= ~_BV(2); } while (0)
#define LED_STATUS_TOGGLE() do { LED_PORT ^= _BV(2); } while (0)
#define LED_TX_ON() do { LED_PORT |= _BV(1); } while (0)
#define LED_TX_OFF() do { LED_PORT &= ~_BV(1); } while (0)
#define LED_RX_ON() do { LED_PORT |= _BV(0); } while (0)
#define LED_RX_OFF() do { LED_PORT &= ~_BV(0); } while (0)
#define LED_STATUS_ON() do { if (!LED_softblock_enabled) LED_PORT |= _BV(2); } while (0)
#define LED_STATUS_OFF() do { if (!LED_softblock_enabled) LED_PORT &= ~_BV(2); } while (0)
#define LED_STATUS_TOGGLE() do { if (!LED_softblock_enabled) LED_PORT ^= _BV(2); } while (0)
#define LED_TX_ON() do { if (!LED_softblock_enabled) LED_PORT |= _BV(1); } while (0)
#define LED_TX_OFF() do { if (!LED_softblock_enabled) LED_PORT &= ~_BV(1); } while (0)
#define LED_RX_ON() do { if (!LED_softblock_enabled) LED_PORT |= _BV(0); } while (0)
#define LED_RX_OFF() do { if (!LED_softblock_enabled) LED_PORT &= ~_BV(0); } while (0)
#define LED_F_STATUS_ON() do { LED_PORT |= _BV(2); } while (0)
#define LED_F_STATUS_OFF() do { LED_PORT &= ~_BV(2); } while (0)
#define LED_F_STATUS_TOGGLE() do { LED_PORT ^= _BV(2); } while (0)
#define LED_F_TX_ON() do { LED_PORT |= _BV(1); } while (0)
#define LED_F_TX_OFF() do { LED_PORT &= ~_BV(1); } while (0)
#define LED_F_RX_ON() do { LED_PORT |= _BV(0); } while (0)
#define LED_F_RX_OFF() do { LED_PORT &= ~_BV(0); } while (0)
void LED_COM_ON(void);
void LED_COM_OFF(void);
@ -21,4 +32,6 @@ void update_led_status(void);
void LED_indicate_error_crypto(void);
void LED_indicate_enabled_crypto(void);
#endif

View file

@ -30,6 +30,9 @@ void sd_automounted_hook(void) {
void sd_autounmounted_hook(void) {
sd_statuschange_indication(0);
if (crypto_enabled()) {
LED_indicate_error_crypto();
}
}
void sd_jobs(void) {

129
hardware/crypto/HMAC_MD5.c Normal file
View file

@ -0,0 +1,129 @@
/* hmac-md5.c */
/*
This file is part of the AVR-Crypto-Lib.
Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
*
* implementation of HMAC as described in RFC2104
* Author: Daniel Otte
* email: bg@nerilex.org
* License: GPLv3 or later
**/
/*
* hmac = hash ( k^opad , hash( k^ipad , msg))
*/
#include <stdint.h>
#include <string.h>
#include "MD5.h"
#include "HMAC_MD5.h"
#define IPAD 0x36
#define OPAD 0x5C
#ifndef HMAC_SHORTONLY
void hmac_md5_init(hmac_md5_ctx_t *s, void *key, uint16_t keylength_b){
uint8_t buffer[MD5_BLOCK_BYTES];
uint8_t i;
memset(buffer, 0, MD5_BLOCK_BYTES);
if (keylength_b > MD5_BLOCK_BITS){
md5((void*)buffer, key, keylength_b);
} else {
memcpy(buffer, key, (keylength_b+7)/8);
}
for (i=0; i<MD5_BLOCK_BYTES; ++i){
buffer[i] ^= IPAD;
}
md5_init(&(s->a));
md5_nextBlock(&(s->a), buffer);
for (i=0; i<MD5_BLOCK_BYTES; ++i){
buffer[i] ^= IPAD^OPAD;
}
md5_init(&(s->b));
md5_nextBlock(&(s->b), buffer);
#if defined SECURE_WIPE_BUFFER
memset(buffer, 0, MD5_BLOCK_BYTES);
#endif
}
void hmac_md5_nextBlock(hmac_md5_ctx_t *s, const void *block){
md5_nextBlock(&(s->a), block);
}
void hmac_md5_lastBlock(hmac_md5_ctx_t *s, const void *block, uint16_t length_b){
md5_lastBlock(&(s->a), block, length_b);
}
void hmac_md5_final(void *dest, hmac_md5_ctx_t *s){
md5_ctx2hash((md5_hash_t*)dest, &(s->a));
md5_lastBlock(&(s->b), dest, MD5_HASH_BITS);
md5_ctx2hash((md5_hash_t*)dest, &(s->b));
}
#endif
/*
void hmac_md5_nextBlock()
void hmac_md5_lastBlock()
*/
/*
* keylength in bits!
* message length in bits!
*/
void hmac_md5(void *dest, void *key, uint16_t keylength_b, void *msg, uint32_t msglength_b){ /* a one-shot*/
md5_ctx_t s;
uint8_t i;
uint8_t buffer[MD5_BLOCK_BYTES];
memset(buffer, 0, MD5_BLOCK_BYTES);
/* if key is larger than a block we have to hash it*/
if (keylength_b > MD5_BLOCK_BITS){
md5((void*)buffer, key, keylength_b);
} else {
memcpy(buffer, key, (keylength_b+7)/8);
}
for (i=0; i<MD5_BLOCK_BYTES; ++i){
buffer[i] ^= IPAD;
}
md5_init(&s);
md5_nextBlock(&s, buffer);
while (msglength_b >= MD5_BLOCK_BITS){
md5_nextBlock(&s, msg);
msg = (uint8_t*)msg + MD5_BLOCK_BYTES;
msglength_b -= MD5_BLOCK_BITS;
}
md5_lastBlock(&s, msg, msglength_b);
/* since buffer still contains key xor ipad we can do ... */
for (i=0; i<MD5_BLOCK_BYTES; ++i){
buffer[i] ^= IPAD ^ OPAD;
}
md5_ctx2hash(dest, &s); /* save inner hash temporary to dest */
md5_init(&s);
md5_nextBlock(&s, buffer);
md5_lastBlock(&s, dest, MD5_HASH_BITS);
md5_ctx2hash(dest, &s);
}

View file

@ -0,0 +1,42 @@
/* hmac-md5.h */
/*
This file is part of the AVR-Crypto-Lib.
Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef HMACMD5_H_
#define HMACMD5_H_
#include "MD5.h"
#define HMAC_MD5_BITS MD5_HASH_BITS
#define HMAC_MD5_BYTES MD5_HASH_BYTES
#define HMAC_MD5_BLOCK_BITS MD5_BLOCK_BITS
#define HMAC_MD5_BLOCK_BYTES MD5_BLOCK_BYTES
typedef struct{
md5_ctx_t a,b;
} hmac_md5_ctx_t;
void hmac_md5_init(hmac_md5_ctx_t *s, void *key, uint16_t keylength_b);
void hmac_md5_nextBlock(hmac_md5_ctx_t *s, const void *block);
void hmac_md5_lastBlock(hmac_md5_ctx_t *s, const void *block, uint16_t length_b);
void hmac_md5_final(void *dest, hmac_md5_ctx_t *s);
void hmac_md5(void *dest, void *key, uint16_t keylength_b, void *msg, uint32_t msglength_b);
#endif /*HMACMD5_H_*/

187
hardware/crypto/MD5.c Normal file
View file

@ -0,0 +1,187 @@
/* md5.c */
/*
This file is part of the AVR-Crypto-Lib.
Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* \file md5.c
* \author Daniel Otte
* \date 2006-07-31
* \license GPLv3 or later
* \brief Implementation of the MD5 hash algorithm as described in RFC 1321
*
*/
#include "MD5.h"
#include "MD5_sbox.h"
#include <stdint.h>
#include <string.h>
#undef DEBUG
void md5_init(md5_ctx_t *s){
s->counter = 0;
s->a[0] = 0x67452301;
s->a[1] = 0xefcdab89;
s->a[2] = 0x98badcfe;
s->a[3] = 0x10325476;
}
static
uint32_t md5_F(uint32_t x, uint32_t y, uint32_t z){
return ((x&y)|((~x)&z));
}
static
uint32_t md5_G(uint32_t x, uint32_t y, uint32_t z){
return ((x&z)|((~z)&y));
}
static
uint32_t md5_H(uint32_t x, uint32_t y, uint32_t z){
return (x^y^z);
}
static
uint32_t md5_I(uint32_t x, uint32_t y, uint32_t z){
return (y ^ (x | (~z)));
}
typedef uint32_t md5_func_t(uint32_t, uint32_t, uint32_t);
#define ROTL32(x,n) (((x)<<(n)) | ((x)>>(32-(n))))
static
void md5_core(uint32_t *a, void *block, uint8_t as, uint8_t s, uint8_t i, uint8_t fi){
uint32_t t;
md5_func_t *funcs[]={md5_F, md5_G, md5_H, md5_I};
as &= 0x3;
/* a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
#ifdef DEBUG
char funcc[]={'*', '-', '+', '~'};
cli_putstr("\r\n DBG: md5_core [");
cli_putc(funcc[fi]);
cli_hexdump(&as, 1); cli_putc(' ');
cli_hexdump(&k, 1); cli_putc(' ');
cli_hexdump(&s, 1); cli_putc(' ');
cli_hexdump(&i, 1); cli_putc(']');
#endif
t = a[as] + funcs[fi](a[(as+1)&3], a[(as+2)&3], a[(as+3)&3])
+ *((uint32_t*)block) + pgm_read_dword(md5_T+i) ;
a[as]=a[(as+1)&3] + ROTL32(t, s);
}
void md5_nextBlock(md5_ctx_t *state, const void *block){
uint32_t a[4];
uint8_t m,n,i=0;
/* this requires other mixed sboxes */
#ifdef DEBUG
cli_putstr("\r\n DBG: md5_nextBlock: block:\r\n");
cli_hexdump(block, 16); cli_putstr("\r\n");
cli_hexdump(block+16, 16); cli_putstr("\r\n");
cli_hexdump(block+32, 16); cli_putstr("\r\n");
cli_hexdump(block+48, 16); cli_putstr("\r\n");
#endif
a[0]=state->a[0];
a[1]=state->a[1];
a[2]=state->a[2];
a[3]=state->a[3];
/* round 1 */
uint8_t s1t[]={7,12,17,22}; // 1,-1 1,4 2,-1 3,-2
for(m=0;m<4;++m){
for(n=0;n<4;++n){
md5_core(a, &(((uint32_t*)block)[m*4+n]), 4-n, s1t[n],i++,0);
}
}
/* round 2 */
uint8_t s2t[]={5,9,14,20}; // 1,-3 1,1 2,-2 2,4
for(m=0;m<4;++m){
for(n=0;n<4;++n){
md5_core(a, &(((uint32_t*)block)[(1+m*4+n*5)&0xf]), 4-n, s2t[n],i++,1);
}
}
/* round 3 */
uint8_t s3t[]={4,11,16,23}; // 0,4 1,3 2,0 3,-1
for(m=0;m<4;++m){
for(n=0;n<4;++n){
md5_core(a, &(((uint32_t*)block)[(5-m*4+n*3)&0xf]), 4-n, s3t[n],i++,2);
}
}
/* round 4 */
uint8_t s4t[]={6,10,15,21}; // 1,-2 1,2 2,-1 3,-3
for(m=0;m<4;++m){
for(n=0;n<4;++n){
md5_core(a, &(((uint32_t*)block)[(0-m*4+n*7)&0xf]), 4-n, s4t[n],i++,3);
}
}
state->a[0] += a[0];
state->a[1] += a[1];
state->a[2] += a[2];
state->a[3] += a[3];
state->counter++;
}
void md5_lastBlock(md5_ctx_t *state, const void *block, uint16_t length_b){
uint16_t l;
union {
uint8_t v8[64];
uint64_t v64[ 8];
} buffer;
while (length_b >= 512){
md5_nextBlock(state, block);
length_b -= 512;
block = ((uint8_t*)block) + 512/8;
}
memset(buffer.v8, 0, 64);
memcpy(buffer.v8, block, length_b/8);
/* insert padding one */
l=length_b/8;
if(length_b%8){
uint8_t t;
t = ((uint8_t*)block)[l];
t |= (0x80>>(length_b%8));
buffer.v8[l]=t;
}else{
buffer.v8[l]=0x80;
}
/* insert length value */
if(l+sizeof(uint64_t) >= 512/8){
md5_nextBlock(state, buffer.v8);
state->counter--;
memset(buffer.v8, 0, 64-8);
}
buffer.v64[7] = (state->counter * 512) + length_b;
md5_nextBlock(state, buffer.v8);
}
void md5_ctx2hash(md5_hash_t *dest, const md5_ctx_t *state){
memcpy(dest, state->a, MD5_HASH_BYTES);
}
void md5(md5_hash_t *dest, const void *msg, uint32_t length_b){
md5_ctx_t ctx;
md5_init(&ctx);
while(length_b>=MD5_BLOCK_BITS){
md5_nextBlock(&ctx, msg);
msg = (uint8_t*)msg + MD5_BLOCK_BYTES;
length_b -= MD5_BLOCK_BITS;
}
md5_lastBlock(&ctx, msg, length_b);
md5_ctx2hash(dest, &ctx);
}

55
hardware/crypto/MD5.h Normal file
View file

@ -0,0 +1,55 @@
/* md5.h */
/*
This file is part of the AVR-Crypto-Lib.
Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* File: md5.h
* Author: Daniel Otte
* Date: 31.07.2006
* License: GPL
* Description: Implementation of the MD5 hash algorithm as described in RFC 1321
*
*/
#ifndef MD5_H_
#define MD5_H_
#include <stdint.h>
#define MD5_HASH_BITS 128
#define MD5_HASH_BYTES (MD5_HASH_BITS/8)
#define MD5_BLOCK_BITS 512
#define MD5_BLOCK_BYTES (MD5_BLOCK_BITS/8)
typedef struct md5_ctx_st {
uint32_t a[4];
uint32_t counter;
} md5_ctx_t;
typedef uint8_t md5_hash_t[MD5_HASH_BYTES];
void md5_init(md5_ctx_t *s);
void md5_nextBlock(md5_ctx_t *state, const void *block);
void md5_lastBlock(md5_ctx_t *state, const void *block, uint16_t length);
void md5_ctx2hash(md5_hash_t *dest, const md5_ctx_t *state);
void md5(md5_hash_t *dest, const void *msg, uint32_t length_b);
#endif /*MD5_H_*/

View file

@ -0,0 +1,36 @@
/* md5_sbox.c */
/*
This file is part of the AVR-Crypto-Lib.
Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdint.h>
#include <avr/pgmspace.h>
const uint32_t md5_T[] PROGMEM = {
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf,
0x4787c62a, 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af,
0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e,
0x49b40821, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, 0x21e1cde6,
0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8,
0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122,
0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039,
0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 0xf4292244, 0x432aff97,
0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d,
0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 };

View file

@ -0,0 +1,27 @@
/* md5_sbox.h */
/*
This file is part of the AVR-Crypto-Lib.
Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MD5_SBOX_H_
#define MD5_SBOX_H_
#include <stdint.h>
#include <avr/pgmspace.h>
extern const uint32_t md5_T[];
#endif /*MD5_SBOX_H_*/