Home | History | Annotate | Download | only in crypto
      1 /*
      2  * Copyright (C) 2007 Michael Brown <mbrown (at) fensystems.co.uk>.
      3  *
      4  * This program is free software; you can redistribute it and/or
      5  * modify it under the terms of the GNU General Public License as
      6  * published by the Free Software Foundation; either version 2 of the
      7  * License, or any later version.
      8  *
      9  * This program is distributed in the hope that it will be useful, but
     10  * WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     12  * General Public License for more details.
     13  *
     14  * You should have received a copy of the GNU General Public License
     15  * along with this program; if not, write to the Free Software
     16  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     17  */
     18 
     19 FILE_LICENCE ( GPL2_OR_LATER );
     20 
     21 #include <string.h>
     22 #include <errno.h>
     23 #include <byteswap.h>
     24 #include <gpxe/crypto.h>
     25 #include <gpxe/cbc.h>
     26 #include <gpxe/aes.h>
     27 #include "crypto/axtls/crypto.h"
     28 
     29 /** @file
     30  *
     31  * AES algorithm
     32  *
     33  */
     34 
     35 /**
     36  * Set key
     37  *
     38  * @v ctx		Context
     39  * @v key		Key
     40  * @v keylen		Key length
     41  * @ret rc		Return status code
     42  */
     43 static int aes_setkey ( void *ctx, const void *key, size_t keylen ) {
     44 	struct aes_context *aes_ctx = ctx;
     45 	AES_MODE mode;
     46 	void *iv;
     47 
     48 	switch ( keylen ) {
     49 	case ( 128 / 8 ):
     50 		mode = AES_MODE_128;
     51 		break;
     52 	case ( 256 / 8 ):
     53 		mode = AES_MODE_256;
     54 		break;
     55 	default:
     56 		return -EINVAL;
     57 	}
     58 
     59 	/* IV is not a relevant concept at this stage; use a dummy
     60 	 * value that will have no side-effects.
     61 	 */
     62 	iv = &aes_ctx->axtls_ctx.iv;
     63 
     64 	AES_set_key ( &aes_ctx->axtls_ctx, key, iv, mode );
     65 
     66 	aes_ctx->decrypting = 0;
     67 
     68 	return 0;
     69 }
     70 
     71 /**
     72  * Set initialisation vector
     73  *
     74  * @v ctx		Context
     75  * @v iv		Initialisation vector
     76  */
     77 static void aes_setiv ( void *ctx __unused, const void *iv __unused ) {
     78 	/* Nothing to do */
     79 }
     80 
     81 /**
     82  * Call AXTLS' AES_encrypt() or AES_decrypt() functions
     83  *
     84  * @v axtls_ctx		AXTLS AES context
     85  * @v src		Data to process
     86  * @v dst		Buffer for output
     87  * @v func		AXTLS AES function to call
     88  */
     89 static void aes_call_axtls ( AES_CTX *axtls_ctx, const void *src, void *dst,
     90 			     void ( * func ) ( const AES_CTX *axtls_ctx,
     91 					       uint32_t *data ) ){
     92 	const uint32_t *srcl = src;
     93 	uint32_t *dstl = dst;
     94 	unsigned int i;
     95 
     96 	/* AXTLS' AES_encrypt() and AES_decrypt() functions both
     97 	 * expect to deal with an array of four dwords in host-endian
     98 	 * order.
     99 	 */
    100 	for ( i = 0 ; i < 4 ; i++ )
    101 		dstl[i] = ntohl ( srcl[i] );
    102 	func ( axtls_ctx, dstl );
    103 	for ( i = 0 ; i < 4 ; i++ )
    104 		dstl[i] = htonl ( dstl[i] );
    105 }
    106 
    107 /**
    108  * Encrypt data
    109  *
    110  * @v ctx		Context
    111  * @v src		Data to encrypt
    112  * @v dst		Buffer for encrypted data
    113  * @v len		Length of data
    114  */
    115 static void aes_encrypt ( void *ctx, const void *src, void *dst,
    116 			  size_t len ) {
    117 	struct aes_context *aes_ctx = ctx;
    118 
    119 	assert ( len == AES_BLOCKSIZE );
    120 	if ( aes_ctx->decrypting )
    121 		assert ( 0 );
    122 	aes_call_axtls ( &aes_ctx->axtls_ctx, src, dst, AES_encrypt );
    123 }
    124 
    125 /**
    126  * Decrypt data
    127  *
    128  * @v ctx		Context
    129  * @v src		Data to decrypt
    130  * @v dst		Buffer for decrypted data
    131  * @v len		Length of data
    132  */
    133 static void aes_decrypt ( void *ctx, const void *src, void *dst,
    134 			  size_t len ) {
    135 	struct aes_context *aes_ctx = ctx;
    136 
    137 	assert ( len == AES_BLOCKSIZE );
    138 	if ( ! aes_ctx->decrypting ) {
    139 		AES_convert_key ( &aes_ctx->axtls_ctx );
    140 		aes_ctx->decrypting = 1;
    141 	}
    142 	aes_call_axtls ( &aes_ctx->axtls_ctx, src, dst, AES_decrypt );
    143 }
    144 
    145 /** Basic AES algorithm */
    146 struct cipher_algorithm aes_algorithm = {
    147 	.name = "aes",
    148 	.ctxsize = sizeof ( struct aes_context ),
    149 	.blocksize = AES_BLOCKSIZE,
    150 	.setkey = aes_setkey,
    151 	.setiv = aes_setiv,
    152 	.encrypt = aes_encrypt,
    153 	.decrypt = aes_decrypt,
    154 };
    155 
    156 /* AES with cipher-block chaining */
    157 CBC_CIPHER ( aes_cbc, aes_cbc_algorithm,
    158 	     aes_algorithm, struct aes_context, AES_BLOCKSIZE );
    159