0
Offline
Tesla Member
Karma: 71
Posts: 6624
Arduino rocks
|
 |
« on: January 25, 2012, 01:51:11 pm » |
I've written an AES (Advanced Encryption Standard) library for Arduino. It supports 128, 192 and 256 bit key sizes. Code space overhead is about 4KB I think, each instance requires 240 bytes RAM for subkeys. Fairly tightly coded and checked against official test vectors for ECB mode. Also CBC mode supported. Its derived from Brian Gladman's implementation for byte-oriented processors but signficantly modified. See the README and examples. Functions: byte set_key (byte key[], int keylen) ; void clean () ; // delete key schedule after use void copy_n_bytes (byte * dest, byte * src, byte n) ;
byte encrypt (byte plain [N_BLOCK], byte cipher [N_BLOCK]) ; byte cbc_encrypt (byte * plain, byte * cipher, int n_block, byte iv [N_BLOCK]) ;
byte decrypt (byte cipher [N_BLOCK], byte plain [N_BLOCK]) ; byte cbc_decrypt (byte * cipher, byte * plain, int n_block, byte iv [N_BLOCK]) ;
Lives here: http://utter.chaos.org.uk:/~markt/AES-library.zipFeedback welcome.
|
|
|
|
|
Logged
|
|
|
|
|
Netherlands
Offline
Tesla Member
Karma: 90
Posts: 9401
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #1 on: January 25, 2012, 04:47:36 pm » |
Nice work, not tested it (if i only had time ...),
have you tried it in communication (serial/ethernet/SD/...) yet? especially with other device PC/Mac/pinguin
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Tesla Member
Karma: 71
Posts: 6624
Arduino rocks
|
 |
« Reply #2 on: January 25, 2012, 08:46:40 pm » |
Its tested against many of the test-vectors (key varying, plaintext varying, Monte Carlo), which is the only contract it needs to fulfil... I've some speed/timing information now:
128 bit, key setup 0.37ms 128 bit, ECB, encryption 0.58ms / block (27.5kB/s) 128 bit, ECB, decryption 0.77ms / block (20.5kB/s)
192 bit, key setup 0.41ms 192 bit, ECB, encryption 0.71ms / block (22.5kB/s) 192 bit, ECB, decryption 0.92ms / block (17.5kB/s)
256 bit, key setup 0.52ms 256 bit, ECB, encryption 0.82ms / block (19.5kB/s) 256 bit, ECB, decryption 1.09ms / block (14.5kB/s)
(CBC modes are a little slower than ECB)
(All ATmega328p, 16MHz)
|
|
|
|
|
Logged
|
|
|
|
|
Netherlands
Offline
Tesla Member
Karma: 90
Posts: 9401
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #3 on: January 28, 2012, 06:25:15 am » |
good speed, given that the Arduino/Mega only have a few KB of RAM, it can encode total RAM within a second.
Arduino can make approx 9000 (18KB) of analogRead samples per second [ @100% ] so I think it can keep up with 3-4000 samples/second.
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Tesla Member
Karma: 71
Posts: 6624
Arduino rocks
|
 |
« Reply #4 on: January 28, 2012, 08:00:45 am » |
Glad you like it. Next project is elliptic curve public key cryptography! (Only half joking)
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 8
|
 |
« Reply #5 on: January 16, 2013, 05:21:35 pm » |
Thank you so much for this extremely useful library. I'm not too "up" on C. Would you have any examples on encrypting a string that is longer than the N_BLOCK?
I have hit a stumbling block (no pun intended), and am trying multi-dimentional arrays to create blocks for encrypting/decrypting - I haven't gotten it working so am not even sure if plain and cipher will always be the same length.
|
|
|
|
|
Logged
|
|
|
|
|
Netherlands
Offline
Tesla Member
Karma: 90
Posts: 9401
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #6 on: January 17, 2013, 12:22:15 pm » |
you make a loop that takes n_BLOCK bytes per iteration of the character array until all chars are done. (you might need to pad the last block with zero's or so).
|
|
|
|
|
Logged
|
|
|
|
|
SF Bay Area (USA)
Offline
Faraday Member
Karma: 78
Posts: 5454
Strongly opinionated, but not official!
|
 |
« Reply #7 on: January 17, 2013, 08:52:11 pm » |
Note that AES is a block hash, not suitable for encrypting bulk data simply by dividing the data into blocks and encrypting each one with the same key. That would open up all sorts of flaws and vulnerabilities. typically you use something like "cipher block chaining" or "random ctr-mode" that generate separate xor keys for each block of data, BASED on your AES key. Essentially you need a library like openSSL on top of AES before you have something more than a mathematical curiosity.
"Cryptography is hard."
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 8
|
 |
« Reply #8 on: January 19, 2013, 05:26:04 am » |
Not looking to encrypt bulk data, just more than 16 characters each time.
|
|
|
|
|
Logged
|
|
|
|
|
SF Bay Area (USA)
Offline
Faraday Member
Karma: 78
Posts: 5454
Strongly opinionated, but not official!
|
 |
« Reply #9 on: January 20, 2013, 03:57:40 am » |
"bulk" means more than the native block size, in this case. For example, if you were to just run AES with your key on each block, an attacked could immediately tell whether both blocks were the same, which would be a terrible thing from a cryptographic point of view. Random-ctr mode consists of picking a random number (N) the same size as a block, and then running THAT through AES with your key to give you something to xor with the first 16 bytes, and then AES(N+1, k) to get something to xor with the second 16 bytes, and so on. (then you transmit N at the start of your message.) Aside from it being a bit tricky to generate 128bit random numbers, it should be TOO hard.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 8
|
 |
« Reply #10 on: January 20, 2013, 11:12:17 am » |
Thanks to robtillaart for putting me on the right track. Fundamental mistake on my part. When transferring string value to char array, I needed to size array to str.length() + 1 and also null terminate the final element.
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Tesla Member
Karma: 71
Posts: 6624
Arduino rocks
|
 |
« Reply #11 on: January 20, 2013, 05:36:58 pm » |
Thank you so much for this extremely useful library. I'm not too "up" on C. Would you have any examples on encrypting a string that is longer than the N_BLOCK?
I have hit a stumbling block (no pun intended), and am trying multi-dimentional arrays to create blocks for encrypting/decrypting - I haven't gotten it working so am not even sure if plain and cipher will always be the same length.
Assuming you have padded your plaintext up to a whole number of blocks "blockcount", and assuming ciphertext is a byte array long enough for that amount of data, and that iv is a block's worth of initialization vector, the encryption call is success_flag = aes.cbc_encrypt (plaintext, ciphertext, blockcount, iv); Similarly for cbc_decrypt. If "iv" and "padding" don't mean anything to you you will need to read up about block cipher encryption modes - all details matter. These routines side-effect the iv argument to perform chaining (meaning they can be called repeatedly on groups of blocks without having to pass around a chaning block explicitly).
|
|
|
|
|
Logged
|
|
|
|
|
SF Bay Area (USA)
Offline
Faraday Member
Karma: 78
Posts: 5454
Strongly opinionated, but not official!
|
 |
« Reply #12 on: January 22, 2013, 03:37:44 am » |
I apologize for not noticing that the library already has a CBC-mode function. That's (one possibility) for what should be used to encrypt more than one block worth of data.
|
|
|
|
|
Logged
|
|
|
|
|
|