"Fossies" - the Fresh Open Source Software Archive

Member "syslinux-6.03/gpxe/src/crypto/aes_wrap.c" (6 Oct 2014, 3011 Bytes) of package /linux/misc/syslinux-6.03.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /*
    2  * Copyright (c) 2009 Joshua Oreman <oremanj@rwcr.net>.
    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 <stdlib.h>
   22 #include <string.h>
   23 #include <gpxe/crypto.h>
   24 #include <gpxe/aes.h>
   25 
   26 /**
   27  * Wrap a key or other data using AES Key Wrap (RFC 3394)
   28  *
   29  * @v kek   Key Encryption Key, 16 bytes
   30  * @v src   Data to encrypt
   31  * @v nblk  Number of 8-byte blocks in @a data
   32  * @ret dest    Encrypted data (8 bytes longer than input)
   33  *
   34  * The algorithm is implemented such that @a src and @a dest may point
   35  * to the same buffer.
   36  */
   37 int aes_wrap ( const void *kek, const void *src, void *dest, int nblk )
   38 {
   39     u8 *A = dest;
   40     u8 B[16];
   41     u8 *R;
   42     int i, j;
   43     void *aes_ctx = malloc ( AES_CTX_SIZE );
   44 
   45     if ( ! aes_ctx )
   46         return -1;
   47 
   48     cipher_setkey ( &aes_algorithm, aes_ctx, kek, 16 );
   49 
   50     /* Set up */
   51     memset ( A, 0xA6, sizeof ( A ) );
   52     memmove ( dest + 8, src, nblk * 8 );
   53 
   54     /* Wrap */
   55     for ( j = 0; j < 6; j++ ) {
   56         R = dest + 8;
   57         for ( i = 1; i <= nblk; i++ ) {
   58             memcpy ( B, A, 8 );
   59             memcpy ( B + 8, R, 8 );
   60             cipher_encrypt ( &aes_algorithm, aes_ctx, B, B, 16 );
   61             memcpy ( A, B, 8 );
   62             A[7] ^= ( nblk * j ) + i;
   63             memcpy ( R, B + 8, 8 );
   64             R += 8;
   65         }
   66     }
   67 
   68     free ( aes_ctx );
   69     return 0;
   70 }
   71 
   72 /**
   73  * Unwrap a key or other data using AES Key Wrap (RFC 3394)
   74  *
   75  * @v kek   Key Encryption Key, 16 bytes
   76  * @v src   Data to decrypt
   77  * @v nblk  Number of 8-byte blocks in @e plaintext key
   78  * @ret dest    Decrypted data (8 bytes shorter than input)
   79  * @ret rc  Zero on success, nonzero on IV mismatch
   80  *
   81  * The algorithm is implemented such that @a src and @a dest may point
   82  * to the same buffer.
   83  */
   84 int aes_unwrap ( const void *kek, const void *src, void *dest, int nblk )
   85 {
   86     u8 A[8], B[16];
   87     u8 *R;
   88     int i, j;
   89     void *aes_ctx = malloc ( AES_CTX_SIZE );
   90 
   91     if ( ! aes_ctx )
   92         return -1;
   93 
   94     cipher_setkey ( &aes_algorithm, aes_ctx, kek, 16 );
   95 
   96     /* Set up */
   97     memcpy ( A, src, 8 );
   98     memmove ( dest, src + 8, nblk * 8 );
   99 
  100     /* Unwrap */
  101     for ( j = 5; j >= 0; j-- ) {
  102         R = dest + ( nblk - 1 ) * 8;
  103         for ( i = nblk; i >= 1; i-- ) {
  104             memcpy ( B, A, 8 );
  105             memcpy ( B + 8, R, 8 );
  106             B[7] ^= ( nblk * j ) + i;
  107             cipher_decrypt ( &aes_algorithm, aes_ctx, B, B, 16 );
  108             memcpy ( A, B, 8 );
  109             memcpy ( R, B + 8, 8 );
  110             R -= 8;
  111         }
  112     }
  113 
  114     free ( aes_ctx );
  115 
  116     /* Check IV */
  117     for ( i = 0; i < 8; i++ ) {
  118         if ( A[i] != 0xA6 )
  119             return -1;
  120     }
  121 
  122     return 0;
  123 }