mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-11-29 15:24:18 +01: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…
Reference in New Issue
Block a user