A simple library to support serving https.
Dependents: oldheating gps motorhome heating
Diff: tls/tls-response.c
- Revision:
- 15:4ddb73b5fea1
- Parent:
- 14:03a0b8fd6ddc
- Child:
- 16:7eeb5f6626ad
diff -r 03a0b8fd6ddc -r 4ddb73b5fea1 tls/tls-response.c --- 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; }