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 |  * \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. |  *  Copyright (C) 2006-2013, Brainspark B.V. | ||||||
|  * |  * | ||||||
| @ -27,7 +27,7 @@ | |||||||
| #ifndef POLARSSL_GCM_H | #ifndef POLARSSL_GCM_H | ||||||
| #define POLARSSL_GCM_H | #define POLARSSL_GCM_H | ||||||
| 
 | 
 | ||||||
| #include "aes.h" | #include "cipher.h" | ||||||
| 
 | 
 | ||||||
| #ifdef _MSC_VER | #ifdef _MSC_VER | ||||||
| #include <basetsd.h> | #include <basetsd.h> | ||||||
| @ -50,7 +50,7 @@ extern "C" { | |||||||
|  * \brief          GCM context structure |  * \brief          GCM context structure | ||||||
|  */ |  */ | ||||||
| typedef struct { | 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 HL[16];            /*!< Precalculated HTable */ | ||||||
|     uint64_t HH[16];            /*!< Precalculated HTable */ |     uint64_t HH[16];            /*!< Precalculated HTable */ | ||||||
|     uint64_t len;               /*!< Total data length */ |     uint64_t len;               /*!< Total data length */ | ||||||
| @ -66,15 +66,17 @@ gcm_context; | |||||||
|  * \brief           GCM initialization (encryption) |  * \brief           GCM initialization (encryption) | ||||||
|  * |  * | ||||||
|  * \param ctx       GCM context to be initialized |  * \param ctx       GCM context to be initialized | ||||||
|  |  * \param cipher    cipher to use (a 128-bit block cipher) | ||||||
|  * \param key       encryption key |  * \param key       encryption key | ||||||
|  * \param keysize   must be 128, 192 or 256 |  * \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. |  * \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. |  *       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 ); |                        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. |  * \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 |  *       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 ); |     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 = { | const cipher_base_t gcm_aes_info = { | ||||||
| @ -310,8 +311,8 @@ const cipher_base_t gcm_aes_info = { | |||||||
|     NULL, |     NULL, | ||||||
|     NULL, |     NULL, | ||||||
|     NULL, |     NULL, | ||||||
|     gcm_setkey_wrap, |     gcm_aes_setkey_wrap, | ||||||
|     gcm_setkey_wrap, |     gcm_aes_setkey_wrap, | ||||||
|     gcm_ctx_alloc, |     gcm_ctx_alloc, | ||||||
|     gcm_ctx_free, |     gcm_ctx_free, | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -54,15 +54,17 @@ | |||||||
| } | } | ||||||
| #endif | #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 hi, lo; | ||||||
|     uint64_t vl, vh; |     uint64_t vl, vh; | ||||||
|     unsigned char h[16]; |     unsigned char h[16]; | ||||||
|  |     size_t olen = 0; | ||||||
| 
 | 
 | ||||||
|     memset( h, 0, 16 ); |     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->HH[0] = 0; | ||||||
|     ctx->HL[0] = 0; |     ctx->HL[0] = 0; | ||||||
| @ -99,18 +101,33 @@ static void gcm_gen_table( gcm_context *ctx ) | |||||||
|             HiL[j] = vl ^ ctx->HL[j]; |             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; |     int ret; | ||||||
|  |     const cipher_info_t *cipher_info; | ||||||
| 
 | 
 | ||||||
|     memset( ctx, 0, sizeof(gcm_context) ); |     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 ); |         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 ); |     return( 0 ); | ||||||
| } | } | ||||||
| @ -176,10 +193,11 @@ int gcm_starts( gcm_context *ctx, | |||||||
|                 const unsigned char *add, |                 const unsigned char *add, | ||||||
|                 size_t add_len ) |                 size_t add_len ) | ||||||
| { | { | ||||||
|  |     int ret; | ||||||
|     unsigned char work_buf[16]; |     unsigned char work_buf[16]; | ||||||
|     size_t i; |     size_t i; | ||||||
|     const unsigned char *p; |     const unsigned char *p; | ||||||
|     size_t use_len; |     size_t use_len, olen = 0; | ||||||
| 
 | 
 | ||||||
|     memset( ctx->y, 0x00, sizeof(ctx->y) ); |     memset( ctx->y, 0x00, sizeof(ctx->y) ); | ||||||
|     memset( ctx->buf, 0x00, sizeof(ctx->buf) ); |     memset( ctx->buf, 0x00, sizeof(ctx->buf) ); | ||||||
| @ -218,7 +236,11 @@ int gcm_starts( gcm_context *ctx, | |||||||
|         gcm_mult( ctx, ctx->y, ctx->y ); |         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; |     ctx->add_len = add_len; | ||||||
|     p = add; |     p = add; | ||||||
| @ -243,11 +265,12 @@ int gcm_update( gcm_context *ctx, | |||||||
|                 const unsigned char *input, |                 const unsigned char *input, | ||||||
|                 unsigned char *output ) |                 unsigned char *output ) | ||||||
| { | { | ||||||
|  |     int ret; | ||||||
|     unsigned char ectr[16]; |     unsigned char ectr[16]; | ||||||
|     size_t i; |     size_t i; | ||||||
|     const unsigned char *p; |     const unsigned char *p; | ||||||
|     unsigned char *out_p = output; |     unsigned char *out_p = output; | ||||||
|     size_t use_len; |     size_t use_len, olen = 0; | ||||||
| 
 | 
 | ||||||
|     if( output > input && (size_t) ( output - input ) < length ) |     if( output > input && (size_t) ( output - input ) < length ) | ||||||
|         return( POLARSSL_ERR_GCM_BAD_INPUT ); |         return( POLARSSL_ERR_GCM_BAD_INPUT ); | ||||||
| @ -263,7 +286,11 @@ int gcm_update( gcm_context *ctx, | |||||||
|             if( ++ctx->y[i - 1] != 0 ) |             if( ++ctx->y[i - 1] != 0 ) | ||||||
|                 break; |                 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++ ) |         for( i = 0; i < use_len; i++ ) | ||||||
|         { |         { | ||||||
| @ -613,6 +640,7 @@ int gcm_self_test( int verbose ) | |||||||
|     unsigned char buf[64]; |     unsigned char buf[64]; | ||||||
|     unsigned char tag_buf[16]; |     unsigned char tag_buf[16]; | ||||||
|     int i, j, ret; |     int i, j, ret; | ||||||
|  |     cipher_id_t cipher = POLARSSL_CIPHER_ID_AES; | ||||||
| 
 | 
 | ||||||
|     for( j = 0; j < 3; j++ ) |     for( j = 0; j < 3; j++ ) | ||||||
|     { |     { | ||||||
| @ -623,7 +651,7 @@ int gcm_self_test( int verbose ) | |||||||
|             if( verbose != 0 ) |             if( verbose != 0 ) | ||||||
|                 printf( "  AES-GCM-%3d #%d (%s): ", key_len, i, "enc" ); |                 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, |             ret = gcm_crypt_and_tag( &ctx, GCM_ENCRYPT, | ||||||
|                                      pt_len[i], |                                      pt_len[i], | ||||||
| @ -647,7 +675,7 @@ int gcm_self_test( int verbose ) | |||||||
|             if( verbose != 0 ) |             if( verbose != 0 ) | ||||||
|                 printf( "  AES-GCM-%3d #%d (%s): ", key_len, i, "dec" ); |                 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, |             ret = gcm_crypt_and_tag( &ctx, GCM_DECRYPT, | ||||||
|                                      pt_len[i], |                                      pt_len[i], | ||||||
| @ -671,7 +699,7 @@ int gcm_self_test( int verbose ) | |||||||
|             if( verbose != 0 ) |             if( verbose != 0 ) | ||||||
|                 printf( "  AES-GCM-%3d #%d split (%s): ", key_len, i, "enc" ); |                 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, |             ret = gcm_starts( &ctx, GCM_ENCRYPT, | ||||||
|                               iv[iv_index[i]], iv_len[i], |                               iv[iv_index[i]], iv_len[i], | ||||||
| @ -734,7 +762,7 @@ int gcm_self_test( int verbose ) | |||||||
|             if( verbose != 0 ) |             if( verbose != 0 ) | ||||||
|                 printf( "  AES-GCM-%3d #%d split (%s): ", key_len, i, "dec" ); |                 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, |             ret = gcm_starts( &ctx, GCM_DECRYPT, | ||||||
|                               iv[iv_index[i]], iv_len[i], |                               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 ); |     iv_len = unhexify( iv_str, hex_iv_string ); | ||||||
|     add_len = unhexify( add_str, hex_add_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 ) |     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 ); |         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 ); |     add_len = unhexify( add_str, hex_add_string ); | ||||||
|     unhexify( tag_str, hex_tag_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 ) |     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 ); |         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