A simple library to support serving https.

Dependents:   oldheating gps motorhome heating

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?

UserRevisionLine numberNew 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 }