A simple library to support serving https.

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Sun Sep 01 18:15:12 2019 +0000
Revision:
6:819c17738dc2
Making progress - now have decryption working.

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 */