A simple library to support serving https.

Dependents:   oldheating gps motorhome heating

Revision:
15:4ddb73b5fea1
Parent:
14:03a0b8fd6ddc
Child:
16:7eeb5f6626ad
--- a/tls/tls-response.c	Wed Oct 02 20:26:04 2019 +0000
+++ b/tls/tls-response.c	Fri Oct 04 18:25:55 2019 +0000
@@ -25,6 +25,59 @@
     *p++ = size & 0xFF;
     *pp = p;
 }
+
+static uint8_t* encryptIvPointer;
+static uint8_t* encryptPayloadPointer;
+static int      encryptPayloadSize;
+static void encryptAddIv(uint8_t** pp)
+{
+    uint8_t* p = *pp;
+    
+    //Add the IV
+    encryptIvPointer = p;
+    for (int i = 0; i < AES_BLOCKLEN; i++) *p++ = RandomGetByte();
+    
+    *pp = p;
+}
+static void encryptAddMac(uint8_t** pp, struct TlsConnection* pConnection, uint8_t contentType)
+{
+    uint8_t* p = *pp;
+    
+    //Add the MAC
+    TlsMacSha1(TLS_KEY_SIZE_MAC,
+               pConnection->serverMacKey,
+               pConnection->serverSequence,
+               contentType,
+               0x03,
+               0x03,
+               encryptPayloadSize,
+               encryptPayloadPointer,
+               p);
+    p += SHA1_HASH_SIZE;
+
+    *pp = p;
+}
+
+static void encryptAddPadding(uint8_t** pp)
+{
+    uint8_t* p = *pp;
+    
+    int paddingSize = AES_BLOCKLEN - 1 - (encryptPayloadSize + SHA1_HASH_SIZE + 1 - 1) % AES_BLOCKLEN;
+    LogF("- padding size %d\r\n", paddingSize);
+    for (int i = 0; i < paddingSize; i++) *p++ = paddingSize;
+    
+    *p++ = paddingSize;
+    
+    *pp = p;
+}
+static void encryptPayload(uint8_t* p, struct TlsConnection* pConnection)
+{
+    //Encrypt payload + mac + padding
+    struct AES_ctx ctx;
+    AES_init_ctx_iv(&ctx, pConnection->serverWriteKey, encryptIvPointer);
+    AES_CBC_encrypt_buffer(&ctx, encryptPayloadPointer, p - encryptPayloadPointer);}
+
+
 static uint8_t* pHandshakeSize;
 static uint8_t* pHandshakePayload;   
 static void addHandshakeStart(uint8_t** pp)
@@ -103,51 +156,27 @@
     LogTime("     sending handshake finished\r\n");
     uint8_t* p = *pp;
     
+    encryptAddIv(&p);
+    encryptPayloadPointer = p;
+    encryptPayloadSize = 16;
+    
+    //Make the 'finished' handshake which is the payload to be encrypted
+    *p++ = TLS_HANDSHAKE_FINISHED;
+    *p++ = 0x00;
+    *p++ = 0x00;
+    *p++ = 0x0c; //Length 12
+    
     //Hash over all handshake payloads exchanged so far
     uint8_t hash[32];
     Sha256Finish(&pConnection->handshakeSha, hash);
     
     //Make verify data
-    uint8_t verify[12];
-    TlsPrfServerFinished(pSession->masterSecret, hash, verify);    //Hash over all handshakes
-    
-    //Make the 'finished' handshake
-    uint8_t payload[16];
-    payload[0] = TLS_HANDSHAKE_FINISHED;
-    payload[1] = 0x00;
-    payload[2] = 0x00;
-    payload[3] = 0x0c; //Length 12
-    for (int i = 0; i < 12; i++) payload[i + 4] = verify[i];
-    int payloadLength = 16;
+    TlsPrfServerFinished(pSession->masterSecret, hash, p);    //Hash over all handshakes
+    p += 12;
     
-    uint8_t mac[SHA1_HASH_SIZE];
-    TlsMacSha1(TLS_KEY_SIZE_MAC,
-               pConnection->serverMacKey,
-               pConnection->serverSequence,
-               TLS_CONTENT_TYPE_HANDSHAKE,
-               0x03,
-               0x03,
-               payloadLength,
-               payload,
-               mac);
-
-    
-    //plaintext
-    uint8_t message[48];
-    for (int i = 0; i < 16; i++) message[i     ] = payload[i];         //payload
-    for (int i = 0; i < 20; i++) message[i + 16] = mac[i];             //mac
-    for (int i = 0; i < 12; i++) message[i + 36] = 0x0b;               //padding
-    
-    uint8_t iv[16];
-    for (int i = 0; i < 16; i++) iv[i] = RandomGetByte();
-    
-    //Encrypt
-    struct AES_ctx ctx;
-    AES_init_ctx_iv(&ctx, pConnection->serverWriteKey, iv);
-    AES_CBC_encrypt_buffer(&ctx, message, 48);
-
-    for (int i = 0; i < 16; i++) *p++ = iv[i];
-    for (int i = 0; i < 48; i++) *p++ = message[i];    
+    encryptAddMac    (&p, pConnection, TLS_CONTENT_TYPE_HANDSHAKE);
+    encryptAddPadding(&p);
+    encryptPayload   ( p, pConnection);
     
     *pp = p;
 }
@@ -241,7 +270,6 @@
     *pWindowSize = p - pWindow;
     pConnection->serverPositionInStreamOffset = positionOfWindowInStream + *pWindowSize;
 }
-
 static bool sendContent(struct TlsConnection* pConnection, int* pWindowSize, uint8_t* pWindow, uint32_t positionOfWindowInStream)
 {
 /*
@@ -270,39 +298,20 @@
     uint8_t* pBackfillSize = p;
     *p++ = 0; *p++ = 0;
     
-    //Add the IV
-    uint8_t* pIv = p;
-    for (int i = 0; i < AES_BLOCKLEN; i++) *p++ = RandomGetByte();
+    encryptAddIv(&p);
 
     //Add the plain payload
-    uint8_t* pPayload = p;
-    int payloadSize = *pWindowSize - CONTENT_MAX_OVERHEAD;
-    LogF("- available payload size %d\r\n", payloadSize);
+    encryptPayloadPointer = p;
+    encryptPayloadSize = *pWindowSize - CONTENT_MAX_OVERHEAD;
+    LogF("- available payload size %d\r\n", encryptPayloadSize);
     uint32_t positionOfPayloadInStream = positionOfWindowInStream - pConnection->serverPositionInStreamOffset;
     LogF("- position of payload in stream %d\r\n", positionOfPayloadInStream);
-    bool finished = HttpAdd(pConnection->id, &payloadSize, (char*)pPayload, positionOfPayloadInStream); //Return whatever HTTP would be
-    LogF("- resulting payload size %d\r\n", payloadSize);
-    p += payloadSize;
+    bool finished = HttpAdd(pConnection->id, &encryptPayloadSize, (char*)p, positionOfPayloadInStream); //Return whatever HTTP would be
+    LogF("- resulting payload size %d\r\n", encryptPayloadSize);
+    p += encryptPayloadSize;
     
-    //Add the MAC
-    TlsMacSha1(TLS_KEY_SIZE_MAC,
-               pConnection->serverMacKey,
-               pConnection->serverSequence,
-               TLS_CONTENT_TYPE_APPLICATION,
-               0x03,
-               0x03,
-               payloadSize,
-               pPayload,
-               p);
-    p += SHA1_HASH_SIZE;
-
-    //Add the padding
-    int paddingSize = AES_BLOCKLEN - 1 - (payloadSize + SHA1_HASH_SIZE + 1 - 1) % AES_BLOCKLEN;
-    LogF("- padding size %d\r\n", paddingSize);
-    for (int i = 0; i < paddingSize; i++) *p++ = paddingSize;
-    
-    //Add the padding size
-    *p++ = paddingSize;
+    encryptAddMac    (&p, pConnection, TLS_CONTENT_TYPE_APPLICATION);
+    encryptAddPadding(&p);
     
     //Backfill the size
     backfillSize(p, pBackfillSize);
@@ -314,14 +323,11 @@
     //Log the plain content
     Log("- plain content\r\n"); LogBytesAsHex(pWindow, *pWindowSize); Log("\r\n");
     
-    //Encrypt payload + mac + padding
-    struct AES_ctx ctx;
-    AES_init_ctx_iv(&ctx, pConnection->serverWriteKey, pIv);
-    AES_CBC_encrypt_buffer(&ctx, pPayload, p - pPayload);
+    encryptPayload(p, pConnection);
     
     //Finalise
     pConnection->serverSequence++;
-    pConnection->serverPositionInStreamOffset += *pWindowSize - payloadSize;
+    pConnection->serverPositionInStreamOffset += *pWindowSize - encryptPayloadSize;
     
     return finished;
 }