A simple library to support serving https.
Dependents: oldheating gps motorhome heating
prf/prf.c@9:f354b4859b0b, 2019-09-11 (annotated)
- 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?
User | Revision | Line number | New 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 | } |