Andrew Boyson / crypto

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Thu Oct 10 07:38:13 2019 +0000
Revision:
17:93feb2a51d58
Parent:
13:0a80b49a5e78
Child:
19:f22327e8be7b
Defined a lot of lengths eg 20 -> SHA1_HASH_LENGTH

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 9:f354b4859b0b 7
andrewboyson 17:93feb2a51d58 8 void TlsPrfMasterSecret(uint8_t * preMasterSecret, uint8_t* clientRandom, uint8_t* serverRandom, uint8_t* masterSecret)
andrewboyson 9:f354b4859b0b 9 {
andrewboyson 17:93feb2a51d58 10 const int SEED_LENGTH = 13 + TLS_LENGTH_RANDOM + TLS_LENGTH_RANDOM;
andrewboyson 17:93feb2a51d58 11 uint8_t* seed = alloca(SEED_LENGTH);
andrewboyson 17:93feb2a51d58 12 for (int i = 0; i < 13; i++) seed[i ] = "master secret"[i];
andrewboyson 17:93feb2a51d58 13 for (int i = 0; i < TLS_LENGTH_RANDOM; i++) seed[i + 13 ] = clientRandom[i];
andrewboyson 17:93feb2a51d58 14 for (int i = 0; i < TLS_LENGTH_RANDOM; i++) seed[i + 13 + TLS_LENGTH_RANDOM] = serverRandom[i];
andrewboyson 9:f354b4859b0b 15
andrewboyson 17:93feb2a51d58 16 const int ITERATIONS = 2;
andrewboyson 17:93feb2a51d58 17 uint8_t* hash = alloca(SHA256_HASH_SIZE * ITERATIONS); //32 * 2
andrewboyson 17:93feb2a51d58 18 PrfHmacSha256(preMasterSecret, TLS_LENGTH_PRE_MASTER_SECRET, seed, SEED_LENGTH, ITERATIONS, hash); //2 iterations will generate 64 bytes
andrewboyson 17:93feb2a51d58 19 for (int i = 0; i < TLS_LENGTH_MASTER_SECRET; i++) masterSecret[i] = hash[i]; //just take the first 48 bytes
andrewboyson 9:f354b4859b0b 20 }
andrewboyson 9:f354b4859b0b 21
andrewboyson 17:93feb2a51d58 22 void TlsPrfKeys(uint8_t * masterSecret, uint8_t* clientRandom, uint8_t* serverRandom, uint8_t* client_MAC_key,
andrewboyson 17:93feb2a51d58 23 uint8_t* server_MAC_key,
andrewboyson 17:93feb2a51d58 24 uint8_t* client_key,
andrewboyson 17:93feb2a51d58 25 uint8_t* server_key)
andrewboyson 9:f354b4859b0b 26 {
andrewboyson 17:93feb2a51d58 27 const int SEED_LENGTH = 13 + TLS_LENGTH_RANDOM + TLS_LENGTH_RANDOM;
andrewboyson 17:93feb2a51d58 28 uint8_t* seed = alloca(SEED_LENGTH);
andrewboyson 17:93feb2a51d58 29 for (int i = 0; i < 13; i++) seed[i ] = "key expansion"[i];
andrewboyson 17:93feb2a51d58 30 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 31 for (int i = 0; i < TLS_LENGTH_RANDOM; i++) seed[i + 13 + TLS_LENGTH_RANDOM] = clientRandom[i];
andrewboyson 9:f354b4859b0b 32
andrewboyson 17:93feb2a51d58 33 const int ITERATIONS = 4;
andrewboyson 17:93feb2a51d58 34 uint8_t* hash = alloca(SHA256_HASH_SIZE * ITERATIONS); //4 iterations of 32 bytes
andrewboyson 17:93feb2a51d58 35 PrfHmacSha256(masterSecret, TLS_LENGTH_MASTER_SECRET, seed, SEED_LENGTH, ITERATIONS, hash); //4 iteration will generate the keys required
andrewboyson 17:93feb2a51d58 36 for (int i = 0; i < TLS_LENGTH_MAC_KEY; i++) client_MAC_key[i] = hash[i ];
andrewboyson 17:93feb2a51d58 37 for (int i = 0; i < TLS_LENGTH_MAC_KEY; i++) server_MAC_key[i] = hash[i + TLS_LENGTH_MAC_KEY ];
andrewboyson 17:93feb2a51d58 38 for (int i = 0; i < TLS_LENGTH_CIPHER_KEY; i++) client_key[i] = hash[i + TLS_LENGTH_MAC_KEY + TLS_LENGTH_MAC_KEY ];
andrewboyson 17:93feb2a51d58 39 for (int i = 0; i < TLS_LENGTH_CIPHER_KEY; i++) server_key[i] = hash[i + TLS_LENGTH_MAC_KEY + TLS_LENGTH_MAC_KEY + TLS_LENGTH_CIPHER_KEY];
andrewboyson 9:f354b4859b0b 40 }
andrewboyson 9:f354b4859b0b 41
andrewboyson 17:93feb2a51d58 42 void TlsPrfServerFinished(uint8_t * masterSecret, uint8_t* handshakeHash, uint8_t* verify)
andrewboyson 9:f354b4859b0b 43 {
andrewboyson 17:93feb2a51d58 44 const int SEED_LENGTH = 15 + SHA256_HASH_SIZE;
andrewboyson 17:93feb2a51d58 45 uint8_t* seed = alloca(SEED_LENGTH);
andrewboyson 17:93feb2a51d58 46 for (int i = 0; i < 15; i++) seed[i ] = "server finished"[i];
andrewboyson 17:93feb2a51d58 47 for (int i = 0; i < SHA256_HASH_SIZE; i++) seed[i + 15] = handshakeHash[i];
andrewboyson 9:f354b4859b0b 48
andrewboyson 17:93feb2a51d58 49 const int ITERATIONS = 1;
andrewboyson 17:93feb2a51d58 50 uint8_t* hash = alloca(SHA256_HASH_SIZE * ITERATIONS);
andrewboyson 17:93feb2a51d58 51 PrfHmacSha256(masterSecret, TLS_LENGTH_MASTER_SECRET, seed, SEED_LENGTH, ITERATIONS, hash);
andrewboyson 17:93feb2a51d58 52 for (int i = 0; i < TLS_LENGTH_VERIFY; i++) verify[i] = hash[i];
andrewboyson 9:f354b4859b0b 53 }
andrewboyson 17:93feb2a51d58 54 void TlsPrfClientFinished(uint8_t * masterSecret, uint8_t* handshakeHash, uint8_t* verify)
andrewboyson 9:f354b4859b0b 55 {
andrewboyson 17:93feb2a51d58 56 const int SEED_LENGTH = 15 + SHA256_HASH_SIZE;
andrewboyson 17:93feb2a51d58 57 uint8_t* seed = alloca(SEED_LENGTH);
andrewboyson 17:93feb2a51d58 58 for (int i = 0; i < 15; i++) seed[i ] = "client finished"[i];
andrewboyson 17:93feb2a51d58 59 for (int i = 0; i < SHA256_HASH_SIZE; i++) seed[i + 15] = handshakeHash[i];
andrewboyson 9:f354b4859b0b 60
andrewboyson 17:93feb2a51d58 61 const int ITERATIONS = 1;
andrewboyson 17:93feb2a51d58 62 uint8_t* hash = alloca(SHA256_HASH_SIZE * ITERATIONS);
andrewboyson 17:93feb2a51d58 63 PrfHmacSha256(masterSecret, TLS_LENGTH_MASTER_SECRET, seed, SEED_LENGTH, ITERATIONS, hash);
andrewboyson 17:93feb2a51d58 64 for (int i = 0; i < TLS_LENGTH_VERIFY; i++) verify[i] = hash[i];
andrewboyson 9:f354b4859b0b 65 }