mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-03-30 20:09:14 +03:00
удаляем библиотеку
This commit is contained in:
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* The MySensors Arduino library handles the wireless radio link and protocol
|
||||
* between your home built sensors/actuators and HA controller of choice.
|
||||
* The sensors forms a self healing radio network with optional repeaters. Each
|
||||
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
|
||||
* network topology allowing messages to be routed to nodes.
|
||||
*
|
||||
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
|
||||
* Copyright (C) 2013-2019 Sensnology AB
|
||||
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
|
||||
*
|
||||
* Documentation: http://www.mysensors.org
|
||||
* Support Forum: http://forum.mysensors.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include "MyCryptoGeneric.h"
|
||||
|
||||
void SHA256HMAC(uint8_t *dest, const uint8_t *key, size_t keyLength, const uint8_t *data,
|
||||
size_t dataLength)
|
||||
{
|
||||
SHA256HMACInit(key, keyLength);
|
||||
SHA256HMACAdd(data, dataLength);
|
||||
SHA256HMACResult(dest);
|
||||
}
|
||||
|
||||
AES _aes;
|
||||
|
||||
void AES128CBCInit(const uint8_t *key)
|
||||
{
|
||||
_aes.set_key((byte *)key, 16);
|
||||
}
|
||||
|
||||
void AES128CBCEncrypt(uint8_t *iv, uint8_t *buffer, const size_t dataLength)
|
||||
{
|
||||
_aes.cbc_encrypt((byte *)buffer, (byte *)buffer, dataLength / 16, iv);
|
||||
}
|
||||
|
||||
void AES128CBCDecrypt(uint8_t *iv, uint8_t *buffer, const size_t dataLength)
|
||||
{
|
||||
_aes.cbc_decrypt((byte *)buffer, (byte *)buffer, dataLength / 16, iv);
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* The MySensors Arduino library handles the wireless radio link and protocol
|
||||
* between your home built sensors/actuators and HA controller of choice.
|
||||
* The sensors forms a self healing radio network with optional repeaters. Each
|
||||
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
|
||||
* network topology allowing messages to be routed to nodes.
|
||||
*
|
||||
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
|
||||
* Copyright (C) 2013-2019 Sensnology AB
|
||||
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
|
||||
*
|
||||
* Documentation: http://www.mysensors.org
|
||||
* Support Forum: http://forum.mysensors.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef MyCryptoGeneric_h
|
||||
#define MyCryptoGeneric_h
|
||||
|
||||
#include "hal/crypto/MyCryptoHAL.h"
|
||||
#include "hal/crypto/generic/drivers/AES/AES.cpp"
|
||||
#include "hal/crypto/generic/drivers/SHA256/sha256.cpp"
|
||||
#include "hal/crypto/generic/drivers/HMAC_SHA256/hmac_sha256.cpp"
|
||||
|
||||
#endif
|
||||
@@ -1,631 +0,0 @@
|
||||
#include "AES.h"
|
||||
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
1. source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
2. binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation;
|
||||
|
||||
3. the name of the copyright holder is not used to endorse products
|
||||
built using this software without specific written permission.
|
||||
|
||||
DISCLAIMER
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its properties, including, but not limited to, correctness
|
||||
and/or fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue 09/09/2006
|
||||
|
||||
This is an AES implementation that uses only 8-bit byte operations on the
|
||||
cipher state (there are options to use 32-bit types if available).
|
||||
|
||||
The combination of mix columns and byte substitution used here is based on
|
||||
that developed by Karl Malbrain. His contribution is acknowledged.
|
||||
*/
|
||||
|
||||
/* This version derived by Mark Tillotson 2012-01-23, tidied up, slimmed down
|
||||
and tailored to 8-bit microcontroller abilities and Arduino datatypes.
|
||||
|
||||
The s-box and inverse s-box were retained as tables (0.5kB PROGMEM) but all
|
||||
the other transformations are coded to save table space. Many efficiency
|
||||
improvments to the routines mix_sub_columns() and inv_mix_sub_columns()
|
||||
(mainly common sub-expression elimination).
|
||||
|
||||
Only the routines with precalculated subkey schedule are retained (together
|
||||
with set_key() - this does however mean each AES object takes 240 bytes of
|
||||
RAM, alas)
|
||||
|
||||
The CBC routines side-effect the iv argument (so that successive calls work
|
||||
together correctly).
|
||||
|
||||
All the encryption and decryption routines work with plain == cipher for
|
||||
in-place encryption, note.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/* functions for finite field multiplication in the AES Galois field */
|
||||
|
||||
/* code was modified by george spanos <spaniakos@gmail.com>
|
||||
* 16/12/14
|
||||
*/
|
||||
|
||||
// GF(2^8) stuff
|
||||
|
||||
#define WPOLY 0x011B
|
||||
#define DPOLY 0x008D
|
||||
|
||||
const static byte s_fwd [0x100] PROGMEM = {
|
||||
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
|
||||
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
|
||||
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
|
||||
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
|
||||
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
|
||||
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
|
||||
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
|
||||
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
|
||||
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
|
||||
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
|
||||
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
|
||||
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
|
||||
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
|
||||
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
|
||||
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
|
||||
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16,
|
||||
} ;
|
||||
|
||||
const static byte s_inv [0x100] PROGMEM = {
|
||||
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
|
||||
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
|
||||
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
|
||||
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
|
||||
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
|
||||
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
|
||||
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
|
||||
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
|
||||
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
|
||||
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
|
||||
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
|
||||
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
|
||||
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
|
||||
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
|
||||
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
|
||||
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d,
|
||||
} ;
|
||||
|
||||
// times 2 in the GF(2^8)
|
||||
#define f2(x) (((x) & 0x80) ? (x << 1) ^ WPOLY : x << 1)
|
||||
#define d2(x) (((x) >> 1) ^ ((x) & 1 ? DPOLY : 0))
|
||||
|
||||
static byte s_box (byte x)
|
||||
{
|
||||
// return fwd_affine (pgm_read_byte (&inv [x])) ;
|
||||
return pgm_read_byte (& s_fwd [x]) ;
|
||||
}
|
||||
|
||||
// Inverse Sbox
|
||||
static byte is_box (byte x)
|
||||
{
|
||||
// return pgm_read_byte (&inv [inv_affine (x)]) ;
|
||||
return pgm_read_byte (& s_inv [x]) ;
|
||||
}
|
||||
|
||||
|
||||
static void xor_block (byte * d, byte * s)
|
||||
{
|
||||
for (byte i = 0 ; i < N_BLOCK ; i += 4) {
|
||||
*d++ ^= *s++ ; // some unrolling
|
||||
*d++ ^= *s++ ;
|
||||
*d++ ^= *s++ ;
|
||||
*d++ ^= *s++ ;
|
||||
}
|
||||
}
|
||||
|
||||
static void copy_and_key (byte * d, byte * s, byte * k)
|
||||
{
|
||||
for (byte i = 0 ; i < N_BLOCK ; i += 4) {
|
||||
*d++ = *s++ ^ *k++ ; // some unrolling
|
||||
*d++ = *s++ ^ *k++ ;
|
||||
*d++ = *s++ ^ *k++ ;
|
||||
*d++ = *s++ ^ *k++ ;
|
||||
}
|
||||
}
|
||||
|
||||
// #define add_round_key(d, k) xor_block (d, k)
|
||||
|
||||
/* SUB ROW PHASE */
|
||||
|
||||
static void shift_sub_rows (byte st [N_BLOCK])
|
||||
{
|
||||
st [0] = s_box (st [0]) ;
|
||||
st [4] = s_box (st [4]) ;
|
||||
st [8] = s_box (st [8]) ;
|
||||
st [12] = s_box (st [12]) ;
|
||||
|
||||
byte tt = st [1] ;
|
||||
st [1] = s_box (st [5]) ;
|
||||
st [5] = s_box (st [9]) ;
|
||||
st [9] = s_box (st [13]) ;
|
||||
st [13] = s_box (tt) ;
|
||||
|
||||
tt = st[2] ;
|
||||
st [2] = s_box (st [10]) ;
|
||||
st [10] = s_box (tt) ;
|
||||
tt = st[6] ;
|
||||
st [6] = s_box (st [14]) ;
|
||||
st [14] = s_box (tt) ;
|
||||
|
||||
tt = st[15] ;
|
||||
st [15] = s_box (st [11]) ;
|
||||
st [11] = s_box (st [7]) ;
|
||||
st [7] = s_box (st [3]) ;
|
||||
st [3] = s_box (tt) ;
|
||||
}
|
||||
|
||||
static void inv_shift_sub_rows (byte st[N_BLOCK])
|
||||
{
|
||||
st [0] = is_box (st[0]) ;
|
||||
st [4] = is_box (st [4]);
|
||||
st [8] = is_box (st[8]) ;
|
||||
st [12] = is_box (st [12]);
|
||||
|
||||
byte tt = st[13] ;
|
||||
st [13] = is_box (st [9]) ;
|
||||
st [9] = is_box (st [5]) ;
|
||||
st [5] = is_box (st [1]) ;
|
||||
st [1] = is_box (tt) ;
|
||||
|
||||
tt = st [2] ;
|
||||
st [2] = is_box (st [10]) ;
|
||||
st [10] = is_box (tt) ;
|
||||
tt = st [6] ;
|
||||
st [6] = is_box (st [14]) ;
|
||||
st [14] = is_box (tt) ;
|
||||
|
||||
tt = st [3] ;
|
||||
st [3] = is_box (st [7]) ;
|
||||
st [7] = is_box (st [11]) ;
|
||||
st [11] = is_box (st [15]) ;
|
||||
st [15] = is_box (tt) ;
|
||||
}
|
||||
|
||||
/* SUB COLUMNS PHASE */
|
||||
|
||||
static void mix_sub_columns (byte dt[N_BLOCK], byte st[N_BLOCK])
|
||||
{
|
||||
byte j = 5 ;
|
||||
byte k = 10 ;
|
||||
byte l = 15 ;
|
||||
for (byte i = 0 ; i < N_BLOCK ; i += N_COL) {
|
||||
byte a = st [i] ;
|
||||
byte b = st [j] ;
|
||||
j = (j+N_COL) & 15 ;
|
||||
byte c = st [k] ;
|
||||
k = (k+N_COL) & 15 ;
|
||||
byte d = st [l] ;
|
||||
l = (l+N_COL) & 15 ;
|
||||
byte a1 = s_box (a), b1 = s_box (b), c1 = s_box (c), d1 = s_box (d) ;
|
||||
byte a2 = f2(a1), b2 = f2(b1), c2 = f2(c1), d2 = f2(d1) ;
|
||||
dt[i] = a2 ^ b2^b1 ^ c1 ^ d1 ;
|
||||
dt[i+1] = a1 ^ b2 ^ c2^c1 ^ d1 ;
|
||||
dt[i+2] = a1 ^ b1 ^ c2 ^ d2^d1 ;
|
||||
dt[i+3] = a2^a1 ^ b1 ^ c1 ^ d2 ;
|
||||
}
|
||||
}
|
||||
|
||||
static void inv_mix_sub_columns (byte dt[N_BLOCK], byte st[N_BLOCK])
|
||||
{
|
||||
for (byte i = 0 ; i < N_BLOCK ; i += N_COL) {
|
||||
byte a1 = st [i] ;
|
||||
byte b1 = st [i+1] ;
|
||||
byte c1 = st [i+2] ;
|
||||
byte d1 = st [i+3] ;
|
||||
byte a2 = f2(a1), b2 = f2(b1), c2 = f2(c1), d2 = f2(d1) ;
|
||||
byte a4 = f2(a2), b4 = f2(b2), c4 = f2(c2), d4 = f2(d2) ;
|
||||
byte a8 = f2(a4), b8 = f2(b4), c8 = f2(c4), d8 = f2(d4) ;
|
||||
byte a9 = a8 ^ a1,b9 = b8 ^ b1,c9 = c8 ^ c1,d9 = d8 ^ d1 ;
|
||||
byte ac = a8 ^ a4,bc = b8 ^ b4,cc = c8 ^ c4,dc = d8 ^ d4 ;
|
||||
|
||||
dt[i] = is_box (ac^a2 ^ b9^b2 ^ cc^c1 ^ d9) ;
|
||||
dt[(i+5)&15] = is_box (a9 ^ bc^b2 ^ c9^c2 ^ dc^d1) ;
|
||||
dt[(i+10)&15] = is_box (ac^a1 ^ b9 ^ cc^c2 ^ d9^d2) ;
|
||||
dt[(i+15)&15] = is_box (a9^a2 ^ bc^b1 ^ c9 ^ dc^d2) ;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
AES::AES()
|
||||
{
|
||||
byte ar_iv[8] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01 };
|
||||
IVC = 0x01;
|
||||
round = 0;
|
||||
pad = 0;
|
||||
size = 0;
|
||||
memset(key_sched, 0, KEY_SCHEDULE_BYTES);
|
||||
memcpy(iv,ar_iv,8);
|
||||
memcpy(iv+8,ar_iv,8);
|
||||
arr_pad[0] = 0x01;
|
||||
arr_pad[1] = 0x02;
|
||||
arr_pad[2] = 0x03;
|
||||
arr_pad[3] = 0x04;
|
||||
arr_pad[4] = 0x05;
|
||||
arr_pad[5] = 0x06;
|
||||
arr_pad[6] = 0x07;
|
||||
arr_pad[7] = 0x08;
|
||||
arr_pad[8] = 0x09;
|
||||
arr_pad[9] = 0x0a;
|
||||
arr_pad[10] = 0x0b;
|
||||
arr_pad[11] = 0x0c;
|
||||
arr_pad[12] = 0x0d;
|
||||
arr_pad[13] = 0x0e;
|
||||
arr_pad[14] = 0x0f;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
byte AES::set_key (byte key [], int keylen)
|
||||
{
|
||||
byte hi ;
|
||||
switch (keylen) {
|
||||
case 16:
|
||||
case 128:
|
||||
keylen = 16; // 10 rounds
|
||||
round = 10 ;
|
||||
break;
|
||||
case 24:
|
||||
case 192:
|
||||
keylen = 24; // 12 rounds
|
||||
round = 12 ;
|
||||
break;
|
||||
case 32:
|
||||
case 256:
|
||||
keylen = 32; // 14 rounds
|
||||
round = 14 ;
|
||||
break;
|
||||
default:
|
||||
round = 0;
|
||||
return AES_FAILURE;
|
||||
}
|
||||
hi = (round + 1) << 4 ;
|
||||
copy_n_bytes (key_sched, key, keylen) ;
|
||||
byte t[4] ;
|
||||
byte next = keylen ;
|
||||
for (byte cc = keylen, rc = 1 ; cc < hi ; cc += N_COL) {
|
||||
for (byte i = 0 ; i < N_COL ; i++) {
|
||||
t[i] = key_sched [cc-4+i] ;
|
||||
}
|
||||
if (cc == next) {
|
||||
next += keylen ;
|
||||
byte ttt = t[0] ;
|
||||
t[0] = s_box (t[1]) ^ rc ;
|
||||
t[1] = s_box (t[2]) ;
|
||||
t[2] = s_box (t[3]) ;
|
||||
t[3] = s_box (ttt) ;
|
||||
rc = f2 (rc) ;
|
||||
} else if (keylen == 32 && (cc & 31) == 16) {
|
||||
for (byte i = 0 ; i < 4 ; i++) {
|
||||
t[i] = s_box (t[i]) ;
|
||||
}
|
||||
}
|
||||
byte tt = cc - keylen ;
|
||||
for (byte i = 0 ; i < N_COL ; i++) {
|
||||
key_sched [cc + i] = key_sched [tt + i] ^ t[i] ;
|
||||
}
|
||||
}
|
||||
return AES_SUCCESS ;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void AES::clean ()
|
||||
{
|
||||
for (byte i = 0 ; i < KEY_SCHEDULE_BYTES ; i++) {
|
||||
key_sched [i] = 0 ;
|
||||
}
|
||||
round = 0 ;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void AES::copy_n_bytes (byte * d, byte * s, byte nn)
|
||||
{
|
||||
while (nn >= 4) {
|
||||
*d++ = *s++ ; // some unrolling
|
||||
*d++ = *s++ ;
|
||||
*d++ = *s++ ;
|
||||
*d++ = *s++ ;
|
||||
nn -= 4 ;
|
||||
}
|
||||
while (nn--) {
|
||||
*d++ = *s++ ;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
byte AES::encrypt (byte plain [N_BLOCK], byte cipher [N_BLOCK])
|
||||
{
|
||||
if (round) {
|
||||
byte s1 [N_BLOCK], r ;
|
||||
copy_and_key (s1, plain, (byte*) (key_sched)) ;
|
||||
|
||||
for (r = 1 ; r < round ; r++) {
|
||||
byte s2 [N_BLOCK] ;
|
||||
mix_sub_columns (s2, s1) ;
|
||||
copy_and_key (s1, s2, (byte*) (key_sched + r * N_BLOCK)) ;
|
||||
}
|
||||
shift_sub_rows (s1) ;
|
||||
copy_and_key (cipher, s1, (byte*) (key_sched + r * N_BLOCK)) ;
|
||||
} else {
|
||||
return AES_FAILURE ;
|
||||
}
|
||||
return AES_SUCCESS ;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
byte AES::cbc_encrypt (byte * plain, byte * cipher, int n_block, byte iv [N_BLOCK])
|
||||
{
|
||||
while (n_block--) {
|
||||
xor_block (iv, plain) ;
|
||||
if (encrypt (iv, iv) != AES_SUCCESS) {
|
||||
return AES_FAILURE ;
|
||||
}
|
||||
copy_n_bytes (cipher, iv, N_BLOCK) ;
|
||||
plain += N_BLOCK ;
|
||||
cipher += N_BLOCK ;
|
||||
}
|
||||
return AES_SUCCESS ;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
byte AES::cbc_encrypt (byte * plain, byte * cipher, int n_block)
|
||||
{
|
||||
while (n_block--) {
|
||||
xor_block (iv, plain) ;
|
||||
if (encrypt (iv, iv) != AES_SUCCESS) {
|
||||
return AES_FAILURE ;
|
||||
}
|
||||
copy_n_bytes (cipher, iv, N_BLOCK) ;
|
||||
plain += N_BLOCK ;
|
||||
cipher += N_BLOCK ;
|
||||
}
|
||||
return AES_SUCCESS ;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
byte AES::decrypt (byte cipher [N_BLOCK], byte plain [N_BLOCK])
|
||||
{
|
||||
if (round) {
|
||||
byte s1 [N_BLOCK] ;
|
||||
copy_and_key (s1, cipher, (byte*) (key_sched + round * N_BLOCK)) ;
|
||||
inv_shift_sub_rows (s1) ;
|
||||
|
||||
for (byte r = round ; --r ; ) {
|
||||
byte s2 [N_BLOCK] ;
|
||||
copy_and_key (s2, s1, (byte*) (key_sched + r * N_BLOCK)) ;
|
||||
inv_mix_sub_columns (s1, s2) ;
|
||||
}
|
||||
copy_and_key (plain, s1, (byte*) (key_sched)) ;
|
||||
} else {
|
||||
return AES_FAILURE ;
|
||||
}
|
||||
return AES_SUCCESS ;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
byte AES::cbc_decrypt (byte * cipher, byte * plain, int n_block, byte iv [N_BLOCK])
|
||||
{
|
||||
while (n_block--) {
|
||||
byte tmp [N_BLOCK] ;
|
||||
copy_n_bytes (tmp, cipher, N_BLOCK) ;
|
||||
if (decrypt (cipher, plain) != AES_SUCCESS) {
|
||||
return AES_FAILURE ;
|
||||
}
|
||||
xor_block (plain, iv) ;
|
||||
copy_n_bytes (iv, tmp, N_BLOCK) ;
|
||||
plain += N_BLOCK ;
|
||||
cipher += N_BLOCK;
|
||||
}
|
||||
return AES_SUCCESS ;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
byte AES::cbc_decrypt (byte * cipher, byte * plain, int n_block)
|
||||
{
|
||||
while (n_block--) {
|
||||
byte tmp [N_BLOCK] ;
|
||||
copy_n_bytes (tmp, cipher, N_BLOCK) ;
|
||||
if (decrypt (cipher, plain) != AES_SUCCESS) {
|
||||
return AES_FAILURE ;
|
||||
}
|
||||
xor_block (plain, iv) ;
|
||||
copy_n_bytes (iv, tmp, N_BLOCK) ;
|
||||
plain += N_BLOCK ;
|
||||
cipher += N_BLOCK;
|
||||
}
|
||||
return AES_SUCCESS ;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void AES::set_IV(unsigned long long int IVCl)
|
||||
{
|
||||
memcpy(iv,&IVCl,8);
|
||||
memcpy(iv+8,&IVCl,8);
|
||||
IVC = IVCl;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void AES::iv_inc()
|
||||
{
|
||||
IVC += 1;
|
||||
memcpy(iv,&IVC,8);
|
||||
memcpy(iv+8,&IVC,8);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
int AES::get_size()
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void AES::set_size(int sizel)
|
||||
{
|
||||
size = sizel;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void AES::get_IV(byte *out)
|
||||
{
|
||||
memcpy(out,&IVC,8);
|
||||
memcpy(out+8,&IVC,8);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void AES::calc_size_n_pad(int p_size)
|
||||
{
|
||||
int s_of_p = p_size - 1;
|
||||
if ( s_of_p % N_BLOCK == 0) {
|
||||
size = s_of_p;
|
||||
} else {
|
||||
size = s_of_p + (N_BLOCK-(s_of_p % N_BLOCK));
|
||||
}
|
||||
pad = size - s_of_p;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void AES::padPlaintext(void* in,byte* out)
|
||||
{
|
||||
memcpy(out,in,size);
|
||||
for (int i = size-pad; i < size; i++) {
|
||||
;
|
||||
out[i] = arr_pad[pad - 1];
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
bool AES::CheckPad(byte* in,int lsize)
|
||||
{
|
||||
if (in[lsize-1] <= 0x0f) {
|
||||
int lpad = (int)in[lsize-1];
|
||||
for (int i = lsize - 1; i >= lsize-lpad; i--) {
|
||||
if (arr_pad[lpad - 1] != in[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void AES::printArray(byte output[],bool p_pad)
|
||||
{
|
||||
uint8_t i,j;
|
||||
uint8_t loops = size/N_BLOCK;
|
||||
uint8_t outp = N_BLOCK;
|
||||
for (j = 0; j < loops; j += 1) {
|
||||
if (p_pad && (j == (loops - 1)) ) {
|
||||
outp = N_BLOCK - pad;
|
||||
}
|
||||
for (i = 0; i < outp; i++) {
|
||||
printf_P(PSTR("%c"),output[j*N_BLOCK + i]);
|
||||
}
|
||||
}
|
||||
printf_P(PSTR("\n"));
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void AES::printArray(byte output[],int sizel)
|
||||
{
|
||||
for (int i = 0; i < sizel; i++) {
|
||||
printf_P(PSTR("%x"),output[i]);
|
||||
}
|
||||
printf_P(PSTR("\n"));
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void AES::do_aes_encrypt(byte *plain,int size_p,byte *cipher,byte *key, int bits,
|
||||
byte ivl [N_BLOCK])
|
||||
{
|
||||
calc_size_n_pad(size_p);
|
||||
byte plain_p[get_size()];
|
||||
padPlaintext(plain,plain_p);
|
||||
int blocks = get_size() / N_BLOCK;
|
||||
set_key (key, bits) ;
|
||||
cbc_encrypt (plain_p, cipher, blocks, ivl);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void AES::do_aes_encrypt(byte *plain,int size_p,byte *cipher,byte *key, int bits)
|
||||
{
|
||||
calc_size_n_pad(size_p);
|
||||
byte plain_p[get_size()];
|
||||
padPlaintext(plain,plain_p);
|
||||
int blocks = get_size() / N_BLOCK;
|
||||
set_key (key, bits) ;
|
||||
cbc_encrypt (plain_p, cipher, blocks);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void AES::do_aes_decrypt(byte *cipher,int size_c,byte *plain,byte *key, int bits,
|
||||
byte ivl [N_BLOCK])
|
||||
{
|
||||
set_size(size_c);
|
||||
int blocks = size_c / N_BLOCK;
|
||||
set_key (key, bits);
|
||||
cbc_decrypt (cipher,plain, blocks, ivl);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void AES::do_aes_decrypt(byte *cipher,int size_c,byte *plain,byte *key, int bits)
|
||||
{
|
||||
set_size(size_c);
|
||||
int blocks = size_c / N_BLOCK;
|
||||
set_key (key, bits);
|
||||
cbc_decrypt (cipher,plain, blocks);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
#if defined(AES_LINUX)
|
||||
double AES::millis()
|
||||
{
|
||||
gettimeofday(&tv, NULL);
|
||||
return (tv.tv_sec + 0.000001 * tv.tv_usec);
|
||||
}
|
||||
#endif
|
||||
@@ -1,381 +0,0 @@
|
||||
#ifndef __AES_H__
|
||||
#define __AES_H__
|
||||
|
||||
#include "AES_config.h"
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
1. source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
2. binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation;
|
||||
|
||||
3. the name of the copyright holder is not used to endorse products
|
||||
built using this software without specific written permission.
|
||||
|
||||
DISCLAIMER
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its properties, including, but not limited to, correctness
|
||||
and/or fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue 09/09/2006
|
||||
|
||||
This is an AES implementation that uses only 8-bit byte operations on the
|
||||
cipher state.
|
||||
*/
|
||||
|
||||
/* code was modified by george spanos <spaniakos@gmail.com>
|
||||
* 16/12/14
|
||||
*/
|
||||
/** AES class */
|
||||
class AES
|
||||
{
|
||||
public:
|
||||
|
||||
/* The following calls are for a precomputed key schedule
|
||||
|
||||
NOTE: If the length_type used for the key length is an
|
||||
unsigned 8-bit character, a key length of 256 bits must
|
||||
be entered as a length in bytes (valid inputs are hence
|
||||
128, 192, 16, 24 and 32).
|
||||
*/
|
||||
/** \fn AES()
|
||||
* \brief AES constructor
|
||||
*
|
||||
* This function initialized an instance of AES.
|
||||
*/
|
||||
AES();
|
||||
|
||||
/** Set the cipher key for the pre-keyed version.
|
||||
* @param key[] pointer to the key string.
|
||||
* @param keylen Integer that indicates the length of the key.
|
||||
* @note NOTE: If the length_type used for the key length is an unsigned 8-bit character,
|
||||
* a key length of 256 bits must be entered as a length in bytes
|
||||
* (valid inputs are hence 128, 192, 16, 24 and 32).
|
||||
*
|
||||
*/
|
||||
byte set_key (byte key[], int keylen) ;
|
||||
|
||||
/** clean up subkeys after use.
|
||||
*
|
||||
*/
|
||||
void clean () ; // delete key schedule after use
|
||||
|
||||
/** copying and xoring utilities.
|
||||
* @param *AESt byte pointer of the AEStination array.
|
||||
* @param *src byte pointer of the source array.
|
||||
* @param n byte, indicating the sizeof the bytes to be copied.
|
||||
* @note this is an alternative for memcpy(void *s1,const void *s2, site_t n),
|
||||
* i have not updated the function in the implementation yet, but it is considered a future plan.
|
||||
*
|
||||
*/
|
||||
void copy_n_bytes (byte * AESt, byte * src, byte n) ;
|
||||
|
||||
/** Encrypt a single block of 16 bytes .
|
||||
* @param plain Array of the plaintext.
|
||||
* @param cipher Array of the ciphertext.
|
||||
* @note The N_BLOCK is defined in AES_config.h as,
|
||||
* @code #define N_ROW 4
|
||||
* #define N_COL 4
|
||||
* #define N_BLOCK (N_ROW * N_COL)
|
||||
* @endcode
|
||||
* Changed to that will change the Block_size.
|
||||
* @return 0 if SUCCESS or -1 if FAILURE
|
||||
*
|
||||
*/
|
||||
byte encrypt (byte plain [N_BLOCK], byte cipher [N_BLOCK]) ;
|
||||
|
||||
/** CBC encrypt a number of blocks (input and return an IV).
|
||||
*
|
||||
* @param *plain Pointer, points to the plaintex.
|
||||
* @param *cipher Pointer, points to the ciphertext that will be created.
|
||||
* @param n_block integer, indicated the number of blocks to be ciphered.
|
||||
* @param iv byte Array that holds the IV (initialization vector).
|
||||
* @return 0 if SUCCESS or -1 if FAILURE
|
||||
*
|
||||
*/
|
||||
byte cbc_encrypt (byte * plain, byte * cipher, int n_block, byte iv [N_BLOCK]) ;
|
||||
|
||||
/** CBC encrypt a number of blocks (input and return an IV).
|
||||
*
|
||||
* @param *plain Pointer, points to the plaintex.
|
||||
* @param *cipher Pointer, points to the ciphertext that will be created.
|
||||
* @param n_block integer, indicated the number of blocks to be ciphered.
|
||||
* @return 0 if SUCCESS or -1 if FAILURE
|
||||
*
|
||||
*/
|
||||
byte cbc_encrypt (byte * plain, byte * cipher, int n_block) ;
|
||||
|
||||
|
||||
/** Decrypt a single block of 16 bytes
|
||||
* @param cipher Array of the ciphertext.
|
||||
* @param plain Array of the plaintext.
|
||||
* @note The N_BLOCK is defined in AES_config.h as,
|
||||
* @code #define N_ROW 4
|
||||
* #define N_COL 4
|
||||
* #define N_BLOCK (N_ROW * N_COL)
|
||||
* @endcode
|
||||
* Changed to that will change the Block_size.
|
||||
* @return 0 if SUCCESS or -1 if FAILURE
|
||||
*
|
||||
*/
|
||||
byte decrypt (byte cipher [N_BLOCK], byte plain [N_BLOCK]) ;
|
||||
|
||||
/** CBC decrypt a number of blocks (input and return an IV)
|
||||
*
|
||||
* @param *cipher Pointer, points to the ciphertext that will be created.
|
||||
* @param *plain Pointer, points to the plaintex.
|
||||
* @param n_block integer, indicated the number of blocks to be ciphered.
|
||||
* @param iv byte Array that holds the IV (initialization vector).
|
||||
* @return 0 if SUCCESS or -1 if FAILURE
|
||||
*
|
||||
*/
|
||||
byte cbc_decrypt (byte * cipher, byte * plain, int n_block, byte iv [N_BLOCK]) ;
|
||||
|
||||
/** CBC decrypt a number of blocks (input and return an IV)
|
||||
*
|
||||
* @param *cipher Pointer, points to the ciphertext that will be created.
|
||||
* @param *plain Pointer, points to the plaintex.
|
||||
* @param n_block integer, indicated the number of blocks to be ciphered.
|
||||
* @return 0 if SUCCESS or -1 if FAILURE
|
||||
*
|
||||
*/
|
||||
byte cbc_decrypt (byte * cipher, byte * plain, int n_block) ;
|
||||
|
||||
/** Sets IV (initialization vector) and IVC (IV counter).
|
||||
* This function changes the ivc and iv variables needed for AES.
|
||||
*
|
||||
* @param IVCl int or hex value of iv , ex. 0x0000000000000001
|
||||
* @note example:
|
||||
* @code unsigned long long int my_iv = 01234567; @endcode
|
||||
*/
|
||||
void set_IV(unsigned long long int IVCl);
|
||||
|
||||
/** increase the iv (initialization vector) and IVC (IV counter) by 1
|
||||
*
|
||||
* This function increased the VI by one step in order to have a different IV each time
|
||||
*
|
||||
*/
|
||||
void iv_inc();
|
||||
|
||||
/** Getter method for size
|
||||
*
|
||||
* This function return the size
|
||||
* @return an integer, that is the size of the of the padded plaintext,
|
||||
* thus, the size of the ciphertext.
|
||||
*/
|
||||
int get_size();
|
||||
|
||||
/** Setter method for size
|
||||
*
|
||||
* This function sets the size of the plaintext+pad
|
||||
*
|
||||
*/
|
||||
void set_size(int sizel);
|
||||
|
||||
/** Getter method for IV
|
||||
*
|
||||
* This function return the IV
|
||||
* @param out byte pointer that gets the IV.
|
||||
* @return none, the IV is writed to the out pointer.
|
||||
*/
|
||||
void get_IV(byte *out);
|
||||
|
||||
/** Calculates the size of the plaintext and the padding.
|
||||
*
|
||||
* Calculates the size of theplaintext with the padding
|
||||
* and the size of the padding needed. Moreover it stores them in their class variables.
|
||||
*
|
||||
* @param p_size the size of the byte array ex sizeof(plaintext)
|
||||
*/
|
||||
void calc_size_n_pad(int p_size);
|
||||
|
||||
/** Pads the plaintext
|
||||
*
|
||||
* This function pads the plaintext and returns an char array with the
|
||||
* plaintext and the padding in order for the plaintext to be compatible with
|
||||
* 16bit size blocks required by AES
|
||||
*
|
||||
* @param in the string of the plaintext in a byte array
|
||||
* @param out The string of the out array.
|
||||
* @return no return, The padded plaintext is stored in the out pointer.
|
||||
*/
|
||||
void padPlaintext(void* in,byte* out);
|
||||
|
||||
/** Check the if the padding is correct.
|
||||
*
|
||||
* This functions checks the padding of the plaintext.
|
||||
*
|
||||
* @param in the string of the plaintext in a byte array
|
||||
* @param size the size of the string
|
||||
* @return true if correct / false if not
|
||||
*/
|
||||
bool CheckPad(byte* in,int size);
|
||||
|
||||
/** Prints the array given.
|
||||
*
|
||||
* This function prints the given array and pad,
|
||||
* It is mainlly used for debugging purpuses or to output the string.
|
||||
*
|
||||
* @param output[] the string of the text in a byte array
|
||||
* @param p_pad optional, used to print with out the padding characters
|
||||
*/
|
||||
void printArray(byte output[],bool p_pad = true);
|
||||
|
||||
/** Prints the array given.
|
||||
*
|
||||
* This function prints the given array in Hexadecimal.
|
||||
*
|
||||
* @param output[] the string of the text in a byte array
|
||||
* @param sizel the size of the array.
|
||||
*/
|
||||
void printArray(byte output[],int sizel);
|
||||
|
||||
/** User friendly implementation of AES-CBC encryption.
|
||||
*
|
||||
* @param *plain pointer to the plaintext
|
||||
* @param size_p size of the plaintext
|
||||
* @param *cipher pointer to the ciphertext
|
||||
* @param *key pointer to the key that will be used.
|
||||
* @param bits bits of the encryption/decrpytion
|
||||
* @param ivl the initialization vector IV that will be used for encryption.
|
||||
* @note The key will be stored in class variable.
|
||||
*/
|
||||
void do_aes_encrypt(byte *plain,int size_p,byte *cipher,byte *key, int bits, byte ivl [N_BLOCK]);
|
||||
|
||||
/** User friendly implementation of AES-CBC encryption.
|
||||
*
|
||||
* @param *plain pointer to the plaintext
|
||||
* @param size_p size of the plaintext
|
||||
* @param *cipher pointer to the ciphertext
|
||||
* @param *key pointer to the key that will be used.
|
||||
* @param bits bits of the encryption/decrpytion
|
||||
* @note The key will be stored in class variable.
|
||||
*/
|
||||
void do_aes_encrypt(byte *plain,int size_p,byte *cipher,byte *key, int bits);
|
||||
|
||||
/** User friendly implementation of AES-CBC decryption.
|
||||
*
|
||||
* @param *cipher pointer to the ciphertext
|
||||
* @param size_c size of the ciphertext
|
||||
* @param *plain pointer to the plaintext
|
||||
* @param *key pointer to the key that will be used.
|
||||
* @param bits bits of the encryption/decrpytion
|
||||
* @param ivl the initialization vector IV that will be used for decryption.
|
||||
* @note The key will be stored in class variable.
|
||||
*/
|
||||
void do_aes_decrypt(byte *cipher,int size_c,byte *plain,byte *key, int bits, byte ivl [N_BLOCK]);
|
||||
|
||||
/** User friendly implementation of AES-CBC decryption.
|
||||
*
|
||||
* @param *cipher pointer to the ciphertext
|
||||
* @param size_c size of the ciphertext
|
||||
* @param *plain pointer to the plaintext
|
||||
* @param *key pointer to the key that will be used.
|
||||
* @param bits bits of the encryption/decrpytion
|
||||
* @note The key will be stored in class variable.
|
||||
*/
|
||||
void do_aes_decrypt(byte *cipher,int size_c,byte *plain,byte *key, int bits);
|
||||
|
||||
#if defined(AES_LINUX)
|
||||
/**
|
||||
* used in linux in order to retrieve the time in milliseconds.
|
||||
*
|
||||
* @return returns the milliseconds in a double format.
|
||||
*/
|
||||
double millis();
|
||||
#endif
|
||||
private:
|
||||
int round ;/**< holds the number of rounds to be used. */
|
||||
byte key_sched [KEY_SCHEDULE_BYTES]
|
||||
;/**< holds the pre-computed key for the encryption/decrpytion. */
|
||||
unsigned long long int IVC;/**< holds the initialization vector counter in numerical format. */
|
||||
byte iv[16];/**< holds the initialization vector that will be used in the cipher. */
|
||||
int pad;/**< holds the size of the padding. */
|
||||
int size;/**< hold the size of the plaintext to be ciphered */
|
||||
#if defined(AES_LINUX)
|
||||
timeval tv;/**< holds the time value on linux */
|
||||
byte arr_pad[15];/**< holds the hexadecimal padding values on linux */
|
||||
#else
|
||||
byte arr_pad[15];// = { 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };/**< holds the hexadecimal padding values */
|
||||
#endif
|
||||
} ;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup aeslib AES library for Arduino and Raspberry pi
|
||||
* @ingroup internals
|
||||
*
|
||||
* @section AesGoals design Goals
|
||||
*
|
||||
* This library is AESigned to be...
|
||||
* @li Fast and efficient.
|
||||
* @li Able to effectively encrypt and decrypt any size of string.
|
||||
* @li Able to encrypt and decrypt using AES
|
||||
* @li Able to encrypt and decrypt using AES-CBC
|
||||
* @li Easy for the user to use in his programs.
|
||||
*
|
||||
* @section Acknowledgements Acknowledgements
|
||||
* This is an AES library for the Arduino, based on tzikis's AES library, which you can find <a href= "https://github.com/tzikis/arduino">here:</a>.<br />
|
||||
* Tzikis library was based on scottmac`s library, which you can find <a href="https://github.com/scottmac/arduino">here:</a><br />
|
||||
*
|
||||
* @section Installation Installation
|
||||
* <h3>Arduino</h3>
|
||||
* Create a folder named _AES_ in the _libraries_ folder inside your Arduino sketch folder. If the
|
||||
* libraries folder doesn't exist, create it. Then copy everything inside. (re)launch the Arduino IDE.<br />
|
||||
* You're done. Time for a mojito
|
||||
*
|
||||
* <h3>Raspberry pi</h3>
|
||||
* <b>install</b><br /><br />
|
||||
*
|
||||
* sudo make install<br />
|
||||
* cd examples_Rpi<br />
|
||||
* make<br /><br />
|
||||
*
|
||||
* <b>What to do after changes to the library</b><br /><br />
|
||||
* sudo make clean<br />
|
||||
* sudo make install<br />
|
||||
* cd examples_Rpi<br />
|
||||
* make clean<br />
|
||||
* make<br /><br />
|
||||
* <b>What to do after changes to a sketch</b><br /><br />
|
||||
* cd examples_Rpi<br />
|
||||
* make \<sketch\><br /><br />
|
||||
* or <br />
|
||||
* make clean<br />
|
||||
* make<br /><br /><br />
|
||||
* <b>How to start a sketch</b><br /><br />
|
||||
* cd examples_Rpi<br />
|
||||
* sudo ./\<sketch\><br /><br />
|
||||
*
|
||||
* @section AesNews News
|
||||
*
|
||||
* If issues are discovered with the documentation, please report them <a href="https://github.com/spaniakos/spaniakos.github.io/issues"> here</a>
|
||||
* @section AesUseful Useful References
|
||||
*
|
||||
* Please refer to:
|
||||
*
|
||||
* @li <a href="http://spaniakos.github.io/AES/classAES.html"><b>AES</b> Class Documentation</a>
|
||||
* @li <a href="https://github.com/spaniakos/AES/archive/master.zip"><b>Download</b></a>
|
||||
* @li <a href="https://github.com/spaniakos/AES/"><b>Source Code</b></a>
|
||||
* @li <a href="http://spaniakos.github.io/">All spaniakos Documentation Main Page</a>
|
||||
*
|
||||
* @section AesBoard_Support Board Support
|
||||
*
|
||||
* Most standard Arduino based boards are supported:
|
||||
* - Arduino
|
||||
* - Intel Galileo support
|
||||
* - Raspberry Pi Support
|
||||
*
|
||||
* - The library has not been tested to other boards, but it should suppport ATMega 328 based boards,Mega Boards,Arduino Due,ATTiny board
|
||||
*/
|
||||
@@ -1,50 +0,0 @@
|
||||
/* code was modified by george spanos <spaniakos@gmail.com>
|
||||
* 16/12/14
|
||||
*/
|
||||
|
||||
#ifndef __AES_CONFIG_H__
|
||||
#define __AES_CONFIG_H__
|
||||
|
||||
#if (defined(__linux) || defined(linux)) && !defined(__ARDUINO_X86__)
|
||||
|
||||
#define AES_LINUX
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#include <Arduino.h>
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(__ARDUINO_X86__) || (defined (__linux) || defined (linux))
|
||||
#undef PROGMEM
|
||||
#define PROGMEM __attribute__(( section(".progmem.data") ))
|
||||
#define pgm_read_byte(p) (*(p))
|
||||
typedef unsigned char byte;
|
||||
#define printf_P printf
|
||||
#define PSTR(x) (x)
|
||||
#elif defined(ARDUINO_ARCH_ESP8266)
|
||||
#include <pgmspace.h>
|
||||
#elif defined(ARDUINO_ARCH_ESP32)
|
||||
#include <pgmspace.h>
|
||||
#elif defined(ARDUINO_ARCH_SAMD)
|
||||
#define printf_P printf
|
||||
#else
|
||||
#include <avr/pgmspace.h>
|
||||
#endif
|
||||
|
||||
#define N_ROW 4
|
||||
#define N_COL 4
|
||||
#define N_BLOCK (N_ROW * N_COL)
|
||||
#define N_MAX_ROUNDS 14
|
||||
#define KEY_SCHEDULE_BYTES ((N_MAX_ROUNDS + 1) * N_BLOCK)
|
||||
#define AES_SUCCESS (0)
|
||||
#define AES_FAILURE (-1)
|
||||
|
||||
#endif
|
||||
@@ -1,91 +0,0 @@
|
||||
### Arduino
|
||||
just run the sketched aftel loading the libraries.
|
||||
|
||||
### Raspberry pi
|
||||
install
|
||||
```
|
||||
sudo make install
|
||||
cd examples_Rpi
|
||||
make
|
||||
```
|
||||
|
||||
What to do after changes to the library
|
||||
```
|
||||
sudo make clean
|
||||
sudo make install
|
||||
cd examples_Rpi
|
||||
make clean
|
||||
make
|
||||
```
|
||||
|
||||
What to do after changes to a sketch
|
||||
```
|
||||
cd examples_Rpi
|
||||
make <sketch>
|
||||
|
||||
or
|
||||
make clean
|
||||
make
|
||||
```
|
||||
|
||||
How to start a sketch
|
||||
```
|
||||
cd examples_Rpi
|
||||
sudo ./<sketch>
|
||||
```
|
||||
|
||||
This is a derived work from Brian Gladman's AES implementation for byte-oriented
|
||||
processors, here's the licence terms:
|
||||
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
1. source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
2. binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation;
|
||||
|
||||
3. the name of the copyright holder is not used to endorse products
|
||||
built using this software without specific written permission.
|
||||
|
||||
DISCLAIMER
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its properties, including, but not limited to, correctness
|
||||
and/or fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue 09/09/2006
|
||||
|
||||
This is an AES implementation that uses only 8-bit byte operations on the
|
||||
cipher state (there are options to use 32-bit types if available).
|
||||
|
||||
The combination of mix columns and byte substitution used here is based on
|
||||
that developed by Karl Malbrain. His contribution is acknowledged.
|
||||
*/
|
||||
|
||||
/* This version derived by Mark Tillotson 2012-01-23, tidied up, slimmed down
|
||||
and tailored to 8-bit microcontroller abilities and Arduino datatypes.
|
||||
|
||||
The s-box and inverse s-box were retained as tables (0.5kB PROGMEM) but all
|
||||
the other transformations are coded to save table space. Many efficiency
|
||||
improvments to the routines mix_sub_columns() and inv_mix_sub_columns()
|
||||
(mainly common sub-expression elimination).
|
||||
|
||||
Only the routines with precalculated subkey schedule are retained (together
|
||||
with set_key() - this does however mean each AES object takes 240 bytes of
|
||||
RAM, alas)
|
||||
|
||||
The CBC routines side-effect the iv argument (so that successive calls work
|
||||
together correctly).
|
||||
|
||||
All the encryption and decryption routines work with plain == cipher for
|
||||
in-place encryption, note.
|
||||
|
||||
*/
|
||||
@@ -1,7 +0,0 @@
|
||||
AES KEYWORD1
|
||||
set_key KEYWORD2
|
||||
clean KEYWORD2
|
||||
encrypt KEYWORD2
|
||||
decrypt KEYWORD2
|
||||
cbc_encrypt KEYWORD2
|
||||
cbc_decrypt KEYWORD2
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* The MySensors Arduino library handles the wireless radio link and protocol
|
||||
* between your home built sensors/actuators and HA controller of choice.
|
||||
* The sensors forms a self healing radio network with optional repeaters. Each
|
||||
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
|
||||
* network topology allowing messages to be routed to nodes.
|
||||
*
|
||||
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
|
||||
* Copyright (C) 2013-2019 Sensnology AB
|
||||
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
|
||||
*
|
||||
* Documentation: http://www.mysensors.org
|
||||
* Support Forum: http://forum.mysensors.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "hmac_sha256.h"
|
||||
|
||||
void SHA256HMACInit(const uint8_t *key, size_t keyLength)
|
||||
{
|
||||
(void)memset((void *)&SHA256keyBuffer, 0x00, BLOCK_LENGTH);
|
||||
if (keyLength > BLOCK_LENGTH) {
|
||||
// Hash long keys
|
||||
SHA256Init();
|
||||
SHA256Add(key, keyLength);
|
||||
SHA256Result(SHA256keyBuffer);
|
||||
} else {
|
||||
// Block length keys are used as is
|
||||
(void)memcpy((void *)SHA256keyBuffer, (const void *)key, keyLength);
|
||||
}
|
||||
// Start inner hash
|
||||
SHA256Init();
|
||||
for (uint8_t i = 0; i < BLOCK_LENGTH; i++) {
|
||||
SHA256Add(SHA256keyBuffer[i] ^ HMAC_IPAD);
|
||||
}
|
||||
}
|
||||
|
||||
void SHA256HMACAdd(const uint8_t data)
|
||||
{
|
||||
SHA256Add(data);
|
||||
}
|
||||
|
||||
void SHA256HMACAdd(const uint8_t *data, size_t dataLength)
|
||||
{
|
||||
SHA256Add(data, dataLength);
|
||||
}
|
||||
|
||||
void SHA256HMACResult(uint8_t *dest)
|
||||
{
|
||||
uint8_t innerHash[HASH_LENGTH];
|
||||
// Complete inner hash
|
||||
SHA256Result(innerHash);
|
||||
// Calculate outer hash
|
||||
SHA256Init();
|
||||
for (uint8_t i = 0; i < BLOCK_LENGTH; i++) {
|
||||
SHA256Add(SHA256keyBuffer[i] ^ HMAC_OPAD);
|
||||
}
|
||||
SHA256Add(innerHash, HASH_LENGTH);
|
||||
SHA256Result(dest);
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* The MySensors Arduino library handles the wireless radio link and protocol
|
||||
* between your home built sensors/actuators and HA controller of choice.
|
||||
* The sensors forms a self healing radio network with optional repeaters. Each
|
||||
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
|
||||
* network topology allowing messages to be routed to nodes.
|
||||
*
|
||||
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
|
||||
* Copyright (C) 2013-2019 Sensnology AB
|
||||
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
|
||||
*
|
||||
* Documentation: http://www.mysensors.org
|
||||
* Support Forum: http://forum.mysensors.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _HMAC_SHA256_
|
||||
#define _HMAC_SHA256_
|
||||
|
||||
#define HMAC_IPAD 0x36 //!< HMAC_IPAD
|
||||
#define HMAC_OPAD 0x5c //!< HMAC_OPAD
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,173 +0,0 @@
|
||||
/*
|
||||
* The MySensors Arduino library handles the wireless radio link and protocol
|
||||
* between your home built sensors/actuators and HA controller of choice.
|
||||
* The sensors forms a self healing radio network with optional repeaters. Each
|
||||
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
|
||||
* network topology allowing messages to be routed to nodes.
|
||||
*
|
||||
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
|
||||
* Copyright (C) 2013-2019 Sensnology AB
|
||||
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
|
||||
*
|
||||
* Documentation: http://www.mysensors.org
|
||||
* Support Forum: http://forum.mysensors.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sha256.h"
|
||||
|
||||
const uint32_t SHA256K[] PROGMEM = {
|
||||
0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,
|
||||
0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,
|
||||
0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,
|
||||
0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,
|
||||
0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,
|
||||
0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,
|
||||
0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,
|
||||
0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
|
||||
};
|
||||
|
||||
const uint8_t SHA256InitState[] PROGMEM = {
|
||||
0x67,0xe6,0x09,0x6a, // H0
|
||||
0x85,0xae,0x67,0xbb, // H1
|
||||
0x72,0xf3,0x6e,0x3c, // H2
|
||||
0x3a,0xf5,0x4f,0xa5, // H3
|
||||
0x7f,0x52,0x0e,0x51, // H4
|
||||
0x8c,0x68,0x05,0x9b, // H5
|
||||
0xab,0xd9,0x83,0x1f, // H6
|
||||
0x19,0xcd,0xe0,0x5b // H7
|
||||
};
|
||||
|
||||
_SHA256buffer_t SHA256buffer;
|
||||
uint8_t SHA256bufferOffset;
|
||||
_SHA256state_t SHA256state;
|
||||
uint32_t SHA256byteCount;
|
||||
uint8_t SHA256keyBuffer[BLOCK_LENGTH];
|
||||
|
||||
void SHA256Init(void)
|
||||
{
|
||||
(void)memcpy_P((void *)&SHA256state.b, (const void *)&SHA256InitState, 32);
|
||||
SHA256byteCount = 0;
|
||||
SHA256bufferOffset = 0;
|
||||
}
|
||||
|
||||
uint32_t SHA256ror32(const uint32_t number, const uint8_t bits)
|
||||
{
|
||||
return ((number << (32 - bits)) | (number >> bits));
|
||||
}
|
||||
|
||||
void SHA256hashBlock(void)
|
||||
{
|
||||
uint32_t a, b, c, d, e, f, g, h, t1, t2;
|
||||
|
||||
a = SHA256state.w[0];
|
||||
b = SHA256state.w[1];
|
||||
c = SHA256state.w[2];
|
||||
d = SHA256state.w[3];
|
||||
e = SHA256state.w[4];
|
||||
f = SHA256state.w[5];
|
||||
g = SHA256state.w[6];
|
||||
h = SHA256state.w[7];
|
||||
|
||||
for (uint8_t i = 0; i < 64; i++) {
|
||||
if (i >= 16) {
|
||||
t1 = SHA256buffer.w[i & 15] + SHA256buffer.w[(i - 7) & 15];
|
||||
t2 = SHA256buffer.w[(i - 2) & 15];
|
||||
t1 += SHA256ror32(t2, 17) ^ SHA256ror32(t2, 19) ^ (t2 >> 10);
|
||||
t2 = SHA256buffer.w[(i - 15) & 15];
|
||||
t1 += SHA256ror32(t2, 7) ^ SHA256ror32(t2, 18) ^ (t2 >> 3);
|
||||
SHA256buffer.w[i & 15] = t1;
|
||||
}
|
||||
t1 = h;
|
||||
t1 += SHA256ror32(e, 6) ^ SHA256ror32(e, 11) ^ SHA256ror32(e, 25); // ∑1(e)
|
||||
t1 += g ^ (e & (g ^ f)); // Ch(e,f,g)
|
||||
t1 += pgm_read_dword(SHA256K + i); // Ki
|
||||
t1 += SHA256buffer.w[i & 15]; // Wi
|
||||
t2 = SHA256ror32(a, 2) ^ SHA256ror32(a, 13) ^ SHA256ror32(a, 22); // ∑0(a)
|
||||
t2 += ((b & c) | (a & (b | c))); // Maj(a,b,c)
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + t1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = t1 + t2;
|
||||
}
|
||||
SHA256state.w[0] += a;
|
||||
SHA256state.w[1] += b;
|
||||
SHA256state.w[2] += c;
|
||||
SHA256state.w[3] += d;
|
||||
SHA256state.w[4] += e;
|
||||
SHA256state.w[5] += f;
|
||||
SHA256state.w[6] += g;
|
||||
SHA256state.w[7] += h;
|
||||
}
|
||||
|
||||
void SHA256addUncounted(const uint8_t data)
|
||||
{
|
||||
SHA256buffer.b[SHA256bufferOffset ^ 3] = data;
|
||||
SHA256bufferOffset++;
|
||||
if (SHA256bufferOffset == BLOCK_LENGTH) {
|
||||
SHA256hashBlock();
|
||||
SHA256bufferOffset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SHA256Add(const uint8_t data)
|
||||
{
|
||||
SHA256byteCount++;
|
||||
SHA256addUncounted(data);
|
||||
}
|
||||
|
||||
void SHA256Add(const uint8_t *data, size_t dataLength)
|
||||
{
|
||||
while (dataLength--) {
|
||||
SHA256Add(*data++);
|
||||
}
|
||||
}
|
||||
|
||||
void SHA256Result(uint8_t *dest)
|
||||
{
|
||||
// Pad to complete the last block
|
||||
SHA256addUncounted(0x80);
|
||||
while (SHA256bufferOffset != 56) {
|
||||
SHA256addUncounted(0x00);
|
||||
}
|
||||
|
||||
// Append length in the last 8 bytes
|
||||
SHA256addUncounted(0); // We're only using 32 bit lengths
|
||||
SHA256addUncounted(0); // But SHA-1 supports 64 bit lengths
|
||||
SHA256addUncounted(0); // So zero pad the top bits
|
||||
SHA256addUncounted(SHA256byteCount >> 29); // Shifting to multiply by 8
|
||||
SHA256addUncounted(SHA256byteCount >> 21); // as SHA-1 supports bitstreams as well as
|
||||
SHA256addUncounted(SHA256byteCount >> 13); // byte.
|
||||
SHA256addUncounted(SHA256byteCount >> 5);
|
||||
SHA256addUncounted(SHA256byteCount << 3);
|
||||
|
||||
// Swap byte order back
|
||||
for (uint8_t i = 0; i<8; i++) {
|
||||
uint32_t a, b;
|
||||
a = SHA256state.w[i];
|
||||
b = a << 24;
|
||||
b |= (a << 8) & 0x00ff0000;
|
||||
b |= (a >> 8) & 0x0000ff00;
|
||||
b |= a >> 24;
|
||||
SHA256state.w[i] = b;
|
||||
}
|
||||
(void)memcpy((void *)dest, (const void *)SHA256state.b, 32);
|
||||
// Return pointer to hash (20 characters)
|
||||
//return SHA256state.b;
|
||||
}
|
||||
|
||||
void SHA256(uint8_t *dest, const uint8_t *data, size_t dataLength)
|
||||
{
|
||||
SHA256Init();
|
||||
SHA256Add(data, dataLength);
|
||||
SHA256Result(dest);
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* The MySensors Arduino library handles the wireless radio link and protocol
|
||||
* between your home built sensors/actuators and HA controller of choice.
|
||||
* The sensors forms a self healing radio network with optional repeaters. Each
|
||||
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
|
||||
* network topology allowing messages to be routed to nodes.
|
||||
*
|
||||
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
|
||||
* Copyright (C) 2013-2019 Sensnology AB
|
||||
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
|
||||
*
|
||||
* Documentation: http://www.mysensors.org
|
||||
* Support Forum: http://forum.mysensors.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _SHA256_H_
|
||||
#define _SHA256_H_
|
||||
|
||||
#define HASH_LENGTH 32 //!< HASH_LENGTH
|
||||
#define BLOCK_LENGTH 64 //!< BLOCK_LENGTH
|
||||
|
||||
/**
|
||||
* @brief buffer for SHA256 calculator
|
||||
*/
|
||||
union _SHA256buffer_t {
|
||||
uint8_t b[BLOCK_LENGTH]; //!< SHA256 b
|
||||
uint32_t w[BLOCK_LENGTH / 4]; //!< SHA256 w
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief state variables for SHA256 calculator
|
||||
*/
|
||||
union _SHA256state_t {
|
||||
uint8_t b[HASH_LENGTH]; //!< SHA256 b
|
||||
uint32_t w[HASH_LENGTH / 4]; //!< SHA256 w
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user