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:
6:819c17738dc2
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 6:819c17738dc2 1 /******************************************************************************
andrewboyson 6:819c17738dc2 2 *
andrewboyson 6:819c17738dc2 3 * THIS SOURCE CODE IS HEREBY PLACED INTO THE PUBLIC DOMAIN FOR THE GOOD OF ALL
andrewboyson 6:819c17738dc2 4 *
andrewboyson 6:819c17738dc2 5 * This is a simple and straightforward implementation of AES-GCM authenticated
andrewboyson 6:819c17738dc2 6 * encryption. The focus of this work was correctness & accuracy. It is written
andrewboyson 6:819c17738dc2 7 * in straight 'C' without any particular focus upon optimization or speed. It
andrewboyson 6:819c17738dc2 8 * should be endian (memory byte order) neutral since the few places that care
andrewboyson 6:819c17738dc2 9 * are handled explicitly.
andrewboyson 6:819c17738dc2 10 *
andrewboyson 6:819c17738dc2 11 * This implementation of AES-GCM was created by Steven M. Gibson of GRC.com.
andrewboyson 6:819c17738dc2 12 *
andrewboyson 6:819c17738dc2 13 * It is intended for general purpose use, but was written in support of GRC's
andrewboyson 6:819c17738dc2 14 * reference implementation of the SQRL (Secure Quick Reliable Login) client.
andrewboyson 6:819c17738dc2 15 *
andrewboyson 6:819c17738dc2 16 * See: http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
andrewboyson 6:819c17738dc2 17 * http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/ \
andrewboyson 6:819c17738dc2 18 * gcm/gcm-revised-spec.pdf
andrewboyson 6:819c17738dc2 19 *
andrewboyson 6:819c17738dc2 20 * NO COPYRIGHT IS CLAIMED IN THIS WORK, HOWEVER, NEITHER IS ANY WARRANTY MADE
andrewboyson 6:819c17738dc2 21 * REGARDING ITS FITNESS FOR ANY PARTICULAR PURPOSE. USE IT AT YOUR OWN RISK.
andrewboyson 6:819c17738dc2 22 *
andrewboyson 6:819c17738dc2 23 *******************************************************************************/
andrewboyson 6:819c17738dc2 24 #ifndef GCM_HEADER
andrewboyson 6:819c17738dc2 25 #define GCM_HEADER
andrewboyson 6:819c17738dc2 26
andrewboyson 6:819c17738dc2 27 #define GCM_AUTH_FAILURE 0x55555555 // authentication failure
andrewboyson 6:819c17738dc2 28
andrewboyson 6:819c17738dc2 29 #include "aes.h" // gcm_context includes aes_context
andrewboyson 6:819c17738dc2 30
andrewboyson 6:819c17738dc2 31 #if defined(_MSC_VER)
andrewboyson 6:819c17738dc2 32 #include <basetsd.h>
andrewboyson 6:819c17738dc2 33 typedef unsigned int size_t;// use the right type for length declarations
andrewboyson 6:819c17738dc2 34 typedef UINT32 uint32_t;
andrewboyson 6:819c17738dc2 35 typedef UINT64 uint64_t;
andrewboyson 6:819c17738dc2 36 #else
andrewboyson 6:819c17738dc2 37 #include <stdint.h>
andrewboyson 6:819c17738dc2 38 #endif
andrewboyson 6:819c17738dc2 39
andrewboyson 6:819c17738dc2 40
andrewboyson 6:819c17738dc2 41 /******************************************************************************
andrewboyson 6:819c17738dc2 42 * GCM_CONTEXT : GCM context / holds keytables, instance data, and AES ctx
andrewboyson 6:819c17738dc2 43 ******************************************************************************/
andrewboyson 6:819c17738dc2 44 typedef struct {
andrewboyson 6:819c17738dc2 45 int mode; // cipher direction: encrypt/decrypt
andrewboyson 6:819c17738dc2 46 uint64_t len; // cipher data length processed so far
andrewboyson 6:819c17738dc2 47 uint64_t add_len; // total add data length
andrewboyson 6:819c17738dc2 48 uint64_t HL[16]; // precalculated lo-half HTable
andrewboyson 6:819c17738dc2 49 uint64_t HH[16]; // precalculated hi-half HTable
andrewboyson 6:819c17738dc2 50 uchar base_ectr[16]; // first counter-mode cipher output for tag
andrewboyson 6:819c17738dc2 51 uchar y[16]; // the current cipher-input IV|Counter value
andrewboyson 6:819c17738dc2 52 uchar buf[16]; // buf working value
andrewboyson 6:819c17738dc2 53 aes_context aes_ctx; // cipher context used
andrewboyson 6:819c17738dc2 54 } gcm_context;
andrewboyson 6:819c17738dc2 55
andrewboyson 6:819c17738dc2 56
andrewboyson 6:819c17738dc2 57 /******************************************************************************
andrewboyson 6:819c17738dc2 58 * GCM_CONTEXT : MUST be called once before ANY use of this library
andrewboyson 6:819c17738dc2 59 ******************************************************************************/
andrewboyson 6:819c17738dc2 60 int gcm_initialize( void );
andrewboyson 6:819c17738dc2 61
andrewboyson 6:819c17738dc2 62
andrewboyson 6:819c17738dc2 63 /******************************************************************************
andrewboyson 6:819c17738dc2 64 * GCM_SETKEY : sets the GCM (and AES) keying material for use
andrewboyson 6:819c17738dc2 65 ******************************************************************************/
andrewboyson 6:819c17738dc2 66 int gcm_setkey( gcm_context *ctx, // caller-provided context ptr
andrewboyson 6:819c17738dc2 67 const uchar *key, // pointer to cipher key
andrewboyson 6:819c17738dc2 68 const uint keysize // must be 128, 192 or 256
andrewboyson 6:819c17738dc2 69 ); // returns 0 for success
andrewboyson 6:819c17738dc2 70
andrewboyson 6:819c17738dc2 71
andrewboyson 6:819c17738dc2 72 /******************************************************************************
andrewboyson 6:819c17738dc2 73 *
andrewboyson 6:819c17738dc2 74 * GCM_CRYPT_AND_TAG
andrewboyson 6:819c17738dc2 75 *
andrewboyson 6:819c17738dc2 76 * This either encrypts or decrypts the user-provided data and, either
andrewboyson 6:819c17738dc2 77 * way, generates an authentication tag of the requested length. It must be
andrewboyson 6:819c17738dc2 78 * called with a GCM context whose key has already been set with GCM_SETKEY.
andrewboyson 6:819c17738dc2 79 *
andrewboyson 6:819c17738dc2 80 * The user would typically call this explicitly to ENCRYPT a buffer of data
andrewboyson 6:819c17738dc2 81 * and optional associated data, and produce its an authentication tag.
andrewboyson 6:819c17738dc2 82 *
andrewboyson 6:819c17738dc2 83 * To reverse the process the user would typically call the companion
andrewboyson 6:819c17738dc2 84 * GCM_AUTH_DECRYPT function to decrypt data and verify a user-provided
andrewboyson 6:819c17738dc2 85 * authentication tag. The GCM_AUTH_DECRYPT function calls this function
andrewboyson 6:819c17738dc2 86 * to perform its decryption and tag generation, which it then compares.
andrewboyson 6:819c17738dc2 87 *
andrewboyson 6:819c17738dc2 88 ******************************************************************************/
andrewboyson 6:819c17738dc2 89 int gcm_crypt_and_tag(
andrewboyson 6:819c17738dc2 90 gcm_context *ctx, // gcm context with key already setup
andrewboyson 6:819c17738dc2 91 int mode, // cipher direction: GCM_ENCRYPT or GCM_DECRYPT
andrewboyson 6:819c17738dc2 92 const uchar *iv, // pointer to the 12-byte initialization vector
andrewboyson 6:819c17738dc2 93 size_t iv_len, // byte length if the IV. should always be 12
andrewboyson 6:819c17738dc2 94 const uchar *add, // pointer to the non-ciphered additional data
andrewboyson 6:819c17738dc2 95 size_t add_len, // byte length of the additional AEAD data
andrewboyson 6:819c17738dc2 96 const uchar *input, // pointer to the cipher data source
andrewboyson 6:819c17738dc2 97 uchar *output, // pointer to the cipher data destination
andrewboyson 6:819c17738dc2 98 size_t length, // byte length of the cipher data
andrewboyson 6:819c17738dc2 99 uchar *tag, // pointer to the tag to be generated
andrewboyson 6:819c17738dc2 100 size_t tag_len ); // byte length of the tag to be generated
andrewboyson 6:819c17738dc2 101
andrewboyson 6:819c17738dc2 102
andrewboyson 6:819c17738dc2 103 /******************************************************************************
andrewboyson 6:819c17738dc2 104 *
andrewboyson 6:819c17738dc2 105 * GCM_AUTH_DECRYPT
andrewboyson 6:819c17738dc2 106 *
andrewboyson 6:819c17738dc2 107 * This DECRYPTS a user-provided data buffer with optional associated data.
andrewboyson 6:819c17738dc2 108 * It then verifies a user-supplied authentication tag against the tag just
andrewboyson 6:819c17738dc2 109 * re-created during decryption to verify that the data has not been altered.
andrewboyson 6:819c17738dc2 110 *
andrewboyson 6:819c17738dc2 111 * This function calls GCM_CRYPT_AND_TAG (above) to perform the decryption
andrewboyson 6:819c17738dc2 112 * and authentication tag generation.
andrewboyson 6:819c17738dc2 113 *
andrewboyson 6:819c17738dc2 114 ******************************************************************************/
andrewboyson 6:819c17738dc2 115 int gcm_auth_decrypt(
andrewboyson 6:819c17738dc2 116 gcm_context *ctx, // gcm context with key already setup
andrewboyson 6:819c17738dc2 117 const uchar *iv, // pointer to the 12-byte initialization vector
andrewboyson 6:819c17738dc2 118 size_t iv_len, // byte length if the IV. should always be 12
andrewboyson 6:819c17738dc2 119 const uchar *add, // pointer to the non-ciphered additional data
andrewboyson 6:819c17738dc2 120 size_t add_len, // byte length of the additional AEAD data
andrewboyson 6:819c17738dc2 121 const uchar *input, // pointer to the cipher data source
andrewboyson 6:819c17738dc2 122 uchar *output, // pointer to the cipher data destination
andrewboyson 6:819c17738dc2 123 size_t length, // byte length of the cipher data
andrewboyson 6:819c17738dc2 124 const uchar *tag, // pointer to the tag to be authenticated
andrewboyson 6:819c17738dc2 125 size_t tag_len ); // byte length of the tag <= 16
andrewboyson 6:819c17738dc2 126
andrewboyson 6:819c17738dc2 127
andrewboyson 6:819c17738dc2 128 /******************************************************************************
andrewboyson 6:819c17738dc2 129 *
andrewboyson 6:819c17738dc2 130 * GCM_START
andrewboyson 6:819c17738dc2 131 *
andrewboyson 6:819c17738dc2 132 * Given a user-provided GCM context, this initializes it, sets the encryption
andrewboyson 6:819c17738dc2 133 * mode, and preprocesses the initialization vector and additional AEAD data.
andrewboyson 6:819c17738dc2 134 *
andrewboyson 6:819c17738dc2 135 ******************************************************************************/
andrewboyson 6:819c17738dc2 136 int gcm_start( gcm_context *ctx, // pointer to user-provided GCM context
andrewboyson 6:819c17738dc2 137 int mode, // GCM_ENCRYPT or GCM_DECRYPT
andrewboyson 6:819c17738dc2 138 const uchar *iv, // pointer to initialization vector
andrewboyson 6:819c17738dc2 139 size_t iv_len, // IV length in bytes (should == 12)
andrewboyson 6:819c17738dc2 140 const uchar *add, // pointer to additional AEAD data (NULL if none)
andrewboyson 6:819c17738dc2 141 size_t add_len ); // length of additional AEAD data (bytes)
andrewboyson 6:819c17738dc2 142
andrewboyson 6:819c17738dc2 143
andrewboyson 6:819c17738dc2 144 /******************************************************************************
andrewboyson 6:819c17738dc2 145 *
andrewboyson 6:819c17738dc2 146 * GCM_UPDATE
andrewboyson 6:819c17738dc2 147 *
andrewboyson 6:819c17738dc2 148 * This is called once or more to process bulk plaintext or ciphertext data.
andrewboyson 6:819c17738dc2 149 * We give this some number of bytes of input and it returns the same number
andrewboyson 6:819c17738dc2 150 * of output bytes. If called multiple times (which is fine) all but the final
andrewboyson 6:819c17738dc2 151 * invocation MUST be called with length mod 16 == 0. (Only the final call can
andrewboyson 6:819c17738dc2 152 * have a partial block length of < 128 bits.)
andrewboyson 6:819c17738dc2 153 *
andrewboyson 6:819c17738dc2 154 ******************************************************************************/
andrewboyson 6:819c17738dc2 155 int gcm_update( gcm_context *ctx, // pointer to user-provided GCM context
andrewboyson 6:819c17738dc2 156 size_t length, // length, in bytes, of data to process
andrewboyson 6:819c17738dc2 157 const uchar *input, // pointer to source data
andrewboyson 6:819c17738dc2 158 uchar *output ); // pointer to destination data
andrewboyson 6:819c17738dc2 159
andrewboyson 6:819c17738dc2 160
andrewboyson 6:819c17738dc2 161 /******************************************************************************
andrewboyson 6:819c17738dc2 162 *
andrewboyson 6:819c17738dc2 163 * GCM_FINISH
andrewboyson 6:819c17738dc2 164 *
andrewboyson 6:819c17738dc2 165 * This is called once after all calls to GCM_UPDATE to finalize the GCM.
andrewboyson 6:819c17738dc2 166 * It performs the final GHASH to produce the resulting authentication TAG.
andrewboyson 6:819c17738dc2 167 *
andrewboyson 6:819c17738dc2 168 ******************************************************************************/
andrewboyson 6:819c17738dc2 169 int gcm_finish( gcm_context *ctx, // pointer to user-provided GCM context
andrewboyson 6:819c17738dc2 170 uchar *tag, // ptr to tag buffer - NULL if tag_len = 0
andrewboyson 6:819c17738dc2 171 size_t tag_len ); // length, in bytes, of the tag-receiving buf
andrewboyson 6:819c17738dc2 172
andrewboyson 6:819c17738dc2 173
andrewboyson 6:819c17738dc2 174 /******************************************************************************
andrewboyson 6:819c17738dc2 175 *
andrewboyson 6:819c17738dc2 176 * GCM_ZERO_CTX
andrewboyson 6:819c17738dc2 177 *
andrewboyson 6:819c17738dc2 178 * The GCM context contains both the GCM context and the AES context.
andrewboyson 6:819c17738dc2 179 * This includes keying and key-related material which is security-
andrewboyson 6:819c17738dc2 180 * sensitive, so it MUST be zeroed after use. This function does that.
andrewboyson 6:819c17738dc2 181 *
andrewboyson 6:819c17738dc2 182 ******************************************************************************/
andrewboyson 6:819c17738dc2 183 void gcm_zero_ctx( gcm_context *ctx );
andrewboyson 6:819c17738dc2 184
andrewboyson 6:819c17738dc2 185
andrewboyson 6:819c17738dc2 186 #endif /* GCM_HEADER */