axtls_aes.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License as
00006  * published by the Free Software Foundation; either version 2 of the
00007  * License, or any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00017  */
00018 
00019 FILE_LICENCE ( GPL2_OR_LATER );
00020 
00021 #include <string.h>
00022 #include <errno.h>
00023 #include <byteswap.h>
00024 #include <gpxe/crypto.h>
00025 #include <gpxe/cbc.h>
00026 #include <gpxe/aes.h>
00027 #include "crypto/axtls/crypto.h"
00028 
00029 /** @file
00030  *
00031  * AES algorithm
00032  *
00033  */
00034 
00035 /**
00036  * Set key
00037  *
00038  * @v ctx               Context
00039  * @v key               Key
00040  * @v keylen            Key length
00041  * @ret rc              Return status code
00042  */
00043 static int aes_setkey ( void *ctx, const void *key, size_t keylen ) {
00044         struct aes_context *aes_ctx = ctx;
00045         AES_MODE mode;
00046         void *iv;
00047 
00048         switch ( keylen ) {
00049         case ( 128 / 8 ):
00050                 mode = AES_MODE_128;
00051                 break;
00052         case ( 256 / 8 ):
00053                 mode = AES_MODE_256;
00054                 break;
00055         default:
00056                 return -EINVAL;
00057         }
00058 
00059         /* IV is not a relevant concept at this stage; use a dummy
00060          * value that will have no side-effects.
00061          */
00062         iv = &aes_ctx->axtls_ctx.iv;
00063 
00064         AES_set_key ( &aes_ctx->axtls_ctx, key, iv, mode );
00065 
00066         aes_ctx->decrypting = 0;
00067 
00068         return 0;
00069 }
00070 
00071 /**
00072  * Set initialisation vector
00073  *
00074  * @v ctx               Context
00075  * @v iv                Initialisation vector
00076  */
00077 static void aes_setiv ( void *ctx __unused, const void *iv __unused ) {
00078         /* Nothing to do */
00079 }
00080 
00081 /**
00082  * Call AXTLS' AES_encrypt() or AES_decrypt() functions
00083  *
00084  * @v axtls_ctx         AXTLS AES context
00085  * @v src               Data to process
00086  * @v dst               Buffer for output
00087  * @v func              AXTLS AES function to call
00088  */
00089 static void aes_call_axtls ( AES_CTX *axtls_ctx, const void *src, void *dst,
00090                              void ( * func ) ( const AES_CTX *axtls_ctx,
00091                                                uint32_t *data ) ){
00092         const uint32_t *srcl = src;
00093         uint32_t *dstl = dst;
00094         unsigned int i;
00095 
00096         /* AXTLS' AES_encrypt() and AES_decrypt() functions both
00097          * expect to deal with an array of four dwords in host-endian
00098          * order.
00099          */
00100         for ( i = 0 ; i < 4 ; i++ )
00101                 dstl[i] = ntohl ( srcl[i] );
00102         func ( axtls_ctx, dstl );
00103         for ( i = 0 ; i < 4 ; i++ )
00104                 dstl[i] = htonl ( dstl[i] );
00105 }
00106 
00107 /**
00108  * Encrypt data
00109  *
00110  * @v ctx               Context
00111  * @v src               Data to encrypt
00112  * @v dst               Buffer for encrypted data
00113  * @v len               Length of data
00114  */
00115 static void aes_encrypt ( void *ctx, const void *src, void *dst,
00116                           size_t len ) {
00117         struct aes_context *aes_ctx = ctx;
00118 
00119         assert ( len == AES_BLOCKSIZE );
00120         if ( aes_ctx->decrypting )
00121                 assert ( 0 );
00122         aes_call_axtls ( &aes_ctx->axtls_ctx, src, dst, AES_encrypt );
00123 }
00124 
00125 /**
00126  * Decrypt data
00127  *
00128  * @v ctx               Context
00129  * @v src               Data to decrypt
00130  * @v dst               Buffer for decrypted data
00131  * @v len               Length of data
00132  */
00133 static void aes_decrypt ( void *ctx, const void *src, void *dst,
00134                           size_t len ) {
00135         struct aes_context *aes_ctx = ctx;
00136 
00137         assert ( len == AES_BLOCKSIZE );
00138         if ( ! aes_ctx->decrypting ) {
00139                 AES_convert_key ( &aes_ctx->axtls_ctx );
00140                 aes_ctx->decrypting = 1;
00141         }
00142         aes_call_axtls ( &aes_ctx->axtls_ctx, src, dst, AES_decrypt );
00143 }
00144 
00145 /** Basic AES algorithm */
00146 struct cipher_algorithm aes_algorithm = {
00147         .name = "aes",
00148         .ctxsize = sizeof ( struct aes_context ),
00149         .blocksize = AES_BLOCKSIZE,
00150         .setkey = aes_setkey,
00151         .setiv = aes_setiv,
00152         .encrypt = aes_encrypt,
00153         .decrypt = aes_decrypt,
00154 };
00155 
00156 /* AES with cipher-block chaining */
00157 CBC_CIPHER ( aes_cbc, aes_cbc_algorithm,
00158              aes_algorithm, struct aes_context, AES_BLOCKSIZE );

Generated on Tue Apr 6 20:00:52 2010 for gPXE by  doxygen 1.5.7.1