mirror of
				https://github.com/cuberite/polarssl.git
				synced 2025-10-30 19:20:40 -04:00 
			
		
		
		
	Moved GCM to use cipher layer instead of AES directly
This commit is contained in:
		
							parent
							
								
									f46b6955e3
								
							
						
					
					
						commit
						43aff2aec4
					
				| @ -1,7 +1,7 @@ | ||||
| /**
 | ||||
|  * \file gcm.h | ||||
|  * | ||||
|  * \brief Galois/Counter mode for AES | ||||
|  * \brief Galois/Counter mode for 128-bit block ciphers | ||||
|  * | ||||
|  *  Copyright (C) 2006-2013, Brainspark B.V. | ||||
|  * | ||||
| @ -27,7 +27,7 @@ | ||||
| #ifndef POLARSSL_GCM_H | ||||
| #define POLARSSL_GCM_H | ||||
| 
 | ||||
| #include "aes.h" | ||||
| #include "cipher.h" | ||||
| 
 | ||||
| #ifdef _MSC_VER | ||||
| #include <basetsd.h> | ||||
| @ -50,7 +50,7 @@ extern "C" { | ||||
|  * \brief          GCM context structure | ||||
|  */ | ||||
| typedef struct { | ||||
|     aes_context aes_ctx;        /*!< AES context used */ | ||||
|     cipher_context_t cipher_ctx;/*!< cipher context used */ | ||||
|     uint64_t HL[16];            /*!< Precalculated HTable */ | ||||
|     uint64_t HH[16];            /*!< Precalculated HTable */ | ||||
|     uint64_t len;               /*!< Total data length */ | ||||
| @ -66,15 +66,17 @@ gcm_context; | ||||
|  * \brief           GCM initialization (encryption) | ||||
|  * | ||||
|  * \param ctx       GCM context to be initialized | ||||
|  * \param cipher    cipher to use (a 128-bit block cipher) | ||||
|  * \param key       encryption key | ||||
|  * \param keysize   must be 128, 192 or 256 | ||||
|  * | ||||
|  * \return          0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH | ||||
|  * \return          0 if successful, or a cipher specific error code | ||||
|  */ | ||||
| int gcm_init( gcm_context *ctx, const unsigned char *key, unsigned int keysize ); | ||||
| int gcm_init( gcm_context *ctx, cipher_id_t cipher, const unsigned char *key, | ||||
|               unsigned int keysize ); | ||||
| 
 | ||||
| /**
 | ||||
|  * \brief           GCM buffer encryption/decryption using AES | ||||
|  * \brief           GCM buffer encryption/decryption using a block cipher | ||||
|  * | ||||
|  * \note On encryption, the output buffer can be the same as the input buffer. | ||||
|  *       On decryption, the output buffer cannot be the same as input buffer. | ||||
| @ -108,7 +110,7 @@ int gcm_crypt_and_tag( gcm_context *ctx, | ||||
|                        unsigned char *tag ); | ||||
| 
 | ||||
| /**
 | ||||
|  * \brief           GCM buffer authenticated decryption using AES | ||||
|  * \brief           GCM buffer authenticated decryption using a block cipher | ||||
|  * | ||||
|  * \note On decryption, the output buffer cannot be the same as input buffer. | ||||
|  *       If buffers overlap, the output buffer must trail at least 8 bytes | ||||
|  | ||||
| @ -298,9 +298,10 @@ static void gcm_ctx_free( void *ctx ) | ||||
|     polarssl_free( ctx ); | ||||
| } | ||||
| 
 | ||||
| static int gcm_setkey_wrap( void *ctx, const unsigned char *key, unsigned int key_length ) | ||||
| static int gcm_aes_setkey_wrap( void *ctx, const unsigned char *key, unsigned int key_length ) | ||||
| { | ||||
|     return gcm_init( (gcm_context *) ctx, key, key_length ); | ||||
|     return gcm_init( (gcm_context *) ctx, POLARSSL_CIPHER_ID_AES, | ||||
|                      key, key_length ); | ||||
| } | ||||
| 
 | ||||
| const cipher_base_t gcm_aes_info = { | ||||
| @ -310,8 +311,8 @@ const cipher_base_t gcm_aes_info = { | ||||
|     NULL, | ||||
|     NULL, | ||||
|     NULL, | ||||
|     gcm_setkey_wrap, | ||||
|     gcm_setkey_wrap, | ||||
|     gcm_aes_setkey_wrap, | ||||
|     gcm_aes_setkey_wrap, | ||||
|     gcm_ctx_alloc, | ||||
|     gcm_ctx_free, | ||||
| }; | ||||
|  | ||||
| @ -54,15 +54,17 @@ | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| static void gcm_gen_table( gcm_context *ctx ) | ||||
| static int gcm_gen_table( gcm_context *ctx ) | ||||
| { | ||||
|     int i, j; | ||||
|     int ret, i, j; | ||||
|     uint64_t hi, lo; | ||||
|     uint64_t vl, vh; | ||||
|     unsigned char h[16]; | ||||
|     size_t olen = 0; | ||||
| 
 | ||||
|     memset( h, 0, 16 ); | ||||
|     aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, h, h ); | ||||
|     if( ( ret = cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 ) | ||||
|         return( ret ); | ||||
| 
 | ||||
|     ctx->HH[0] = 0; | ||||
|     ctx->HL[0] = 0; | ||||
| @ -99,18 +101,33 @@ static void gcm_gen_table( gcm_context *ctx ) | ||||
|             HiL[j] = vl ^ ctx->HL[j]; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return( 0 ); | ||||
| } | ||||
| 
 | ||||
| int gcm_init( gcm_context *ctx, const unsigned char *key, unsigned int keysize ) | ||||
| int gcm_init( gcm_context *ctx, cipher_id_t cipher, const unsigned char *key, | ||||
|               unsigned int keysize ) | ||||
| { | ||||
|     int ret; | ||||
|     const cipher_info_t *cipher_info; | ||||
| 
 | ||||
|     memset( ctx, 0, sizeof(gcm_context) ); | ||||
| 
 | ||||
|     if( ( ret = aes_setkey_enc( &ctx->aes_ctx, key, keysize ) ) != 0 ) | ||||
|     cipher_info = cipher_info_from_values( cipher, keysize, POLARSSL_MODE_ECB ); | ||||
|     if( cipher_info == NULL ) | ||||
|         return( POLARSSL_ERR_GCM_BAD_INPUT ); | ||||
| 
 | ||||
|     if( ( ret = cipher_init_ctx( &ctx->cipher_ctx, cipher_info ) ) != 0 ) | ||||
|         return( ret ); | ||||
| 
 | ||||
|     gcm_gen_table( ctx ); | ||||
|     if( ( ret = cipher_setkey( &ctx->cipher_ctx, key, keysize, | ||||
|                                POLARSSL_ENCRYPT ) ) != 0 ) | ||||
|     { | ||||
|         return( ret ); | ||||
|     } | ||||
| 
 | ||||
|     if( ( ret = gcm_gen_table( ctx ) ) != 0 ) | ||||
|         return( ret ); | ||||
| 
 | ||||
|     return( 0 ); | ||||
| } | ||||
| @ -176,10 +193,11 @@ int gcm_starts( gcm_context *ctx, | ||||
|                 const unsigned char *add, | ||||
|                 size_t add_len ) | ||||
| { | ||||
|     int ret; | ||||
|     unsigned char work_buf[16]; | ||||
|     size_t i; | ||||
|     const unsigned char *p; | ||||
|     size_t use_len; | ||||
|     size_t use_len, olen = 0; | ||||
| 
 | ||||
|     memset( ctx->y, 0x00, sizeof(ctx->y) ); | ||||
|     memset( ctx->buf, 0x00, sizeof(ctx->buf) ); | ||||
| @ -218,7 +236,11 @@ int gcm_starts( gcm_context *ctx, | ||||
|         gcm_mult( ctx, ctx->y, ctx->y ); | ||||
|     } | ||||
| 
 | ||||
|     aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, ctx->y, ctx->base_ectr ); | ||||
|     if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr, | ||||
|                              &olen ) ) != 0 ) | ||||
|     { | ||||
|         return( ret ); | ||||
|     } | ||||
| 
 | ||||
|     ctx->add_len = add_len; | ||||
|     p = add; | ||||
| @ -243,11 +265,12 @@ int gcm_update( gcm_context *ctx, | ||||
|                 const unsigned char *input, | ||||
|                 unsigned char *output ) | ||||
| { | ||||
|     int ret; | ||||
|     unsigned char ectr[16]; | ||||
|     size_t i; | ||||
|     const unsigned char *p; | ||||
|     unsigned char *out_p = output; | ||||
|     size_t use_len; | ||||
|     size_t use_len, olen = 0; | ||||
| 
 | ||||
|     if( output > input && (size_t) ( output - input ) < length ) | ||||
|         return( POLARSSL_ERR_GCM_BAD_INPUT ); | ||||
| @ -263,7 +286,11 @@ int gcm_update( gcm_context *ctx, | ||||
|             if( ++ctx->y[i - 1] != 0 ) | ||||
|                 break; | ||||
| 
 | ||||
|         aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, ctx->y, ectr ); | ||||
|         if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr, | ||||
|                                    &olen ) ) != 0 ) | ||||
|         { | ||||
|             return( ret ); | ||||
|         } | ||||
| 
 | ||||
|         for( i = 0; i < use_len; i++ ) | ||||
|         { | ||||
| @ -613,6 +640,7 @@ int gcm_self_test( int verbose ) | ||||
|     unsigned char buf[64]; | ||||
|     unsigned char tag_buf[16]; | ||||
|     int i, j, ret; | ||||
|     cipher_id_t cipher = POLARSSL_CIPHER_ID_AES; | ||||
| 
 | ||||
|     for( j = 0; j < 3; j++ ) | ||||
|     { | ||||
| @ -623,7 +651,7 @@ int gcm_self_test( int verbose ) | ||||
|             if( verbose != 0 ) | ||||
|                 printf( "  AES-GCM-%3d #%d (%s): ", key_len, i, "enc" ); | ||||
| 
 | ||||
|             gcm_init( &ctx, key[key_index[i]], key_len ); | ||||
|             gcm_init( &ctx, cipher, key[key_index[i]], key_len ); | ||||
| 
 | ||||
|             ret = gcm_crypt_and_tag( &ctx, GCM_ENCRYPT, | ||||
|                                      pt_len[i], | ||||
| @ -647,7 +675,7 @@ int gcm_self_test( int verbose ) | ||||
|             if( verbose != 0 ) | ||||
|                 printf( "  AES-GCM-%3d #%d (%s): ", key_len, i, "dec" ); | ||||
| 
 | ||||
|             gcm_init( &ctx, key[key_index[i]], key_len ); | ||||
|             gcm_init( &ctx, cipher, key[key_index[i]], key_len ); | ||||
| 
 | ||||
|             ret = gcm_crypt_and_tag( &ctx, GCM_DECRYPT, | ||||
|                                      pt_len[i], | ||||
| @ -671,7 +699,7 @@ int gcm_self_test( int verbose ) | ||||
|             if( verbose != 0 ) | ||||
|                 printf( "  AES-GCM-%3d #%d split (%s): ", key_len, i, "enc" ); | ||||
| 
 | ||||
|             gcm_init( &ctx, key[key_index[i]], key_len ); | ||||
|             gcm_init( &ctx, cipher, key[key_index[i]], key_len ); | ||||
| 
 | ||||
|             ret = gcm_starts( &ctx, GCM_ENCRYPT, | ||||
|                               iv[iv_index[i]], iv_len[i], | ||||
| @ -734,7 +762,7 @@ int gcm_self_test( int verbose ) | ||||
|             if( verbose != 0 ) | ||||
|                 printf( "  AES-GCM-%3d #%d split (%s): ", key_len, i, "dec" ); | ||||
| 
 | ||||
|             gcm_init( &ctx, key[key_index[i]], key_len ); | ||||
|             gcm_init( &ctx, cipher, key[key_index[i]], key_len ); | ||||
| 
 | ||||
|             ret = gcm_starts( &ctx, GCM_DECRYPT, | ||||
|                               iv[iv_index[i]], iv_len[i], | ||||
|  | ||||
| @ -39,7 +39,7 @@ void gcm_encrypt_and_tag( char *hex_key_string, char *hex_src_string, | ||||
|     iv_len = unhexify( iv_str, hex_iv_string ); | ||||
|     add_len = unhexify( add_str, hex_add_string ); | ||||
| 
 | ||||
|     TEST_ASSERT( gcm_init( &ctx, key_str, key_len * 8 ) == init_result ); | ||||
|     TEST_ASSERT( gcm_init( &ctx, POLARSSL_CIPHER_ID_AES, key_str, key_len * 8 ) == init_result ); | ||||
|     if( init_result == 0 ) | ||||
|     { | ||||
|         TEST_ASSERT( gcm_crypt_and_tag( &ctx, GCM_ENCRYPT, pt_len, iv_str, iv_len, add_str, add_len, src_str, output, tag_len, tag_output ) == 0 ); | ||||
| @ -84,7 +84,7 @@ void gcm_decrypt_and_verify( char *hex_key_string, char *hex_src_string, | ||||
|     add_len = unhexify( add_str, hex_add_string ); | ||||
|     unhexify( tag_str, hex_tag_string ); | ||||
| 
 | ||||
|     TEST_ASSERT( gcm_init( &ctx, key_str, key_len * 8 ) == init_result ); | ||||
|     TEST_ASSERT( gcm_init( &ctx, POLARSSL_CIPHER_ID_AES, key_str, key_len * 8 ) == init_result ); | ||||
|     if( init_result == 0 ) | ||||
|     { | ||||
|         ret = gcm_auth_decrypt( &ctx, pt_len, iv_str, iv_len, add_str, add_len, tag_str, tag_len, src_str, output ); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Paul Bakker
						Paul Bakker