diff options
author | Mateusz Maciaś <ursereg@gmail.com> | 2011-11-23 09:48:34 +0100 |
---|---|---|
committer | Mateusz Maciaś <ursereg@gmail.com> | 2011-11-23 09:48:34 +0100 |
commit | ef93596f77911b1611c447371cc10f6275bdbf7f (patch) | |
tree | 2c1de970678846072b5b9ffccbba42cd6d6013c8 | |
parent | a17533aa1c57995af0cf96f747ed118d406fd298 (diff) | |
download | doorman-ef93596f77911b1611c447371cc10f6275bdbf7f.tar.gz doorman-ef93596f77911b1611c447371cc10f6275bdbf7f.tar.bz2 doorman-ef93596f77911b1611c447371cc10f6275bdbf7f.tar.xz doorman-ef93596f77911b1611c447371cc10f6275bdbf7f.zip |
Added Sha arduino library since it different from upstream version.
See: http://code.google.com/p/cryptosuite/issues/detail?id=2
-rw-r--r-- | libraries/Sha/examples/hmacsha256test/hmacsha256test.pde | 120 | ||||
-rw-r--r-- | libraries/Sha/examples/sha1test/sha1test.pde | 131 | ||||
-rw-r--r-- | libraries/Sha/examples/sha256test/sha256test.pde | 144 | ||||
-rw-r--r-- | libraries/Sha/keywords.txt | 40 | ||||
-rw-r--r-- | libraries/Sha/readme.txt | 39 | ||||
-rw-r--r-- | libraries/Sha/sha1.cpp | 168 | ||||
-rw-r--r-- | libraries/Sha/sha1.h | 61 | ||||
-rw-r--r-- | libraries/Sha/sha256.cpp | 186 | ||||
-rw-r--r-- | libraries/Sha/sha256.h | 60 |
9 files changed, 949 insertions, 0 deletions
diff --git a/libraries/Sha/examples/hmacsha256test/hmacsha256test.pde b/libraries/Sha/examples/hmacsha256test/hmacsha256test.pde new file mode 100644 index 0000000..e7b925e --- /dev/null +++ b/libraries/Sha/examples/hmacsha256test/hmacsha256test.pde @@ -0,0 +1,120 @@ +/** + * Cryptosuite - A cryptographic library for Arduino + * Copyright (C) 2010 Peter Knight (Cathedrow) + * + * 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 "sha256.h" + +uint8_t hmacKey1[]={ + 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b +}; +uint8_t hmacKey2[]={ + 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14, + 0x15,0x16,0x17,0x18,0x19 +}; +uint8_t hmacKey3[]={ + 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa +}; +uint8_t hmacKey4[]={ + 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c +}; +uint8_t hmacKey5[]={ + 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa, + 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa, + 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa, + 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa, + 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa, + 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa, + 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa +}; + +void printHash(uint8_t* hash) { + int i; + for (i=0; i<32; i++) { + Serial.print("0123456789abcdef"[hash[i]>>4]); + Serial.print("0123456789abcdef"[hash[i]&0xf]); + } + Serial.println(); +} + +void setup() { + uint8_t* hash; + uint32_t a; + + Serial.begin(9600); + + // HMAC tests + Serial.println("Test: RFC4231 4.2"); + Serial.println("Expect:b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7"); + Serial.print("Result:"); + Sha256.initHmac(hmacKey1,20); + Sha256.print("Hi There"); + printHash(Sha256.resultHmac()); + Serial.println(); + + Serial.println("Test: RFC4231 4.3"); + Serial.println("Expect:5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843"); + Serial.print("Result:"); + Sha256.initHmac((uint8_t*)"Jefe",4); + Sha256.print("what do ya want for nothing?"); + printHash(Sha256.resultHmac()); + Serial.println(); + + Serial.println("Test: RFC4231 4.4"); + Serial.println("Expect:773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe"); + Serial.print("Result:"); + Sha256.initHmac(hmacKey3,20); + for (a=0; a<50; a++) Sha256.write(0xdd); + printHash(Sha256.resultHmac()); + Serial.println(); + + Serial.println("Test: RFC4231 4.5"); + Serial.println("Expect:82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b"); + Serial.print("Result:"); + Sha256.initHmac(hmacKey2,25); + for (a=0; a<50; a++) Sha256.write(0xcd); + printHash(Sha256.resultHmac()); + Serial.println(); + + Serial.println("Test: RFC4231 4.6"); + Serial.println("Expect:a3b6167473100ee06e0c796c2955552b-------------------------------"); + Serial.print("Result:"); + Sha256.initHmac(hmacKey4,20); + Sha256.print("Test With Truncation"); + printHash(Sha256.resultHmac()); + Serial.println(); + + Serial.println("Test: RFC4231 4.7"); + Serial.println("Expect:60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54"); + Serial.print("Result:"); + Sha256.initHmac(hmacKey5,131); + Sha256.print("Test Using Larger Than Block-Size Key - Hash Key First"); + printHash(Sha256.resultHmac()); + Serial.println(); + + Serial.println("Test: RFC4231 4.8"); + Serial.println("Expect:9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2"); + Serial.print("Result:"); + Sha256.initHmac(hmacKey5,131); + Sha256.print("This is a test using a larger than block-size key and a larger than " + "block-size data. The key needs to be hashed before being used by the HMAC algorithm."); + printHash(Sha256.resultHmac()); + Serial.println(); + +} + +void loop() { +}
\ No newline at end of file diff --git a/libraries/Sha/examples/sha1test/sha1test.pde b/libraries/Sha/examples/sha1test/sha1test.pde new file mode 100644 index 0000000..9fd205b --- /dev/null +++ b/libraries/Sha/examples/sha1test/sha1test.pde @@ -0,0 +1,131 @@ +/** + * Cryptosuite - A cryptographic library for Arduino + * Copyright (C) 2010 Peter Knight (Cathedrow) + * + * 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 "sha1.h" + +void printHash(uint8_t* hash) { + int i; + for (i=0; i<20; i++) { + Serial.print("0123456789abcdef"[hash[i]>>4]); + Serial.print("0123456789abcdef"[hash[i]&0xf]); + } + Serial.println(); +} + +uint8_t hmacKey1[]={ + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, + 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f +}; +uint8_t hmacKey2[]={ + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x40,0x41,0x42,0x43 +}; +uint8_t hmacKey3[]={ + 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f, + 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f, + 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f, + 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f, + 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f, + 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf, + 0xb0,0xb1,0xb2,0xb3 +}; +uint8_t hmacKey4[]={ + 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f, + 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f, + 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f, + 0xa0 +}; + + +void setup() { + uint8_t* hash; + uint32_t a; + + Serial.begin(9600); + + // SHA tests + Serial.println("Test: FIPS 180-2 C.1 and RFC3174 7.3 TEST1"); + Serial.println("Expect:a9993e364706816aba3e25717850c26c9cd0d89d"); + Serial.print("Result:"); + Sha1.init(); + Sha1.print("abc"); + printHash(Sha1.result()); + Serial.println(); + + Serial.println("Test: FIPS 180-2 C.2 and RFC3174 7.3 TEST2"); + Serial.println("Expect:84983e441c3bd26ebaae4aa1f95129e5e54670f1"); + Serial.print("Result:"); + Sha1.init(); + Sha1.print("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"); + printHash(Sha1.result()); + Serial.println(); + + Serial.println("Test: RFC3174 7.3 TEST4"); + Serial.println("Expect:dea356a2cddd90c7a7ecedc5ebb563934f460452"); + Serial.print("Result:"); + Sha1.init(); + for (a=0; a<80; a++) Sha1.print("01234567"); + printHash(Sha1.result()); + Serial.println(); + + // HMAC tests + Serial.println("Test: FIPS 198a A.1"); + Serial.println("Expect:4f4ca3d5d68ba7cc0a1208c9c61e9c5da0403c0a"); + Serial.print("Result:"); + Sha1.initHmac(hmacKey1,64); + Sha1.print("Sample #1"); + printHash(Sha1.resultHmac()); + Serial.println(); + + Serial.println("Test: FIPS 198a A.2"); + Serial.println("Expect:0922d3405faa3d194f82a45830737d5cc6c75d24"); + Serial.print("Result:"); + Sha1.initHmac(hmacKey2,20); + Sha1.print("Sample #2"); + printHash(Sha1.resultHmac()); + Serial.println(); + + Serial.println("Test: FIPS 198a A.3"); + Serial.println("Expect:bcf41eab8bb2d802f3d05caf7cb092ecf8d1a3aa"); + Serial.print("Result:"); + Sha1.initHmac(hmacKey3,100); + Sha1.print("Sample #3"); + printHash(Sha1.resultHmac()); + Serial.println(); + + Serial.println("Test: FIPS 198a A.4"); + Serial.println("Expect:9ea886efe268dbecce420c7524df32e0751a2a26"); + Serial.print("Result:"); + Sha1.initHmac(hmacKey4,49); + Sha1.print("Sample #4"); + printHash(Sha1.resultHmac()); + Serial.println(); + + // Long tests + Serial.println("Test: FIPS 180-2 C.3 and RFC3174 7.3 TEST3 (Processing 1000000 characters. This will take a while.)"); + Serial.println("Expect:34aa973cd4c4daa4f61eeb2bdbad27316534016f"); + Serial.print("Result:"); + Sha1.init(); + for (a=0; a<1000000; a++) Sha1.write('a'); + printHash(Sha1.result()); +} + +void loop() { +}
\ No newline at end of file diff --git a/libraries/Sha/examples/sha256test/sha256test.pde b/libraries/Sha/examples/sha256test/sha256test.pde new file mode 100644 index 0000000..2f9b932 --- /dev/null +++ b/libraries/Sha/examples/sha256test/sha256test.pde @@ -0,0 +1,144 @@ +/** + * Cryptosuite - A cryptographic library for Arduino + * Copyright (C) 2010 Peter Knight (Cathedrow) + * + * 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 "sha256.h" + +uint8_t hmacKey1[]={ + 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b +}; +uint8_t hmacKey2[]={ + 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14, + 0x15,0x16,0x17,0x18,0x19 +}; +uint8_t hmacKey3[]={ + 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa +}; +uint8_t hmacKey4[]={ + 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c +}; +uint8_t hmacKey5[]={ + 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa, + 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa, + 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa, + 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa, + 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa, + 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa, + 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa +}; + +void printHash(uint8_t* hash) { + int i; + for (i=0; i<32; i++) { + Serial.print("0123456789abcdef"[hash[i]>>4]); + Serial.print("0123456789abcdef"[hash[i]&0xf]); + } + Serial.println(); +} + +void setup() { + uint8_t* hash; + uint32_t a; + + Serial.begin(9600); + + // SHA tests + Serial.println("Test: FIPS 180-2 B.1"); + Serial.println("Expect:ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"); + Serial.print("Result:"); + Sha256.init(); + Sha256.print("abc"); + printHash(Sha256.result()); + Serial.println(); + + Serial.println("Test: FIPS 180-2 B.2"); + Serial.println("Expect:248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1"); + Serial.print("Result:"); + Sha256.init(); + Sha256.print("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"); + printHash(Sha256.result()); + Serial.println(); + + // HMAC tests + Serial.println("Test: RFC4231 4.2"); + Serial.println("Expect:b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7"); + Serial.print("Result:"); + Sha256.initHmac(hmacKey1,20); + Sha256.print("Hi There"); + printHash(Sha256.resultHmac()); + Serial.println(); + + Serial.println("Test: RFC4231 4.3"); + Serial.println("Expect:5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843"); + Serial.print("Result:"); + Sha256.initHmac((uint8_t*)"Jefe",4); + Sha256.print("what do ya want for nothing?"); + printHash(Sha256.resultHmac()); + Serial.println(); + + Serial.println("Test: RFC4231 4.4"); + Serial.println("Expect:773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe"); + Serial.print("Result:"); + Sha256.initHmac(hmacKey3,20); + for (a=0; a<50; a++) Sha256.write(0xdd); + printHash(Sha256.resultHmac()); + Serial.println(); + + Serial.println("Test: RFC4231 4.5"); + Serial.println("Expect:82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b"); + Serial.print("Result:"); + Sha256.initHmac(hmacKey2,25); + for (a=0; a<50; a++) Sha256.write(0xcd); + printHash(Sha256.resultHmac()); + Serial.println(); + + Serial.println("Test: RFC4231 4.6"); + Serial.println("Expect:a3b6167473100ee06e0c796c2955552b-------------------------------"); + Serial.print("Result:"); + Sha256.initHmac(hmacKey4,20); + Sha256.print("Test With Truncation"); + printHash(Sha256.resultHmac()); + Serial.println(); + + Serial.println("Test: RFC4231 4.7"); + Serial.println("Expect:60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54"); + Serial.print("Result:"); + Sha256.initHmac(hmacKey5,131); + Sha256.print("Test Using Larger Than Block-Size Key - Hash Key First"); + printHash(Sha256.resultHmac()); + Serial.println(); + + Serial.println("Test: RFC4231 4.8"); + Serial.println("Expect:9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2"); + Serial.print("Result:"); + Sha256.initHmac(hmacKey5,131); +// Sha256.print("This is a test using a larger than block-size key and a larger than " +// "block-size data. The key needs to be hashed before being used by the HMAC algorithm."); + printHash(Sha256.resultHmac()); + Serial.println(); + + // Long tests + Serial.println("Test: FIPS 180-2 B.3 (Processing 1000000 characters. This will take a while.)"); + Serial.println("Expect:cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0"); + Serial.print("Result:"); + Sha256.init(); + for (a=0; a<1000000; a++) Sha256.write('a'); + printHash(Sha256.result()); +} + +void loop() { +}
\ No newline at end of file diff --git a/libraries/Sha/keywords.txt b/libraries/Sha/keywords.txt new file mode 100644 index 0000000..a48af9b --- /dev/null +++ b/libraries/Sha/keywords.txt @@ -0,0 +1,40 @@ +# Cryptosuite - A cryptographic library for Arduino +# Copyright (C) 2010 Peter Knight (Cathedrow) +# +# 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/>. + +####################################### +# Syntax Coloring Map For Cryptolib +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### +Sha1 KEYWORD1 +Sha256 KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +init KEYWORD2 +initHmac KEYWORD2 +add KEYWORD2 +result KEYWORD2 +resultHmac KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### + diff --git a/libraries/Sha/readme.txt b/libraries/Sha/readme.txt new file mode 100644 index 0000000..bf1dbd8 --- /dev/null +++ b/libraries/Sha/readme.txt @@ -0,0 +1,39 @@ +Cryptosuite - A cryptographic library for Arduino +Copyright (C) 2010 Peter Knight (Cathedrow) + +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/>. + + +SHA implements secure hash functions that can be used for cryptography, data integrity and security purposes. + +Sha covers the following standards: + SHA-1 (FIPS 180-2) + SHA-256 (FIPS 180-2) + HMAC-SHA-1 (FIPS 198a) + HMAC-SHA-256 (FIPS 198a) + +What is a hash function? + A hash function takes a message, and generates a number. + A good hash function has the following properties: + The number is large enough that you will never find two messages with the same number (a 'collision') + It is computationally unfeasible to extract message information from its hash (without trying every possible combination) + A small (1 bit) change in the message will produce a huge (approximately half of all bits) change in the hash. + Fast to calculate + + SHA is slower than simple hashes (eg. parity), but has very high security - high enough to be used in currency transactions and confidential documents. + SHA-1 is currently secure, but there is some suggestion it may not be for much longer. + SHA-256 is slightly slower, but has higher security. + +What is an HMAC? + HMACs are Hashed Message Authentication Codes. Using them, it is possible to prove that you have a secret key without actually disclosing it. diff --git a/libraries/Sha/sha1.cpp b/libraries/Sha/sha1.cpp new file mode 100644 index 0000000..cd03684 --- /dev/null +++ b/libraries/Sha/sha1.cpp @@ -0,0 +1,168 @@ +/** + * Cryptosuite - A cryptographic library for Arduino + * Copyright (C) 2010 Peter Knight (Cathedrow) + * + * 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 <string.h> +#include <avr/io.h> +#include <avr/pgmspace.h> +#include "sha1.h" + +#define SHA1_K0 0x5a827999 +#define SHA1_K20 0x6ed9eba1 +#define SHA1_K40 0x8f1bbcdc +#define SHA1_K60 0xca62c1d6 + +const uint8_t sha1InitState[] PROGMEM = { + 0x01,0x23,0x45,0x67, // H0 + 0x89,0xab,0xcd,0xef, // H1 + 0xfe,0xdc,0xba,0x98, // H2 + 0x76,0x54,0x32,0x10, // H3 + 0xf0,0xe1,0xd2,0xc3 // H4 +}; + +void Sha1Class::init(void) { + memcpy_P(state.b,sha1InitState,HASH_LENGTH); + byteCount = 0; + bufferOffset = 0; +} + +uint32_t Sha1Class::rol32(uint32_t number, uint8_t bits) { + return ((number << bits) | (number >> (32-bits))); +} + +void Sha1Class::hashBlock() { + uint8_t i; + uint32_t a,b,c,d,e,t; + + a=state.w[0]; + b=state.w[1]; + c=state.w[2]; + d=state.w[3]; + e=state.w[4]; + for (i=0; i<80; i++) { + if (i>=16) { + t = buffer.w[(i+13)&15] ^ buffer.w[(i+8)&15] ^ buffer.w[(i+2)&15] ^ buffer.w[i&15]; + buffer.w[i&15] = rol32(t,1); + } + if (i<20) { + t = (d ^ (b & (c ^ d))) + SHA1_K0; + } else if (i<40) { + t = (b ^ c ^ d) + SHA1_K20; + } else if (i<60) { + t = ((b & c) | (d & (b | c))) + SHA1_K40; + } else { + t = (b ^ c ^ d) + SHA1_K60; + } + t+=rol32(a,5) + e + buffer.w[i&15]; + e=d; + d=c; + c=rol32(b,30); + b=a; + a=t; + } + state.w[0] += a; + state.w[1] += b; + state.w[2] += c; + state.w[3] += d; + state.w[4] += e; +} + +void Sha1Class::addUncounted(uint8_t data) { + buffer.b[bufferOffset ^ 3] = data; + bufferOffset++; + if (bufferOffset == BLOCK_LENGTH) { + hashBlock(); + bufferOffset = 0; + } +} + +void Sha1Class::write(uint8_t data) { + ++byteCount; + addUncounted(data); +} + +void Sha1Class::pad() { + // Implement SHA-1 padding (fips180-2 §5.1.1) + + // Pad with 0x80 followed by 0x00 until the end of the block + addUncounted(0x80); + while (bufferOffset != 56) addUncounted(0x00); + + // Append length in the last 8 bytes + addUncounted(0); // We're only using 32 bit lengths + addUncounted(0); // But SHA-1 supports 64 bit lengths + addUncounted(0); // So zero pad the top bits + addUncounted(byteCount >> 29); // Shifting to multiply by 8 + addUncounted(byteCount >> 21); // as SHA-1 supports bitstreams as well as + addUncounted(byteCount >> 13); // byte. + addUncounted(byteCount >> 5); + addUncounted(byteCount << 3); +} + + +uint8_t* Sha1Class::result(void) { + // Pad to complete the last block + pad(); + + // Swap byte order back + for (int i=0; i<5; i++) { + uint32_t a,b; + a=state.w[i]; + b=a<<24; + b|=(a<<8) & 0x00ff0000; + b|=(a>>8) & 0x0000ff00; + b|=a>>24; + state.w[i]=b; + } + + // Return pointer to hash (20 characters) + return state.b; +} + +#define HMAC_IPAD 0x36 +#define HMAC_OPAD 0x5c + +void Sha1Class::initHmac(const uint8_t* key, int keyLength) { + uint8_t i; + memset(keyBuffer,0,BLOCK_LENGTH); + if (keyLength > BLOCK_LENGTH) { + // Hash long keys + init(); + for (;keyLength--;) write(*key++); + memcpy(keyBuffer,result(),HASH_LENGTH); + } else { + // Block length keys are used as is + memcpy(keyBuffer,key,keyLength); + } + // Start inner hash + init(); + for (i=0; i<BLOCK_LENGTH; i++) { + write(keyBuffer[i] ^ HMAC_IPAD); + } +} + +uint8_t* Sha1Class::resultHmac(void) { + uint8_t i; + // Complete inner hash + memcpy(innerHash,result(),HASH_LENGTH); + // Calculate outer hash + init(); + for (i=0; i<BLOCK_LENGTH; i++) write(keyBuffer[i] ^ HMAC_OPAD); + for (i=0; i<HASH_LENGTH; i++) write(innerHash[i]); + return result(); +} +Sha1Class Sha1; diff --git a/libraries/Sha/sha1.h b/libraries/Sha/sha1.h new file mode 100644 index 0000000..2493676 --- /dev/null +++ b/libraries/Sha/sha1.h @@ -0,0 +1,61 @@ +/** + * Cryptosuite - A cryptographic library for Arduino + * Copyright (C) 2010 Peter Knight (Cathedrow) + * + * 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 Sha1_h +#define Sha1_h + +#include <inttypes.h> +#include "Print.h" + +#define HASH_LENGTH 20 +#define BLOCK_LENGTH 64 + +union _buffer { + uint8_t b[BLOCK_LENGTH]; + uint32_t w[BLOCK_LENGTH/4]; +}; +union _state { + uint8_t b[HASH_LENGTH]; + uint32_t w[HASH_LENGTH/4]; +}; + +class Sha1Class : public Print +{ + public: + void init(void); + void initHmac(const uint8_t* secret, int secretLength); + uint8_t* result(void); + uint8_t* resultHmac(void); + virtual void write(uint8_t); + using Print::write; + private: + void pad(); + void addUncounted(uint8_t data); + void hashBlock(); + uint32_t rol32(uint32_t number, uint8_t bits); + _buffer buffer; + uint8_t bufferOffset; + _state state; + uint32_t byteCount; + uint8_t keyBuffer[BLOCK_LENGTH]; + uint8_t innerHash[HASH_LENGTH]; + +}; +extern Sha1Class Sha1; + +#endif diff --git a/libraries/Sha/sha256.cpp b/libraries/Sha/sha256.cpp new file mode 100644 index 0000000..b0c7a94 --- /dev/null +++ b/libraries/Sha/sha256.cpp @@ -0,0 +1,186 @@ +/** + * Cryptosuite - A cryptographic library for Arduino + * Copyright (C) 2010 Peter Knight (Cathedrow) + * + * 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 <string.h> +#include <avr/io.h> +#include <avr/pgmspace.h> +#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 +}; + +#define BUFFER_SIZE 64 + +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 +}; + +void Sha256Class::init(void) { + memcpy_P(state.b,sha256InitState,32); + byteCount = 0; + bufferOffset = 0; +} + +uint32_t Sha256Class::ror32(uint32_t number, uint8_t bits) { + return ((number << (32-bits)) | (number >> bits)); +} + +void Sha256Class::hashBlock() { + uint8_t i; + uint32_t a,b,c,d,e,f,g,h,t1,t2; + + a=state.w[0]; + b=state.w[1]; + c=state.w[2]; + d=state.w[3]; + e=state.w[4]; + f=state.w[5]; + g=state.w[6]; + h=state.w[7]; + + for (i=0; i<64; i++) { + if (i>=16) { + t1 = buffer.w[i&15] + buffer.w[(i-7)&15]; + t2 = buffer.w[(i-2)&15]; + t1 += ror32(t2,17) ^ ror32(t2,19) ^ (t2>>10); + t2 = buffer.w[(i-15)&15]; + t1 += ror32(t2,7) ^ ror32(t2,18) ^ (t2>>3); + buffer.w[i&15] = t1; + } + t1 = h; + t1 += ror32(e,6) ^ ror32(e,11) ^ ror32(e,25); // ∑1(e) + t1 += g ^ (e & (g ^ f)); // Ch(e,f,g) + t1 += pgm_read_dword(sha256K+i); // Ki + t1 += buffer.w[i&15]; // Wi + t2 = ror32(a,2) ^ ror32(a,13) ^ ror32(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; + } + state.w[0] += a; + state.w[1] += b; + state.w[2] += c; + state.w[3] += d; + state.w[4] += e; + state.w[5] += f; + state.w[6] += g; + state.w[7] += h; +} + +void Sha256Class::addUncounted(uint8_t data) { + buffer.b[bufferOffset ^ 3] = data; + bufferOffset++; + if (bufferOffset == BUFFER_SIZE) { + hashBlock(); + bufferOffset = 0; + } +} + +void Sha256Class::write(uint8_t data) { + ++byteCount; + addUncounted(data); +} + +void Sha256Class::pad() { + // Implement SHA-256 padding (fips180-2 §5.1.1) + + // Pad with 0x80 followed by 0x00 until the end of the block + addUncounted(0x80); + while (bufferOffset != 56) addUncounted(0x00); + + // Append length in the last 8 bytes + addUncounted(0); // We're only using 32 bit lengths + addUncounted(0); // But SHA-1 supports 64 bit lengths + addUncounted(0); // So zero pad the top bits + addUncounted(byteCount >> 29); // Shifting to multiply by 8 + addUncounted(byteCount >> 21); // as SHA-1 supports bitstreams as well as + addUncounted(byteCount >> 13); // byte. + addUncounted(byteCount >> 5); + addUncounted(byteCount << 3); +} + + +uint8_t* Sha256Class::result(void) { + // Pad to complete the last block + pad(); + + // Swap byte order back + for (int i=0; i<8; i++) { + uint32_t a,b; + a=state.w[i]; + b=a<<24; + b|=(a<<8) & 0x00ff0000; + b|=(a>>8) & 0x0000ff00; + b|=a>>24; + state.w[i]=b; + } + + // Return pointer to hash (20 characters) + return state.b; +} + +#define HMAC_IPAD 0x36 +#define HMAC_OPAD 0x5c + +uint8_t keyBuffer[BLOCK_LENGTH]; // K0 in FIPS-198a +uint8_t innerHash[HASH_LENGTH]; + +void Sha256Class::initHmac(const uint8_t* key, int keyLength) { + uint8_t i; + memset(keyBuffer,0,BLOCK_LENGTH); + if (keyLength > BLOCK_LENGTH) { + // Hash long keys + init(); + for (;keyLength--;) write(*key++); + memcpy(keyBuffer,result(),HASH_LENGTH); + } else { + // Block length keys are used as is + memcpy(keyBuffer,key,keyLength); + } + // Start inner hash + init(); + for (i=0; i<BLOCK_LENGTH; i++) { + write(keyBuffer[i] ^ HMAC_IPAD); + } +} + +uint8_t* Sha256Class::resultHmac(void) { + uint8_t i; + // Complete inner hash + memcpy(innerHash,result(),HASH_LENGTH); + // Calculate outer hash + init(); + for (i=0; i<BLOCK_LENGTH; i++) write(keyBuffer[i] ^ HMAC_OPAD); + for (i=0; i<HASH_LENGTH; i++) write(innerHash[i]); + return result(); +} +Sha256Class Sha256; diff --git a/libraries/Sha/sha256.h b/libraries/Sha/sha256.h new file mode 100644 index 0000000..a29d377 --- /dev/null +++ b/libraries/Sha/sha256.h @@ -0,0 +1,60 @@ +/** + * Cryptosuite - A cryptographic library for Arduino + * Copyright (C) 2010 Peter Knight (Cathedrow) + * + * 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 Sha256_h +#define Sha256_h + +#include <inttypes.h> +#include "Print.h" + +#define HASH_LENGTH 32 +#define BLOCK_LENGTH 64 + +union _buffer { + uint8_t b[BLOCK_LENGTH]; + uint32_t w[BLOCK_LENGTH/4]; +}; +union _state { + uint8_t b[HASH_LENGTH]; + uint32_t w[HASH_LENGTH/4]; +}; + +class Sha256Class : public Print +{ + public: + void init(void); + void initHmac(const uint8_t* secret, int secretLength); + uint8_t* result(void); + uint8_t* resultHmac(void); + virtual void write(uint8_t); + using Print::write; + private: + void pad(); + void addUncounted(uint8_t data); + void hashBlock(); + uint32_t ror32(uint32_t number, uint8_t bits); + _buffer buffer; + uint8_t bufferOffset; + _state state; + uint32_t byteCount; + uint8_t keyBuffer[BLOCK_LENGTH]; + uint8_t innerHash[HASH_LENGTH]; +}; +extern Sha256Class Sha256; + +#endif |