iPXE
Functions
aes_wrap.c File Reference
#include <stdlib.h>
#include <string.h>
#include <ipxe/crypto.h>
#include <ipxe/aes.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER)
int aes_wrap (const void *kek, const void *src, void *dest, int nblk)
 Wrap a key or other data using AES Key Wrap (RFC 3394)
int aes_unwrap (const void *kek, const void *src, void *dest, int nblk)
 Unwrap a key or other data using AES Key Wrap (RFC 3394)

Function Documentation

FILE_LICENCE ( GPL2_OR_LATER  )
int aes_wrap ( const void *  kek,
const void *  src,
void *  dest,
int  nblk 
)

Wrap a key or other data using AES Key Wrap (RFC 3394)

Parameters:
kekKey Encryption Key, 16 bytes
srcData to encrypt
nblkNumber of 8-byte blocks in data
Return values:
destEncrypted data (8 bytes longer than input)

The algorithm is implemented such that src and dest may point to the same buffer.

Definition at line 38 of file aes_wrap.c.

References aes_algorithm, AES_CTX_SIZE, cipher_encrypt, cipher_setkey(), dest, free, malloc(), memcpy(), memmove(), and memset().

{
        u8 *A = dest;
        u8 B[16];
        u8 *R;
        int i, j;
        void *aes_ctx = malloc ( AES_CTX_SIZE );

        if ( ! aes_ctx )
                return -1;

        cipher_setkey ( &aes_algorithm, aes_ctx, kek, 16 );

        /* Set up */
        memset ( A, 0xA6, 8 );
        memmove ( dest + 8, src, nblk * 8 );

        /* Wrap */
        for ( j = 0; j < 6; j++ ) {
                R = dest + 8;
                for ( i = 1; i <= nblk; i++ ) {
                        memcpy ( B, A, 8 );
                        memcpy ( B + 8, R, 8 );
                        cipher_encrypt ( &aes_algorithm, aes_ctx, B, B, 16 );
                        memcpy ( A, B, 8 );
                        A[7] ^= ( nblk * j ) + i;
                        memcpy ( R, B + 8, 8 );
                        R += 8;
                }
        }

        free ( aes_ctx );
        return 0;
}
int aes_unwrap ( const void *  kek,
const void *  src,
void *  dest,
int  nblk 
)

Unwrap a key or other data using AES Key Wrap (RFC 3394)

Parameters:
kekKey Encryption Key, 16 bytes
srcData to decrypt
nblkNumber of 8-byte blocks in plaintext key
Return values:
destDecrypted data (8 bytes shorter than input)
rcZero on success, nonzero on IV mismatch

The algorithm is implemented such that src and dest may point to the same buffer.

Definition at line 85 of file aes_wrap.c.

References aes_algorithm, AES_CTX_SIZE, cipher_decrypt, cipher_setkey(), free, malloc(), memcpy(), and memmove().

Referenced by ccmp_kie_decrypt().

{
        u8 A[8], B[16];
        u8 *R;
        int i, j;
        void *aes_ctx = malloc ( AES_CTX_SIZE );

        if ( ! aes_ctx )
                return -1;

        cipher_setkey ( &aes_algorithm, aes_ctx, kek, 16 );

        /* Set up */
        memcpy ( A, src, 8 );
        memmove ( dest, src + 8, nblk * 8 );

        /* Unwrap */
        for ( j = 5; j >= 0; j-- ) {
                R = dest + ( nblk - 1 ) * 8;
                for ( i = nblk; i >= 1; i-- ) {
                        memcpy ( B, A, 8 );
                        memcpy ( B + 8, R, 8 );
                        B[7] ^= ( nblk * j ) + i;
                        cipher_decrypt ( &aes_algorithm, aes_ctx, B, B, 16 );
                        memcpy ( A, B, 8 );
                        memcpy ( R, B + 8, 8 );
                        R -= 8;
                }
        }

        free ( aes_ctx );

        /* Check IV */
        for ( i = 0; i < 8; i++ ) {
                if ( A[i] != 0xA6 )
                        return -1;
        }

        return 0;
}