]> AND Private Git Repository - Cipher_code.git/blob - Arduino/libraries/Arduino-crypto-master/Crypto.h
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
SCPRNG
[Cipher_code.git] / Arduino / libraries / Arduino-crypto-master / Crypto.h
1 /**
2  * An extremely minimal crypto library for Arduino devices.
3  * 
4  * The SHA256 and AES implementations are derived from axTLS 
5  * (http://axtls.sourceforge.net/), Copyright (c) 2008, Cameron Rich.
6  * 
7  * Ported and refactored by Chris Ellis 2016.
8  * 
9  */
10
11 #ifndef CRYPTO_h
12 #define CRYPTO_h
13
14 #include <Arduino.h>
15 #include <osapi.h>
16
17 #define SHA256_SIZE             32
18 #define SHA256HMAC_SIZE         32
19 #define SHA256HMAC_BLOCKSIZE    64
20 #define AES_MAXROUNDS           14
21 #define AES_BLOCKSIZE           16
22 #define AES_IV_SIZE             16
23 #define AES_IV_LENGTH           16
24 #define AES_128_KEY_LENGTH      16
25 #define AES_256_KEY_LENGTH      16
26
27 /**
28  * Compute a SHA256 hash
29  */
30 class SHA256
31 {
32     public:
33         SHA256();
34         /**
35          * Update the hash with new data
36          */
37         void doUpdate(const byte *msg, int len);
38         void doUpdate(const char *msg, unsigned int len) { doUpdate((byte*) msg, len); }
39         void doUpdate(const char *msg) { doUpdate((byte*) msg, strlen(msg)); }
40         /**
41          * Compute the final hash and store it in [digest], digest must be 
42          * at least 32 bytes
43          */
44         void doFinal(byte *digest);
45         /**
46          * Compute the final hash and check it matches this given expected hash
47          */
48         bool matches(const byte *expected);
49     private:
50         void SHA256_Process(const byte digest[64]);
51         uint32_t total[2];
52         uint32_t state[8];
53         uint8_t  buffer[64];
54 };
55
56 #define HMAC_OPAD 0x5C
57 #define HMAC_IPAD 0x36
58
59 /**
60  * Compute a HMAC using SHA256
61  */
62 class SHA256HMAC
63 {
64     public:
65         /**
66          * Compute a SHA256 HMAC with the given [key] key of [length] bytes 
67          * for authenticity
68          */
69         SHA256HMAC(const byte *key, unsigned int keyLen);
70         /**
71          * Update the hash with new data
72          */
73         void doUpdate(const byte *msg, unsigned int len);
74         void doUpdate(const char *msg, unsigned int len) { doUpdate((byte*) msg, len); }
75         void doUpdate(const char *msg) { doUpdate((byte*) msg, strlen(msg)); }
76         /**
77          * Compute the final hash and store it in [digest], digest must be 
78          * at least 32 bytes
79          */
80         void doFinal(byte *digest);
81         /**
82          * Compute the final hash and check it matches this given expected hash
83          */
84         bool matches(const byte *expected);
85     private:
86         void blockXor(const byte *in, byte *out, byte val, byte len);
87         SHA256 _hash;
88         byte _innerKey[SHA256HMAC_BLOCKSIZE];
89         byte _outerKey[SHA256HMAC_BLOCKSIZE];
90 };
91
92 /**
93  * AES 128 and 256, based on code from axTLS
94  */
95 class AES
96 {
97     public:
98         typedef enum
99         {
100             AES_MODE_128,
101             AES_MODE_256
102         } AES_MODE;
103         typedef enum
104         {
105             CIPHER_ENCRYPT = 0x01,
106             CIPHER_DECRYPT = 0x02
107         } CIPHER_MODE;
108         /**
109          * Create this cipher instance in either encrypt or decrypt mode
110          * 
111          * Use the given [key] which must be 16 bytes long for AES 128 and 
112          *  32 bytes for AES 256
113          * 
114          * Use the given [iv] initialistion vection which must be 16 bytes long
115          * 
116          * Use the either AES 128 or AES 256 as specified by [mode]
117          * 
118          * Either encrypt or decrypt as specified by [cipherMode]
119          */
120         AES(const uint8_t *key, const uint8_t *iv, AES_MODE mode, CIPHER_MODE cipherMode);
121         /**
122          * Either encrypt or decrypt [in] and store into [out] for [length] bytes.
123          * 
124          * Note: the length must be a multiple of 16 bytes
125          */
126         void process(const uint8_t *in, uint8_t *out, int length);
127         void encryptCTR(const uint8_t *in, uint8_t *out, int length);
128         void encryptCBC(const uint8_t *in, uint8_t *out, int length);
129         void decryptCBC(const uint8_t *in, uint8_t *out, int length);
130         void convertKey();
131     private:
132
133         void encrypt(uint32_t *data);
134         void decrypt(uint32_t *data);
135         uint16_t _rounds;
136         uint16_t _key_size;
137         uint32_t _ks[(AES_MAXROUNDS+1)*8];
138         uint8_t _iv[AES_IV_SIZE];
139         CIPHER_MODE _cipherMode;
140 };
141
142 /**
143  * ESP8266 specific random number generator
144  */
145 class RNG
146 {
147     public:
148         /**
149          * Fill the [dst] array with [length] random bytes
150          */
151         static void fill(uint8_t *dst, unsigned int length);
152         /**
153          * Get a random byte
154          */
155         static byte get();
156         /**
157          * Get a 32bit random number
158          */
159         static uint32_t getLong();
160     private:
161 };
162
163 #endif