Commit be1cf907 by Enrico Pozzobon

Stripped down AES GCM

parent fcb7d9c8
......@@ -6,7 +6,7 @@ LFLAGS=-lm
all: gcm
gcm: gcm.c genkat_aead.c aes.c cipher.c cipher_wrap.c platform_util.c
gcm: gcm.c genkat_aead.c aes.c platform_util.c
$(CC) $(NISTGCCFLAGS) -o $@ $^ $(LFLAGS)
.PHONY: clean
......@@ -14,4 +14,5 @@ gcm: gcm.c genkat_aead.c aes.c cipher.c cipher_wrap.c platform_util.c
clean:
rm -rf *.o
rm -rf gcm
rm -rf LWC_*
/**
* \file cipher_internal.h
*
* \brief Cipher wrappers.
*
* \author Adriaan de Jong <dejong@fox-it.com>
*/
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_CIPHER_WRAP_H
#define MBEDTLS_CIPHER_WRAP_H
#include "config.h"
#include "cipher.h"
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "psa/crypto.h"
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#ifdef __cplusplus
extern "C" {
#endif
/**
* Base cipher information. The non-mode specific functions and values.
*/
struct mbedtls_cipher_base_t
{
/** Base Cipher type (e.g. MBEDTLS_CIPHER_ID_AES) */
mbedtls_cipher_id_t cipher;
/** Encrypt using ECB */
int (*ecb_func)( void *ctx, mbedtls_operation_t mode,
const unsigned char *input, unsigned char *output );
#if defined(MBEDTLS_CIPHER_MODE_CBC)
/** Encrypt using CBC */
int (*cbc_func)( void *ctx, mbedtls_operation_t mode, size_t length,
unsigned char *iv, const unsigned char *input,
unsigned char *output );
#endif
#if defined(MBEDTLS_CIPHER_MODE_CFB)
/** Encrypt using CFB (Full length) */
int (*cfb_func)( void *ctx, mbedtls_operation_t mode, size_t length, size_t *iv_off,
unsigned char *iv, const unsigned char *input,
unsigned char *output );
#endif
#if defined(MBEDTLS_CIPHER_MODE_OFB)
/** Encrypt using OFB (Full length) */
int (*ofb_func)( void *ctx, size_t length, size_t *iv_off,
unsigned char *iv,
const unsigned char *input,
unsigned char *output );
#endif
#if defined(MBEDTLS_CIPHER_MODE_CTR)
/** Encrypt using CTR */
int (*ctr_func)( void *ctx, size_t length, size_t *nc_off,
unsigned char *nonce_counter, unsigned char *stream_block,
const unsigned char *input, unsigned char *output );
#endif
#if defined(MBEDTLS_CIPHER_MODE_XTS)
/** Encrypt or decrypt using XTS. */
int (*xts_func)( void *ctx, mbedtls_operation_t mode, size_t length,
const unsigned char data_unit[16],
const unsigned char *input, unsigned char *output );
#endif
#if defined(MBEDTLS_CIPHER_MODE_STREAM)
/** Encrypt using STREAM */
int (*stream_func)( void *ctx, size_t length,
const unsigned char *input, unsigned char *output );
#endif
/** Set key for encryption purposes */
int (*setkey_enc_func)( void *ctx, const unsigned char *key,
unsigned int key_bitlen );
/** Set key for decryption purposes */
int (*setkey_dec_func)( void *ctx, const unsigned char *key,
unsigned int key_bitlen);
/** Allocate a new context */
void * (*ctx_alloc_func)( void );
/** Free the given context */
void (*ctx_free_func)( void *ctx );
};
typedef struct
{
mbedtls_cipher_type_t type;
const mbedtls_cipher_info_t *info;
} mbedtls_cipher_definition_t;
#if defined(MBEDTLS_USE_PSA_CRYPTO)
typedef enum
{
MBEDTLS_CIPHER_PSA_KEY_UNSET = 0,
MBEDTLS_CIPHER_PSA_KEY_OWNED, /* Used for PSA-based cipher contexts which */
/* use raw key material internally imported */
/* into a allocated key slot, and which */
/* hence need to destroy that key slot */
/* when they are no longer needed. */
MBEDTLS_CIPHER_PSA_KEY_NOT_OWNED, /* Used for PSA-based cipher contexts */
/* which use a key from a key slot */
/* provided by the user, and which */
/* hence should not be destroyed when */
/* the context is no longer needed. */
} mbedtls_cipher_psa_key_ownership;
typedef struct
{
psa_algorithm_t alg;
psa_key_handle_t slot;
mbedtls_cipher_psa_key_ownership slot_state;
} mbedtls_cipher_context_psa;
#endif /* MBEDTLS_USE_PSA_CRYPTO */
extern const mbedtls_cipher_definition_t mbedtls_cipher_definitions[];
extern int mbedtls_cipher_supported[];
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_CIPHER_WRAP_H */
#pragma once
#undef MBEDTLS_SELF_TEST
#define MBEDTLS_GCM_C
#define MBEDTLS_CIPHER_C
#define MBEDTLS_AES_C
......@@ -29,23 +29,15 @@
* [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory.
*/
#include "config.h"
#include "platform_util.h"
#if defined(MBEDTLS_GCM_C)
#include "gcm.h"
#include "aes.h"
#include "api.h"
#include "crypto_aead.h"
#include <string.h>
#if defined(MBEDTLS_AESNI_C)
#include "mbedtls/aesni.h"
#endif
#if !defined(MBEDTLS_GCM_ALT)
/* Parameter validation macros */
#define GCM_VALIDATE_RET( cond ) \
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_GCM_BAD_INPUT )
......@@ -86,6 +78,9 @@ void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
}
#define mbedtls_cipher_update(ctx, input, output) \
mbedtls_aes_crypt_ecb((ctx)->cipher_ctx, MBEDTLS_ENCRYPT, input, output)
/*
* Encrypt function for NIST API
*/
......@@ -100,6 +95,7 @@ int crypto_aead_encrypt(
{
(void) nsec;
mbedtls_gcm_context ctx;
mbedtls_aes_context aes;
int ret;
unsigned long long mask = 15;
unsigned long long mlenp = (mlen + mask) & (~mask);
......@@ -107,9 +103,11 @@ int crypto_aead_encrypt(
*clen = mlenp + CRYPTO_ABYTES;
mbedtls_gcm_init( &ctx );
ret = mbedtls_gcm_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, k, 128);
ctx.cipher_ctx.cipher_ctx = &aes;
ret = mbedtls_gcm_setkey( &ctx, k, 128);
ret = mbedtls_gcm_crypt_and_tag( &ctx, 1, mlen, npub, 12, ad, adlen, m, c, 16, tag_buf );
mbedtls_gcm_free( &ctx );
mbedtls_platform_zeroize( &aes, sizeof( aes ) );
memcpy(c + mlenp, tag_buf, CRYPTO_ABYTES);
return ret;
}
......@@ -125,6 +123,7 @@ int crypto_aead_decrypt(
{
(void) nsec;
mbedtls_gcm_context ctx;
mbedtls_aes_context aes;
int ret;
unsigned char tag_buf[CRYPTO_ABYTES];
......@@ -133,9 +132,11 @@ int crypto_aead_decrypt(
*mlen = clen;
mbedtls_gcm_init( &ctx );
ret = mbedtls_gcm_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, k, 128);
ctx.cipher_ctx.cipher_ctx = &aes;
ret = mbedtls_gcm_setkey( &ctx, k, 128);
ret = mbedtls_gcm_auth_decrypt( &ctx, clen, npub, 12, ad, adlen, tag_buf, 16, c, m);
mbedtls_gcm_free( &ctx );
mbedtls_platform_zeroize( &aes, sizeof( aes ) );
return ret;
......@@ -155,10 +156,9 @@ static int gcm_gen_table( mbedtls_gcm_context *ctx )
uint64_t hi, lo;
uint64_t vl, vh;
unsigned char h[16];
size_t olen = 0;
memset( h, 0, 16 );
if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, h ) ) != 0 )
return( ret );
/* pack h as two 64-bits ints, big-endian */
......@@ -174,12 +174,6 @@ static int gcm_gen_table( mbedtls_gcm_context *ctx )
ctx->HL[8] = vl;
ctx->HH[8] = vh;
#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
/* With CLMUL support, we need only h, not the rest of the table */
if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) )
return( 0 );
#endif
/* 0 corresponds to 0 in GF(2^128) */
ctx->HH[0] = 0;
ctx->HL[0] = 0;
......@@ -210,32 +204,18 @@ static int gcm_gen_table( mbedtls_gcm_context *ctx )
}
int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
mbedtls_cipher_id_t cipher,
const unsigned char *key,
unsigned int keybits )
{
int ret;
const mbedtls_cipher_info_t *cipher_info;
GCM_VALIDATE_RET( ctx != NULL );
GCM_VALIDATE_RET( key != NULL );
GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 );
cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
MBEDTLS_MODE_ECB );
if( cipher_info == NULL )
return( MBEDTLS_ERR_GCM_BAD_INPUT );
if( cipher_info->block_size != 16 )
return( MBEDTLS_ERR_GCM_BAD_INPUT );
ctx->cipher_ctx.key_bitlen = keybits;
mbedtls_cipher_free( &ctx->cipher_ctx );
if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
return( ret );
if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
MBEDTLS_ENCRYPT ) ) != 0 )
if( ( ret = mbedtls_aes_setkey_enc( ctx->cipher_ctx.cipher_ctx, key, keybits ) ) != 0)
{
return( ret );
}
......@@ -270,20 +250,6 @@ static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
unsigned char lo, hi, rem;
uint64_t zh, zl;
#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
unsigned char h[16];
PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
PUT_UINT32_BE( ctx->HH[8], h, 4 );
PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
PUT_UINT32_BE( ctx->HL[8], h, 12 );
mbedtls_aesni_gcm_mult( output, x, h );
return;
}
#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
lo = x[15] & 0xf;
zh = ctx->HH[lo];
......@@ -330,7 +296,7 @@ int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
unsigned char work_buf[16];
size_t i;
const unsigned char *p;
size_t use_len, olen = 0;
size_t use_len;
GCM_VALIDATE_RET( ctx != NULL );
GCM_VALIDATE_RET( iv != NULL );
......@@ -382,8 +348,8 @@ int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
gcm_mult( ctx, ctx->y, ctx->y );
}
if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16,
ctx->base_ectr, &olen ) ) != 0 )
if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y,
ctx->base_ectr ) ) != 0 )
{
return( ret );
}
......@@ -416,7 +382,7 @@ int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
size_t i;
const unsigned char *p;
unsigned char *out_p = output;
size_t use_len, olen = 0;
size_t use_len;
GCM_VALIDATE_RET( ctx != NULL );
GCM_VALIDATE_RET( length == 0 || input != NULL );
......@@ -444,8 +410,8 @@ int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
if( ++ctx->y[i - 1] != 0 )
break;
if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
&olen ) ) != 0 )
if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, ectr
) ) != 0 )
{
return( ret );
}
......@@ -590,10 +556,6 @@ void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
{
if( ctx == NULL )
return;
mbedtls_cipher_free( &ctx->cipher_ctx );
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
}
#endif /* !MBEDTLS_GCM_ALT */
#endif /* MBEDTLS_GCM_C */
......@@ -33,8 +33,6 @@
#ifndef MBEDTLS_GCM_H
#define MBEDTLS_GCM_H
#include "config.h"
#include "cipher.h"
#include <stdint.h>
......@@ -43,18 +41,12 @@
#define MBEDTLS_GCM_DECRYPT 0
#define MBEDTLS_ERR_GCM_AUTH_FAILED -0x0012 /**< Authenticated decryption failed. */
/* MBEDTLS_ERR_GCM_HW_ACCEL_FAILED is deprecated and should not be used. */
#define MBEDTLS_ERR_GCM_HW_ACCEL_FAILED -0x0013 /**< GCM hardware accelerator failed. */
#define MBEDTLS_ERR_GCM_BAD_INPUT -0x0014 /**< Bad input parameters to function. */
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(MBEDTLS_GCM_ALT)
/**
* \brief The GCM context structure.
*/
......@@ -74,10 +66,6 @@ typedef struct mbedtls_gcm_context
}
mbedtls_gcm_context;
#else /* !MBEDTLS_GCM_ALT */
#include "gcm_alt.h"
#endif /* !MBEDTLS_GCM_ALT */
/**
* \brief This function initializes the specified GCM context,
* to make references valid, and prepares the context
......@@ -96,7 +84,6 @@ void mbedtls_gcm_init( mbedtls_gcm_context *ctx );
* cipher algorithm and a key.
*
* \param ctx The GCM context. This must be initialized.
* \param cipher The 128-bit block cipher to use.
* \param key The encryption key. This must be a readable buffer of at
* least \p keybits bits.
* \param keybits The key size in bits. Valid options are:
......@@ -108,7 +95,6 @@ void mbedtls_gcm_init( mbedtls_gcm_context *ctx );
* \return A cipher-specific error code on failure.
*/
int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
mbedtls_cipher_id_t cipher,
const unsigned char *key,
unsigned int keybits );
......@@ -302,18 +288,6 @@ int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
*/
void mbedtls_gcm_free( mbedtls_gcm_context *ctx );
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief The GCM checkup routine.
*
* \return \c 0 on success.
* \return \c 1 on failure.
*/
int mbedtls_gcm_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif
......
......@@ -20,22 +20,11 @@
* This file is part of Mbed TLS (https://tls.mbed.org)
*/
/*
* Ensure gmtime_r is available even with -std=c99; must be defined before
* config.h, which pulls in glibc's features.h. Harmless on other platforms.
*/
#if !defined(_POSIX_C_SOURCE)
#define _POSIX_C_SOURCE 200112L
#endif
#include "config.h"
#include "platform_util.h"
#include <stddef.h>
#include <string.h>
#if !defined(MBEDTLS_PLATFORM_ZEROIZE_ALT)
/*
* This implementation should never be optimized out by the compiler
*
......@@ -68,5 +57,4 @@ void mbedtls_platform_zeroize( void *buf, size_t len )
{
memset_func( buf, 0, len );
}
#endif /* MBEDTLS_PLATFORM_ZEROIZE_ALT */
......@@ -25,8 +25,6 @@
#ifndef MBEDTLS_PLATFORM_UTIL_H
#define MBEDTLS_PLATFORM_UTIL_H
#include "config.h"
#include <stddef.h>
#ifdef __cplusplus
......@@ -34,9 +32,6 @@ extern "C" {
#endif
#define MBEDTLS_PARAM_FAILED( cond ) assert( cond )
#define MBEDTLS_PARAM_FAILED_ALT
/* Internal macros meant to be called only from within the library. */
#define MBEDTLS_INTERNAL_VALIDATE_RET( cond, ret ) do { } while( 0 )
#define MBEDTLS_INTERNAL_VALIDATE( cond ) do { } while( 0 )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment