A simple library to support serving https.
Dependents: oldheating gps motorhome heating
tls/tls-prf.c@24:cb43290fc439, 2020-04-01 (annotated)
- Committer:
- andrewboyson
- Date:
- Wed Apr 01 12:48:52 2020 +0000
- Revision:
- 24:cb43290fc439
- Parent:
- 19:f22327e8be7b
Added check so that if the client closes the TCP connection before the TLS connection is established then respond that we have finished and the TCP connection is to be closed.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
andrewboyson | 9:f354b4859b0b | 1 | #include <stdint.h> |
andrewboyson | 13:0a80b49a5e78 | 2 | #include <alloca.h> |
andrewboyson | 13:0a80b49a5e78 | 3 | |
andrewboyson | 9:f354b4859b0b | 4 | #include "prf.h" |
andrewboyson | 17:93feb2a51d58 | 5 | #include "tls-defs.h" |
andrewboyson | 17:93feb2a51d58 | 6 | #include "sha256.h" |
andrewboyson | 19:f22327e8be7b | 7 | #include "sha1.h" |
andrewboyson | 19:f22327e8be7b | 8 | #include "aes128cbc.h" |
andrewboyson | 9:f354b4859b0b | 9 | |
andrewboyson | 17:93feb2a51d58 | 10 | void TlsPrfMasterSecret(uint8_t * preMasterSecret, uint8_t* clientRandom, uint8_t* serverRandom, uint8_t* masterSecret) |
andrewboyson | 9:f354b4859b0b | 11 | { |
andrewboyson | 17:93feb2a51d58 | 12 | const int SEED_LENGTH = 13 + TLS_LENGTH_RANDOM + TLS_LENGTH_RANDOM; |
andrewboyson | 17:93feb2a51d58 | 13 | uint8_t* seed = alloca(SEED_LENGTH); |
andrewboyson | 17:93feb2a51d58 | 14 | for (int i = 0; i < 13; i++) seed[i ] = "master secret"[i]; |
andrewboyson | 17:93feb2a51d58 | 15 | for (int i = 0; i < TLS_LENGTH_RANDOM; i++) seed[i + 13 ] = clientRandom[i]; |
andrewboyson | 17:93feb2a51d58 | 16 | for (int i = 0; i < TLS_LENGTH_RANDOM; i++) seed[i + 13 + TLS_LENGTH_RANDOM] = serverRandom[i]; |
andrewboyson | 9:f354b4859b0b | 17 | |
andrewboyson | 17:93feb2a51d58 | 18 | const int ITERATIONS = 2; |
andrewboyson | 17:93feb2a51d58 | 19 | uint8_t* hash = alloca(SHA256_HASH_SIZE * ITERATIONS); //32 * 2 |
andrewboyson | 17:93feb2a51d58 | 20 | PrfHmacSha256(preMasterSecret, TLS_LENGTH_PRE_MASTER_SECRET, seed, SEED_LENGTH, ITERATIONS, hash); //2 iterations will generate 64 bytes |
andrewboyson | 17:93feb2a51d58 | 21 | for (int i = 0; i < TLS_LENGTH_MASTER_SECRET; i++) masterSecret[i] = hash[i]; //just take the first 48 bytes |
andrewboyson | 9:f354b4859b0b | 22 | } |
andrewboyson | 9:f354b4859b0b | 23 | |
andrewboyson | 19:f22327e8be7b | 24 | void TlsPrfKeysAes128Sha1(uint8_t * masterSecret, uint8_t* clientRandom, uint8_t* serverRandom, uint8_t* client_MAC_key, |
andrewboyson | 19:f22327e8be7b | 25 | uint8_t* server_MAC_key, |
andrewboyson | 19:f22327e8be7b | 26 | uint8_t* client_key, |
andrewboyson | 19:f22327e8be7b | 27 | uint8_t* server_key) |
andrewboyson | 9:f354b4859b0b | 28 | { |
andrewboyson | 17:93feb2a51d58 | 29 | const int SEED_LENGTH = 13 + TLS_LENGTH_RANDOM + TLS_LENGTH_RANDOM; |
andrewboyson | 17:93feb2a51d58 | 30 | uint8_t* seed = alloca(SEED_LENGTH); |
andrewboyson | 17:93feb2a51d58 | 31 | for (int i = 0; i < 13; i++) seed[i ] = "key expansion"[i]; |
andrewboyson | 17:93feb2a51d58 | 32 | for (int i = 0; i < TLS_LENGTH_RANDOM; i++) seed[i + 13 ] = serverRandom[i]; //Notice the order relative to the master secret algorithm |
andrewboyson | 17:93feb2a51d58 | 33 | for (int i = 0; i < TLS_LENGTH_RANDOM; i++) seed[i + 13 + TLS_LENGTH_RANDOM] = clientRandom[i]; |
andrewboyson | 9:f354b4859b0b | 34 | |
andrewboyson | 17:93feb2a51d58 | 35 | const int ITERATIONS = 4; |
andrewboyson | 17:93feb2a51d58 | 36 | uint8_t* hash = alloca(SHA256_HASH_SIZE * ITERATIONS); //4 iterations of 32 bytes |
andrewboyson | 17:93feb2a51d58 | 37 | PrfHmacSha256(masterSecret, TLS_LENGTH_MASTER_SECRET, seed, SEED_LENGTH, ITERATIONS, hash); //4 iteration will generate the keys required |
andrewboyson | 19:f22327e8be7b | 38 | for (int i = 0; i < SHA1_HASH_SIZE; i++) client_MAC_key[i] = hash[i ]; |
andrewboyson | 19:f22327e8be7b | 39 | for (int i = 0; i < SHA1_HASH_SIZE; i++) server_MAC_key[i] = hash[i + SHA1_HASH_SIZE ]; |
andrewboyson | 19:f22327e8be7b | 40 | for (int i = 0; i < AES128CBC_BLOCK_SIZE; i++) client_key[i] = hash[i + SHA1_HASH_SIZE + SHA1_HASH_SIZE ]; |
andrewboyson | 19:f22327e8be7b | 41 | for (int i = 0; i < AES128CBC_BLOCK_SIZE; i++) server_key[i] = hash[i + SHA1_HASH_SIZE + SHA1_HASH_SIZE + AES128CBC_BLOCK_SIZE]; |
andrewboyson | 9:f354b4859b0b | 42 | } |
andrewboyson | 9:f354b4859b0b | 43 | |
andrewboyson | 17:93feb2a51d58 | 44 | void TlsPrfServerFinished(uint8_t * masterSecret, uint8_t* handshakeHash, uint8_t* verify) |
andrewboyson | 9:f354b4859b0b | 45 | { |
andrewboyson | 17:93feb2a51d58 | 46 | const int SEED_LENGTH = 15 + SHA256_HASH_SIZE; |
andrewboyson | 17:93feb2a51d58 | 47 | uint8_t* seed = alloca(SEED_LENGTH); |
andrewboyson | 17:93feb2a51d58 | 48 | for (int i = 0; i < 15; i++) seed[i ] = "server finished"[i]; |
andrewboyson | 17:93feb2a51d58 | 49 | for (int i = 0; i < SHA256_HASH_SIZE; i++) seed[i + 15] = handshakeHash[i]; |
andrewboyson | 9:f354b4859b0b | 50 | |
andrewboyson | 17:93feb2a51d58 | 51 | const int ITERATIONS = 1; |
andrewboyson | 17:93feb2a51d58 | 52 | uint8_t* hash = alloca(SHA256_HASH_SIZE * ITERATIONS); |
andrewboyson | 17:93feb2a51d58 | 53 | PrfHmacSha256(masterSecret, TLS_LENGTH_MASTER_SECRET, seed, SEED_LENGTH, ITERATIONS, hash); |
andrewboyson | 17:93feb2a51d58 | 54 | for (int i = 0; i < TLS_LENGTH_VERIFY; i++) verify[i] = hash[i]; |
andrewboyson | 9:f354b4859b0b | 55 | } |
andrewboyson | 17:93feb2a51d58 | 56 | void TlsPrfClientFinished(uint8_t * masterSecret, uint8_t* handshakeHash, uint8_t* verify) |
andrewboyson | 9:f354b4859b0b | 57 | { |
andrewboyson | 17:93feb2a51d58 | 58 | const int SEED_LENGTH = 15 + SHA256_HASH_SIZE; |
andrewboyson | 17:93feb2a51d58 | 59 | uint8_t* seed = alloca(SEED_LENGTH); |
andrewboyson | 17:93feb2a51d58 | 60 | for (int i = 0; i < 15; i++) seed[i ] = "client finished"[i]; |
andrewboyson | 17:93feb2a51d58 | 61 | for (int i = 0; i < SHA256_HASH_SIZE; i++) seed[i + 15] = handshakeHash[i]; |
andrewboyson | 9:f354b4859b0b | 62 | |
andrewboyson | 17:93feb2a51d58 | 63 | const int ITERATIONS = 1; |
andrewboyson | 17:93feb2a51d58 | 64 | uint8_t* hash = alloca(SHA256_HASH_SIZE * ITERATIONS); |
andrewboyson | 17:93feb2a51d58 | 65 | PrfHmacSha256(masterSecret, TLS_LENGTH_MASTER_SECRET, seed, SEED_LENGTH, ITERATIONS, hash); |
andrewboyson | 17:93feb2a51d58 | 66 | for (int i = 0; i < TLS_LENGTH_VERIFY; i++) verify[i] = hash[i]; |
andrewboyson | 9:f354b4859b0b | 67 | } |