A simple library to support serving https.

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Wed Sep 11 07:24:21 2019 +0000
Revision:
9:f354b4859b0b
Child:
13:0a80b49a5e78
Got application data to be returned but not encrypted yet

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 9:f354b4859b0b 1 #include "hmac-sha256.h"
andrewboyson 9:f354b4859b0b 2 #include "log.h"
andrewboyson 9:f354b4859b0b 3 /*
andrewboyson 9:f354b4859b0b 4 master_secret = PRF(pre_master_secret, "master secret", ClientHello.random + ServerHello.random)[0..47];
andrewboyson 9:f354b4859b0b 5
andrewboyson 9:f354b4859b0b 6 key_block = PRF(master_secret, "key expansion", server_random + client_random);
andrewboyson 9:f354b4859b0b 7
andrewboyson 9:f354b4859b0b 8 PRF(secret, label, seed) = P_<hash>(secret, label + seed)
andrewboyson 9:f354b4859b0b 9
andrewboyson 9:f354b4859b0b 10 P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
andrewboyson 9:f354b4859b0b 11 HMAC_hash(secret, A(2) + seed) +
andrewboyson 9:f354b4859b0b 12 HMAC_hash(secret, A(3) + seed) + ...
andrewboyson 9:f354b4859b0b 13
andrewboyson 9:f354b4859b0b 14 A(0) = seed
andrewboyson 9:f354b4859b0b 15 A(i) = HMAC_hash(secret, A(i-1))
andrewboyson 9:f354b4859b0b 16 */
andrewboyson 9:f354b4859b0b 17
andrewboyson 9:f354b4859b0b 18 void PrfHmacSha256(uint8_t* secret, int secretLength, uint8_t* seed, int seedLength, int number, uint8_t* output) //output needs to hold number * 32 bytes
andrewboyson 9:f354b4859b0b 19 {
andrewboyson 9:f354b4859b0b 20 uint8_t prevA[SHA256_HASH_SIZE];
andrewboyson 9:f354b4859b0b 21 uint8_t thisA[SHA256_HASH_SIZE];
andrewboyson 9:f354b4859b0b 22 uint8_t hash [SHA256_HASH_SIZE];
andrewboyson 9:f354b4859b0b 23
andrewboyson 9:f354b4859b0b 24 for (int j = 0; j < number; j++)
andrewboyson 9:f354b4859b0b 25 {
andrewboyson 9:f354b4859b0b 26 //Calculate the hash A(i)
andrewboyson 9:f354b4859b0b 27 if (j) HmacSha256(secret, secretLength, prevA, SHA256_HASH_SIZE, thisA);
andrewboyson 9:f354b4859b0b 28 else HmacSha256(secret, secretLength, seed, seedLength, thisA);
andrewboyson 9:f354b4859b0b 29 for (int i = 0; i < SHA256_HASH_SIZE; i++) prevA[i] = thisA[i];
andrewboyson 9:f354b4859b0b 30
andrewboyson 9:f354b4859b0b 31 //Concatanate A(i) + seed
andrewboyson 9:f354b4859b0b 32 uint8_t* aPlusSeed = alloca(SHA256_HASH_SIZE + seedLength);
andrewboyson 9:f354b4859b0b 33 for (int i = 0; i < SHA256_HASH_SIZE; i++) aPlusSeed[i ] = thisA[i];
andrewboyson 9:f354b4859b0b 34 for (int i = 0; i < seedLength; i++) aPlusSeed[i + SHA256_HASH_SIZE] = seed[i];
andrewboyson 9:f354b4859b0b 35
andrewboyson 9:f354b4859b0b 36 //Calculate the hash
andrewboyson 9:f354b4859b0b 37 HmacSha256(secret, secretLength, aPlusSeed, SHA256_HASH_SIZE + seedLength, hash);
andrewboyson 9:f354b4859b0b 38
andrewboyson 9:f354b4859b0b 39 //Concatanate the hash onto the output
andrewboyson 9:f354b4859b0b 40 for (int i = 0; i < SHA256_HASH_SIZE; i++) output[j * SHA256_HASH_SIZE + i] = hash[i];
andrewboyson 9:f354b4859b0b 41 }
andrewboyson 9:f354b4859b0b 42 }
andrewboyson 9:f354b4859b0b 43 void PrfHmacSha256Test()
andrewboyson 9:f354b4859b0b 44 {
andrewboyson 9:f354b4859b0b 45 uint8_t Secret[] = {
andrewboyson 9:f354b4859b0b 46 0x9b, 0xbe, 0x43, 0x6b, 0xa9, 0x40, 0xf0, 0x17,
andrewboyson 9:f354b4859b0b 47 0xb1, 0x76, 0x52, 0x84, 0x9a, 0x71, 0xdb, 0x35
andrewboyson 9:f354b4859b0b 48 };
andrewboyson 9:f354b4859b0b 49
andrewboyson 9:f354b4859b0b 50 uint8_t Seed[] = {
andrewboyson 9:f354b4859b0b 51 0x74, 0x65, 0x73, 0x74, 0x20, 0x6c, 0x61, 0x62,
andrewboyson 9:f354b4859b0b 52 0x65, 0x6c,
andrewboyson 9:f354b4859b0b 53 0xa0, 0xba, 0x9f, 0x93, 0x6c, 0xda, 0x31, 0x18,
andrewboyson 9:f354b4859b0b 54 0x27, 0xa6, 0xf7, 0x96, 0xff, 0xd5, 0x19, 0x8c
andrewboyson 9:f354b4859b0b 55 };
andrewboyson 9:f354b4859b0b 56
andrewboyson 9:f354b4859b0b 57 uint8_t* hash = alloca(128);
andrewboyson 9:f354b4859b0b 58 PrfHmacSha256(Secret, 16, Seed, 26, 4, hash); //4 iteration will generate the keys required
andrewboyson 9:f354b4859b0b 59 Log("TLS PRF test\r\n");
andrewboyson 9:f354b4859b0b 60 LogBytesAsHex(hash, 128);
andrewboyson 9:f354b4859b0b 61 Log("\r\n\r\n");
andrewboyson 9:f354b4859b0b 62 /*
andrewboyson 9:f354b4859b0b 63 Output (100 bytes):
andrewboyson 9:f354b4859b0b 64 0000 e3 f2 29 ba 72 7b e1 7b ....r...
andrewboyson 9:f354b4859b0b 65 0008 8d 12 26 20 55 7c d4 53 ... U..S
andrewboyson 9:f354b4859b0b 66 0010 c2 aa b2 1d 07 c3 d4 95 ........
andrewboyson 9:f354b4859b0b 67 0018 32 9b 52 d4 e6 1e db 5a 2.R....Z
andrewboyson 9:f354b4859b0b 68 0020 6b 30 17 91 e9 0d 35 c9 k0....5.
andrewboyson 9:f354b4859b0b 69 0028 c9 a4 6b 4e 14 ba f9 af ..kN....
andrewboyson 9:f354b4859b0b 70 0030 0f a0 22 f7 07 7d ef 17 ........
andrewboyson 9:f354b4859b0b 71 0038 ab fd 37 97 c0 56 4b ab ..7..VK.
andrewboyson 9:f354b4859b0b 72 0040 4f bc 91 66 6e 9d ef 9b O..fn...
andrewboyson 9:f354b4859b0b 73 0048 97 fc e3 4f 79 67 89 ba ...Oyg..
andrewboyson 9:f354b4859b0b 74 0050 a4 80 82 d1 22 ee 42 c5 ......B.
andrewboyson 9:f354b4859b0b 75 0058 a7 2e 5a 51 10 ff f7 01 ..ZQ....
andrewboyson 9:f354b4859b0b 76 0060 87 34 7b 66 .4.f
andrewboyson 9:f354b4859b0b 77 */
andrewboyson 9:f354b4859b0b 78 }