Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Functions
rijndael.c File Reference
#include "prinit.h"
#include "prerr.h"
#include "secerr.h"
#include "prtypes.h"
#include "blapi.h"
#include "rijndael.h"
#include "rijndael32.tab"

Go to the source code of this file.

Classes

union  rijndael_state

Defines

#define WORD4(b0, b1, b2, b3)   (((b0) << 24) | ((b1) << 16) | ((b2) << 8) | (b3))
#define SBOX(b)   (_S[b])
#define SINV(b)   (_SInv[b])
#define XTIME(a)   ((a & 0x80) ? ((a << 1) ^ 0x1b) : (a << 1))
#define GFM01(a)   (a) /* a * 01 = a, the identity */
#define GFM02(a)   (XTIME(a) & 0xff) /* a * 02 = xtime(a) */
#define GFM03(a)   (gfm(a, 0x03)) /* a * 03 */
#define GFM09(a)   (gfm(a, 0x09)) /* a * 09 */
#define GFM0B(a)   (gfm(a, 0x0B)) /* a * 0B */
#define GFM0D(a)   (gfm(a, 0x0D)) /* a * 0D */
#define GFM0E(a)   (gfm(a, 0x0E)) /* a * 0E */
#define G_T0(i)   ( WORD4( GFM02(SBOX(i)), GFM01(SBOX(i)), GFM01(SBOX(i)), GFM03(SBOX(i)) ) )
#define G_T1(i)   ( WORD4( GFM03(SBOX(i)), GFM02(SBOX(i)), GFM01(SBOX(i)), GFM01(SBOX(i)) ) )
#define G_T2(i)   ( WORD4( GFM01(SBOX(i)), GFM03(SBOX(i)), GFM02(SBOX(i)), GFM01(SBOX(i)) ) )
#define G_T3(i)   ( WORD4( GFM01(SBOX(i)), GFM01(SBOX(i)), GFM03(SBOX(i)), GFM02(SBOX(i)) ) )
#define G_TInv0(i)   ( WORD4( GFM0E(SINV(i)), GFM09(SINV(i)), GFM0D(SINV(i)), GFM0B(SINV(i)) ) )
#define G_TInv1(i)   ( WORD4( GFM0B(SINV(i)), GFM0E(SINV(i)), GFM09(SINV(i)), GFM0D(SINV(i)) ) )
#define G_TInv2(i)   ( WORD4( GFM0D(SINV(i)), GFM0B(SINV(i)), GFM0E(SINV(i)), GFM09(SINV(i)) ) )
#define G_TInv3(i)   ( WORD4( GFM09(SINV(i)), GFM0D(SINV(i)), GFM0B(SINV(i)), GFM0E(SINV(i)) ) )
#define G_IMXC0(i)   ( WORD4( GFM0E(i), GFM09(i), GFM0D(i), GFM0B(i) ) )
#define G_IMXC1(i)   ( WORD4( GFM0B(i), GFM0E(i), GFM09(i), GFM0D(i) ) )
#define G_IMXC2(i)   ( WORD4( GFM0D(i), GFM0B(i), GFM0E(i), GFM09(i) ) )
#define G_IMXC3(i)   ( WORD4( GFM09(i), GFM0D(i), GFM0B(i), GFM0E(i) ) )
#define T0(i)   rijndaelTables->T0[i]
#define T1(i)   rijndaelTables->T1[i]
#define T2(i)   rijndaelTables->T2[i]
#define T3(i)   rijndaelTables->T3[i]
#define TInv0(i)   rijndaelTables->TInv0[i]
#define TInv1(i)   rijndaelTables->TInv1[i]
#define TInv2(i)   rijndaelTables->TInv2[i]
#define TInv3(i)   rijndaelTables->TInv3[i]
#define IMXC0(b)   G_IMXC0(b)
#define IMXC1(b)   G_IMXC1(b)
#define IMXC2(b)   G_IMXC2(b)
#define IMXC3(b)   G_IMXC3(b)
#define SUBBYTE(w)
#define ROTBYTE(b)   ((b << 8) | (b >> 24))
#define BYTE0WORD(w)   ((w) & 0xff000000)
#define BYTE1WORD(w)   ((w) & 0x00ff0000)
#define BYTE2WORD(w)   ((w) & 0x0000ff00)
#define BYTE3WORD(w)   ((w) & 0x000000ff)
#define COLUMN_0(state)   state.w[0]
#define COLUMN_1(state)   state.w[1]
#define COLUMN_2(state)   state.w[2]
#define COLUMN_3(state)   state.w[3]
#define STATE_BYTE(i)   state.b[i]
#define COLUMN(array, j)   *((PRUint32 *)(array + j))

Functions

PRUint8 gfm (PRUint8 a, PRUint8 b)
static SECStatus rijndael_key_expansion7 (AESContext *cx, const unsigned char *key, unsigned int Nk)
static SECStatus rijndael_key_expansion (AESContext *cx, const unsigned char *key, unsigned int Nk)
static SECStatus rijndael_invkey_expansion (AESContext *cx, const unsigned char *key, unsigned int Nk)
static SECStatus rijndael_encryptBlock128 (AESContext *cx, unsigned char *output, const unsigned char *input)
static SECStatus rijndael_decryptBlock128 (AESContext *cx, unsigned char *output, const unsigned char *input)
SECStatus rijndael_encryptBlock (AESContext *cx, unsigned char *output, const unsigned char *input)
SECStatus rijndael_decryptBlock (AESContext *cx, unsigned char *output, const unsigned char *input)
static SECStatus rijndael_encryptECB (AESContext *cx, unsigned char *output, unsigned int *outputLen, unsigned int maxOutputLen, const unsigned char *input, unsigned int inputLen, unsigned int blocksize)
static SECStatus rijndael_encryptCBC (AESContext *cx, unsigned char *output, unsigned int *outputLen, unsigned int maxOutputLen, const unsigned char *input, unsigned int inputLen, unsigned int blocksize)
static SECStatus rijndael_decryptECB (AESContext *cx, unsigned char *output, unsigned int *outputLen, unsigned int maxOutputLen, const unsigned char *input, unsigned int inputLen, unsigned int blocksize)
static SECStatus rijndael_decryptCBC (AESContext *cx, unsigned char *output, unsigned int *outputLen, unsigned int maxOutputLen, const unsigned char *input, unsigned int inputLen, unsigned int blocksize)
AESContext * AES_AllocateContext (void)
SECStatus AES_InitContext (AESContext *cx, const unsigned char *key, unsigned int keysize, const unsigned char *iv, int mode, unsigned int encrypt, unsigned int blocksize)
AESContext * AES_CreateContext (const unsigned char *key, const unsigned char *iv, int mode, int encrypt, unsigned int keysize, unsigned int blocksize)
void AES_DestroyContext (AESContext *cx, PRBool freeit)
SECStatus AES_Encrypt (AESContext *cx, unsigned char *output, unsigned int *outputLen, unsigned int maxOutputLen, const unsigned char *input, unsigned int inputLen)
SECStatus AES_Decrypt (AESContext *cx, unsigned char *output, unsigned int *outputLen, unsigned int maxOutputLen, const unsigned char *input, unsigned int inputLen)

Class Documentation

union rijndael_state

Definition at line 536 of file rijndael.c.

Class Members
PRUint8 b
PRUint32 w

Define Documentation

#define BYTE0WORD (   w)    ((w) & 0xff000000)

Definition at line 530 of file rijndael.c.

#define BYTE1WORD (   w)    ((w) & 0x00ff0000)

Definition at line 531 of file rijndael.c.

#define BYTE2WORD (   w)    ((w) & 0x0000ff00)

Definition at line 532 of file rijndael.c.

#define BYTE3WORD (   w)    ((w) & 0x000000ff)

Definition at line 533 of file rijndael.c.

#define COLUMN (   array,
  j 
)    *((PRUint32 *)(array + j))

Definition at line 747 of file rijndael.c.

#define COLUMN_0 (   state)    state.w[0]

Definition at line 541 of file rijndael.c.

#define COLUMN_1 (   state)    state.w[1]

Definition at line 542 of file rijndael.c.

#define COLUMN_2 (   state)    state.w[2]

Definition at line 543 of file rijndael.c.

#define COLUMN_3 (   state)    state.w[3]

Definition at line 544 of file rijndael.c.

#define G_IMXC0 (   i)    ( WORD4( GFM0E(i), GFM09(i), GFM0D(i), GFM0B(i) ) )

Definition at line 207 of file rijndael.c.

#define G_IMXC1 (   i)    ( WORD4( GFM0B(i), GFM0E(i), GFM09(i), GFM0D(i) ) )

Definition at line 209 of file rijndael.c.

#define G_IMXC2 (   i)    ( WORD4( GFM0D(i), GFM0B(i), GFM0E(i), GFM09(i) ) )

Definition at line 211 of file rijndael.c.

#define G_IMXC3 (   i)    ( WORD4( GFM09(i), GFM0D(i), GFM0B(i), GFM0E(i) ) )

Definition at line 213 of file rijndael.c.

#define G_T0 (   i)    ( WORD4( GFM02(SBOX(i)), GFM01(SBOX(i)), GFM01(SBOX(i)), GFM03(SBOX(i)) ) )

Definition at line 183 of file rijndael.c.

#define G_T1 (   i)    ( WORD4( GFM03(SBOX(i)), GFM02(SBOX(i)), GFM01(SBOX(i)), GFM01(SBOX(i)) ) )

Definition at line 185 of file rijndael.c.

#define G_T2 (   i)    ( WORD4( GFM01(SBOX(i)), GFM03(SBOX(i)), GFM02(SBOX(i)), GFM01(SBOX(i)) ) )

Definition at line 187 of file rijndael.c.

#define G_T3 (   i)    ( WORD4( GFM01(SBOX(i)), GFM01(SBOX(i)), GFM03(SBOX(i)), GFM02(SBOX(i)) ) )

Definition at line 189 of file rijndael.c.

#define G_TInv0 (   i)    ( WORD4( GFM0E(SINV(i)), GFM09(SINV(i)), GFM0D(SINV(i)), GFM0B(SINV(i)) ) )

Definition at line 195 of file rijndael.c.

#define G_TInv1 (   i)    ( WORD4( GFM0B(SINV(i)), GFM0E(SINV(i)), GFM09(SINV(i)), GFM0D(SINV(i)) ) )

Definition at line 197 of file rijndael.c.

#define G_TInv2 (   i)    ( WORD4( GFM0D(SINV(i)), GFM0B(SINV(i)), GFM0E(SINV(i)), GFM09(SINV(i)) ) )

Definition at line 199 of file rijndael.c.

#define G_TInv3 (   i)    ( WORD4( GFM09(SINV(i)), GFM0D(SINV(i)), GFM0B(SINV(i)), GFM0E(SINV(i)) ) )

Definition at line 201 of file rijndael.c.

#define GFM01 (   a)    (a) /* a * 01 = a, the identity */

Definition at line 163 of file rijndael.c.

#define GFM02 (   a)    (XTIME(a) & 0xff) /* a * 02 = xtime(a) */

Definition at line 165 of file rijndael.c.

#define GFM03 (   a)    (gfm(a, 0x03)) /* a * 03 */

Definition at line 167 of file rijndael.c.

#define GFM09 (   a)    (gfm(a, 0x09)) /* a * 09 */

Definition at line 169 of file rijndael.c.

#define GFM0B (   a)    (gfm(a, 0x0B)) /* a * 0B */

Definition at line 171 of file rijndael.c.

#define GFM0D (   a)    (gfm(a, 0x0D)) /* a * 0D */

Definition at line 173 of file rijndael.c.

#define GFM0E (   a)    (gfm(a, 0x0E)) /* a * 0E */

Definition at line 175 of file rijndael.c.

#define IMXC0 (   b)    G_IMXC0(b)

Definition at line 280 of file rijndael.c.

#define IMXC1 (   b)    G_IMXC1(b)

Definition at line 281 of file rijndael.c.

#define IMXC2 (   b)    G_IMXC2(b)

Definition at line 282 of file rijndael.c.

#define IMXC3 (   b)    G_IMXC3(b)

Definition at line 283 of file rijndael.c.

#define ROTBYTE (   b)    ((b << 8) | (b >> 24))

Definition at line 362 of file rijndael.c.

#define SBOX (   b)    (_S[b])

Definition at line 111 of file rijndael.c.

#define SINV (   b)    (_SInv[b])

Definition at line 112 of file rijndael.c.

#define STATE_BYTE (   i)    state.b[i]

Definition at line 546 of file rijndael.c.

#define SUBBYTE (   w)
Value:
((SBOX((w >> 24) & 0xff) << 24) | \
     (SBOX((w >> 16) & 0xff) << 16) | \
     (SBOX((w >>  8) & 0xff) <<  8) | \
     (SBOX((w      ) & 0xff)         ))

Definition at line 352 of file rijndael.c.

#define T0 (   i)    rijndaelTables->T0[i]

Definition at line 272 of file rijndael.c.

#define T1 (   i)    rijndaelTables->T1[i]

Definition at line 273 of file rijndael.c.

#define T2 (   i)    rijndaelTables->T2[i]

Definition at line 274 of file rijndael.c.

#define T3 (   i)    rijndaelTables->T3[i]

Definition at line 275 of file rijndael.c.

#define TInv0 (   i)    rijndaelTables->TInv0[i]

Definition at line 276 of file rijndael.c.

#define TInv1 (   i)    rijndaelTables->TInv1[i]

Definition at line 277 of file rijndael.c.

#define TInv2 (   i)    rijndaelTables->TInv2[i]

Definition at line 278 of file rijndael.c.

#define TInv3 (   i)    rijndaelTables->TInv3[i]

Definition at line 279 of file rijndael.c.

#define WORD4 (   b0,
  b1,
  b2,
  b3 
)    (((b0) << 24) | ((b1) << 16) | ((b2) << 8) | (b3))

Definition at line 104 of file rijndael.c.

#define XTIME (   a)    ((a & 0x80) ? ((a << 1) ^ 0x1b) : (a << 1))

Definition at line 117 of file rijndael.c.


Function Documentation

AESContext* AES_AllocateContext ( void  )

Definition at line 972 of file rijndael.c.

{
    return PORT_ZNew(AESContext);
}
AESContext* AES_CreateContext ( const unsigned char *  key,
const unsigned char *  iv,
int  mode,
int  encrypt,
unsigned int  keysize,
unsigned int  blocksize 
)

Definition at line 1046 of file rijndael.c.

{
    AESContext *cx = AES_AllocateContext();
    if (cx) {
       SECStatus rv = AES_InitContext(cx, key, keysize, iv, mode, encrypt,
                                   blocksize);
       if (rv != SECSuccess) {
           AES_DestroyContext(cx, PR_TRUE);
           cx = NULL;
       }
    }
    return cx;
}

Here is the call graph for this function:

SECStatus AES_Decrypt ( AESContext *  cx,
unsigned char *  output,
unsigned int outputLen,
unsigned int  maxOutputLen,
const unsigned char *  input,
unsigned int  inputLen 
)

Definition at line 1123 of file rijndael.c.

{
    int blocksize;
    /* Check args */
    if (cx == NULL || output == NULL || input == NULL) {
       PORT_SetError(SEC_ERROR_INVALID_ARGS);
       return SECFailure;
    }
    blocksize = 4 * cx->Nb;
    if (inputLen % blocksize != 0) {
       PORT_SetError(SEC_ERROR_INPUT_LEN);
       return SECFailure;
    }
    if (maxOutputLen < inputLen) {
       PORT_SetError(SEC_ERROR_OUTPUT_LEN);
       return SECFailure;
    }
    *outputLen = inputLen;
#if defined(RIJNDAEL_GENERATE_TABLES) ||  \
    defined(RIJNDAEL_GENERATE_TABLES_MACRO)
    if (rijndaelTables == NULL) {
       if (PR_CallOnce(&coRTInit, init_rijndael_tables) 
             != PR_SUCCESS) {
           return PR_FAILURE;
       }
    }
#endif
    return (*cx->worker)(cx, output, outputLen, maxOutputLen,  
                             input, inputLen, blocksize);
}

Here is the call graph for this function:

void AES_DestroyContext ( AESContext *  cx,
PRBool  freeit 
)

Definition at line 1069 of file rijndael.c.

{
/*  memset(cx, 0, sizeof *cx); */
    if (freeit)
       PORT_Free(cx);
}

Here is the call graph for this function:

SECStatus AES_Encrypt ( AESContext *  cx,
unsigned char *  output,
unsigned int outputLen,
unsigned int  maxOutputLen,
const unsigned char *  input,
unsigned int  inputLen 
)

Definition at line 1083 of file rijndael.c.

{
    int blocksize;
    /* Check args */
    if (cx == NULL || output == NULL || input == NULL) {
       PORT_SetError(SEC_ERROR_INVALID_ARGS);
       return SECFailure;
    }
    blocksize = 4 * cx->Nb;
    if (inputLen % blocksize != 0) {
       PORT_SetError(SEC_ERROR_INPUT_LEN);
       return SECFailure;
    }
    if (maxOutputLen < inputLen) {
       PORT_SetError(SEC_ERROR_OUTPUT_LEN);
       return SECFailure;
    }
    *outputLen = inputLen;
#if defined(RIJNDAEL_GENERATE_TABLES) ||  \
    defined(RIJNDAEL_GENERATE_TABLES_MACRO)
    if (rijndaelTables == NULL) {
       if (PR_CallOnce(&coRTInit, init_rijndael_tables) 
             != PR_SUCCESS) {
           return PR_FAILURE;
       }
    }
#endif
    return (*cx->worker)(cx, output, outputLen, maxOutputLen,  
                             input, inputLen, blocksize);
}

Here is the call graph for this function:

SECStatus AES_InitContext ( AESContext *  cx,
const unsigned char *  key,
unsigned int  keysize,
const unsigned char *  iv,
int  mode,
unsigned int  encrypt,
unsigned int  blocksize 
)

Definition at line 978 of file rijndael.c.

{
    unsigned int Nk;
    /* According to Rijndael AES Proposal, section 12.1, block and key
     * lengths between 128 and 256 bits are supported, as long as the
     * length in bytes is divisible by 4.
     */
    if (key == NULL || 
        keysize < RIJNDAEL_MIN_BLOCKSIZE   || 
       keysize > RIJNDAEL_MAX_BLOCKSIZE   || 
       keysize % 4 != 0 ||
        blocksize < RIJNDAEL_MIN_BLOCKSIZE || 
       blocksize > RIJNDAEL_MAX_BLOCKSIZE || 
       blocksize % 4 != 0) {
       PORT_SetError(SEC_ERROR_INVALID_ARGS);
       return SECFailure;
    }
    if (mode != NSS_AES && mode != NSS_AES_CBC) {
       PORT_SetError(SEC_ERROR_INVALID_ARGS);
       return SECFailure;
    }
    if (mode == NSS_AES_CBC && iv == NULL) {
       PORT_SetError(SEC_ERROR_INVALID_ARGS);
       return SECFailure;
    }
    if (!cx) {
       PORT_SetError(SEC_ERROR_INVALID_ARGS);
       return SECFailure;
    }
    /* Nb = (block size in bits) / 32 */
    cx->Nb = blocksize / 4;
    /* Nk = (key size in bits) / 32 */
    Nk = keysize / 4;
    /* Obtain number of rounds from "table" */
    cx->Nr = RIJNDAEL_NUM_ROUNDS(Nk, cx->Nb);
    /* copy in the iv, if neccessary */
    if (mode == NSS_AES_CBC) {
       memcpy(cx->iv, iv, blocksize);
       cx->worker = (encrypt) ? &rijndael_encryptCBC : &rijndael_decryptCBC;
    } else {
       cx->worker = (encrypt) ? &rijndael_encryptECB : &rijndael_decryptECB;
    }
    PORT_Assert((cx->Nb * (cx->Nr + 1)) <= RIJNDAEL_MAX_EXP_KEY_SIZE);
    if ((cx->Nb * (cx->Nr + 1)) > RIJNDAEL_MAX_EXP_KEY_SIZE) {
       PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
       goto cleanup;
    }
    /* Generate expanded key */
    if (encrypt) {
       if (rijndael_key_expansion(cx, key, Nk) != SECSuccess)
           goto cleanup;
    } else {
       if (rijndael_invkey_expansion(cx, key, Nk) != SECSuccess)
           goto cleanup;
    }
    return SECSuccess;
cleanup:
    return SECFailure;
}

Here is the call graph for this function:

PRUint8 gfm ( PRUint8  a,
PRUint8  b 
)

Definition at line 152 of file rijndael.c.

{
    PRUint8 res = 0;
    while (b > 0) {
       res = (b & 0x01) ? res ^ a : res;
       a = XTIME(a);
       b >>= 1;
    }
    return res;
}
SECStatus rijndael_decryptBlock ( AESContext *  cx,
unsigned char *  output,
const unsigned char *  input 
)

Definition at line 792 of file rijndael.c.

{
    return SECFailure;
#ifdef rijndael_large_blocks_fixed
    int j, r, Nb;
    int c2=0, c3=0;
    PRUint32 *roundkeyw;
    PRUint8 clone[RIJNDAEL_MAX_STATE_SIZE];
    Nb = cx->Nb;
    roundkeyw = cx->expandedKey + cx->Nb * cx->Nr + 3;
    /* reverse key addition */
    for (j=4*Nb; j>=0; j-=4) {
       COLUMN(clone, j) = COLUMN(input, j) ^ *roundkeyw--;
    }
    /* Loop over rounds in reverse [NR..1] */
    for (r=cx->Nr; r>1; --r) {
       /* Invert the (InvByteSub*InvMixColumn)(InvShiftRow(state)) */
       for (j=0; j<Nb; ++j) {
           COLUMN(output, 4*j) = TInv0(STATE_BYTE(4* j            )) ^
                                 TInv1(STATE_BYTE(4*(j+Nb- 1)%Nb)+1) ^
                                 TInv2(STATE_BYTE(4*(j+Nb-c2)%Nb)+2) ^
                                 TInv3(STATE_BYTE(4*(j+Nb-c3)%Nb)+3);
       }
       /* Invert the key addition step */
       for (j=4*Nb; j>=0; j-=4) {
           COLUMN(clone, j) = COLUMN(output, j) ^ *roundkeyw--;
       }
    }
    /* inverse sub */
    for (j=0; j<4*Nb; ++j) {
       output[j] = SINV(clone[j]);
    }
    /* final key addition */
    for (j=4*Nb; j>=0; j-=4) {
       COLUMN(output, j) ^= *roundkeyw--;
    }
    return SECSuccess;
#endif
}

Here is the caller graph for this function:

static SECStatus rijndael_decryptBlock128 ( AESContext *  cx,
unsigned char *  output,
const unsigned char *  input 
) [static]

Definition at line 645 of file rijndael.c.

{
    int r;
    PRUint32 *roundkeyw;
    rijndael_state state;
    PRUint32 C0, C1, C2, C3;
#if defined(_X86_)
#define pIn input
#define pOut output
#else
    unsigned char *pIn, *pOut;
    PRUint32 inBuf[4], outBuf[4];

    if ((ptrdiff_t)input & 0x3) {
       memcpy(inBuf, input, sizeof inBuf);
       pIn = (unsigned char *)inBuf;
    } else {
       pIn = (unsigned char *)input;
    }
    if ((ptrdiff_t)output & 0x3) {
       pOut = (unsigned char *)outBuf;
    } else {
       pOut = (unsigned char *)output;
    }
#endif
    roundkeyw = cx->expandedKey + cx->Nb * cx->Nr + 3;
    /* reverse the final key addition */
    COLUMN_3(state) = *((PRUint32 *)(pIn + 12)) ^ *roundkeyw--;
    COLUMN_2(state) = *((PRUint32 *)(pIn +  8)) ^ *roundkeyw--;
    COLUMN_1(state) = *((PRUint32 *)(pIn +  4)) ^ *roundkeyw--;
    COLUMN_0(state) = *((PRUint32 *)(pIn     )) ^ *roundkeyw--;
    /* Loop over rounds in reverse [NR..1] */
    for (r=cx->Nr; r>1; --r) {
       /* Invert the (InvByteSub*InvMixColumn)(InvShiftRow(state)) */
       C0 = TInv0(STATE_BYTE(0))  ^
            TInv1(STATE_BYTE(13)) ^
            TInv2(STATE_BYTE(10)) ^
            TInv3(STATE_BYTE(7));
       C1 = TInv0(STATE_BYTE(4))  ^
            TInv1(STATE_BYTE(1))  ^
            TInv2(STATE_BYTE(14)) ^
            TInv3(STATE_BYTE(11));
       C2 = TInv0(STATE_BYTE(8))  ^
            TInv1(STATE_BYTE(5))  ^
            TInv2(STATE_BYTE(2))  ^
            TInv3(STATE_BYTE(15));
       C3 = TInv0(STATE_BYTE(12)) ^
            TInv1(STATE_BYTE(9))  ^
            TInv2(STATE_BYTE(6))  ^
            TInv3(STATE_BYTE(3));
       /* Invert the key addition step */
       COLUMN_3(state) = C3 ^ *roundkeyw--;
       COLUMN_2(state) = C2 ^ *roundkeyw--;
       COLUMN_1(state) = C1 ^ *roundkeyw--;
       COLUMN_0(state) = C0 ^ *roundkeyw--;
    }
    /* inverse sub */
    pOut[ 0] = SINV(STATE_BYTE( 0));
    pOut[ 1] = SINV(STATE_BYTE(13));
    pOut[ 2] = SINV(STATE_BYTE(10));
    pOut[ 3] = SINV(STATE_BYTE( 7));
    pOut[ 4] = SINV(STATE_BYTE( 4));
    pOut[ 5] = SINV(STATE_BYTE( 1));
    pOut[ 6] = SINV(STATE_BYTE(14));
    pOut[ 7] = SINV(STATE_BYTE(11));
    pOut[ 8] = SINV(STATE_BYTE( 8));
    pOut[ 9] = SINV(STATE_BYTE( 5));
    pOut[10] = SINV(STATE_BYTE( 2));
    pOut[11] = SINV(STATE_BYTE(15));
    pOut[12] = SINV(STATE_BYTE(12));
    pOut[13] = SINV(STATE_BYTE( 9));
    pOut[14] = SINV(STATE_BYTE( 6));
    pOut[15] = SINV(STATE_BYTE( 3));
    /* final key addition */
    *((PRUint32 *)(pOut + 12)) ^= *roundkeyw--;
    *((PRUint32 *)(pOut +  8)) ^= *roundkeyw--;
    *((PRUint32 *)(pOut +  4)) ^= *roundkeyw--;
    *((PRUint32 *) pOut      ) ^= *roundkeyw--;
#if defined(_X86_)
#undef pIn
#undef pOut
#else
    if ((ptrdiff_t)output & 0x3) {
       memcpy(output, outBuf, sizeof outBuf);
    }
#endif
    return SECSuccess;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static SECStatus rijndael_decryptCBC ( AESContext *  cx,
unsigned char *  output,
unsigned int outputLen,
unsigned int  maxOutputLen,
const unsigned char *  input,
unsigned int  inputLen,
unsigned int  blocksize 
) [static]

Definition at line 921 of file rijndael.c.

{
    SECStatus rv;
    AESBlockFunc *decryptor;
    const unsigned char *in;
    unsigned char *out;
    unsigned int j;
    unsigned char newIV[RIJNDAEL_MAX_BLOCKSIZE];

    if (!inputLen) 
       return SECSuccess;
    PORT_Assert(output - input >= 0 || input - output >= (int)inputLen );
    decryptor = (blocksize == RIJNDAEL_MIN_BLOCKSIZE) 
                                  ? &rijndael_decryptBlock128 
                              : &rijndael_decryptBlock;
    in  = input  + (inputLen - blocksize);
    memcpy(newIV, in, blocksize);
    out = output + (inputLen - blocksize);
    while (inputLen > blocksize) {
        rv = (*decryptor)(cx, out, in);
       if (rv != SECSuccess)
           return rv;
       for (j=0; j<blocksize; ++j)
           out[j] ^= in[(int)(j - blocksize)];
       out -= blocksize;
       in -= blocksize;
       inputLen -= blocksize;
    }
    if (in == input) {
        rv = (*decryptor)(cx, out, in);
       if (rv != SECSuccess)
           return rv;
       for (j=0; j<blocksize; ++j)
           out[j] ^= cx->iv[j];
    }
    memcpy(cx->iv, newIV, blocksize);
    return SECSuccess;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static SECStatus rijndael_decryptECB ( AESContext *  cx,
unsigned char *  output,
unsigned int outputLen,
unsigned int  maxOutputLen,
const unsigned char *  input,
unsigned int  inputLen,
unsigned int  blocksize 
) [static]

Definition at line 899 of file rijndael.c.

{
    SECStatus rv;
    AESBlockFunc *decryptor;
    decryptor = (blocksize == RIJNDAEL_MIN_BLOCKSIZE) 
                              ? &rijndael_decryptBlock128 
                              : &rijndael_decryptBlock;
    while (inputLen > 0) {
        rv = (*decryptor)(cx, output, input);
       if (rv != SECSuccess)
           return rv;
       output += blocksize;
       input += blocksize;
       inputLen -= blocksize;
    }
    return SECSuccess;
}

Here is the call graph for this function:

Here is the caller graph for this function:

SECStatus rijndael_encryptBlock ( AESContext *  cx,
unsigned char *  output,
const unsigned char *  input 
)

Definition at line 750 of file rijndael.c.

{
    return SECFailure;
#ifdef rijndael_large_blocks_fixed
    unsigned int j, r, Nb;
    unsigned int c2=0, c3=0;
    PRUint32 *roundkeyw;
    PRUint8 clone[RIJNDAEL_MAX_STATE_SIZE];
    Nb = cx->Nb;
    roundkeyw = cx->expandedKey;
    /* Step 1: Add Round Key 0 to initial state */
    for (j=0; j<4*Nb; j+=4) {
       COLUMN(clone, j) = COLUMN(input, j) ^ *roundkeyw++;
    }
    /* Step 2: Loop over rounds [1..NR-1] */
    for (r=1; r<cx->Nr; ++r) {
       for (j=0; j<Nb; ++j) {
           COLUMN(output, j) = T0(STATE_BYTE(4*  j          )) ^
                               T1(STATE_BYTE(4*((j+ 1)%Nb)+1)) ^
                               T2(STATE_BYTE(4*((j+c2)%Nb)+2)) ^
                               T3(STATE_BYTE(4*((j+c3)%Nb)+3));
       }
       for (j=0; j<4*Nb; j+=4) {
           COLUMN(clone, j) = COLUMN(output, j) ^ *roundkeyw++;
       }
    }
    /* Step 3: Do the last round */
    /* Final round does not employ MixColumn */
    for (j=0; j<Nb; ++j) {
       COLUMN(output, j) = ((BYTE0WORD(T2(STATE_BYTE(4* j         ))))  |
                             (BYTE1WORD(T3(STATE_BYTE(4*(j+ 1)%Nb)+1)))  |
                             (BYTE2WORD(T0(STATE_BYTE(4*(j+c2)%Nb)+2)))  |
                             (BYTE3WORD(T1(STATE_BYTE(4*(j+c3)%Nb)+3)))) ^
                            *roundkeyw++;
    }
    return SECSuccess;
#endif
}

Here is the caller graph for this function:

static SECStatus rijndael_encryptBlock128 ( AESContext *  cx,
unsigned char *  output,
const unsigned char *  input 
) [static]

Definition at line 549 of file rijndael.c.

{
    unsigned int r;
    PRUint32 *roundkeyw;
    rijndael_state state;
    PRUint32 C0, C1, C2, C3;
#if defined(_X86_)
#define pIn input
#define pOut output
#else
    unsigned char *pIn, *pOut;
    PRUint32 inBuf[4], outBuf[4];

    if ((ptrdiff_t)input & 0x3) {
       memcpy(inBuf, input, sizeof inBuf);
       pIn = (unsigned char *)inBuf;
    } else {
       pIn = (unsigned char *)input;
    }
    if ((ptrdiff_t)output & 0x3) {
       pOut = (unsigned char *)outBuf;
    } else {
       pOut = (unsigned char *)output;
    }
#endif
    roundkeyw = cx->expandedKey;
    /* Step 1: Add Round Key 0 to initial state */
    COLUMN_0(state) = *((PRUint32 *)(pIn     )) ^ *roundkeyw++;
    COLUMN_1(state) = *((PRUint32 *)(pIn + 4 )) ^ *roundkeyw++;
    COLUMN_2(state) = *((PRUint32 *)(pIn + 8 )) ^ *roundkeyw++;
    COLUMN_3(state) = *((PRUint32 *)(pIn + 12)) ^ *roundkeyw++;
    /* Step 2: Loop over rounds [1..NR-1] */
    for (r=1; r<cx->Nr; ++r) {
        /* Do ShiftRow, ByteSub, and MixColumn all at once */
       C0 = T0(STATE_BYTE(0))  ^
            T1(STATE_BYTE(5))  ^
            T2(STATE_BYTE(10)) ^
            T3(STATE_BYTE(15));
       C1 = T0(STATE_BYTE(4))  ^
            T1(STATE_BYTE(9))  ^
            T2(STATE_BYTE(14)) ^
            T3(STATE_BYTE(3));
       C2 = T0(STATE_BYTE(8))  ^
            T1(STATE_BYTE(13)) ^
            T2(STATE_BYTE(2))  ^
            T3(STATE_BYTE(7));
       C3 = T0(STATE_BYTE(12)) ^
            T1(STATE_BYTE(1))  ^
            T2(STATE_BYTE(6))  ^
            T3(STATE_BYTE(11));
       /* Round key addition */
       COLUMN_0(state) = C0 ^ *roundkeyw++;
       COLUMN_1(state) = C1 ^ *roundkeyw++;
       COLUMN_2(state) = C2 ^ *roundkeyw++;
       COLUMN_3(state) = C3 ^ *roundkeyw++;
    }
    /* Step 3: Do the last round */
    /* Final round does not employ MixColumn */
    C0 = ((BYTE0WORD(T2(STATE_BYTE(0))))   |
          (BYTE1WORD(T3(STATE_BYTE(5))))   |
          (BYTE2WORD(T0(STATE_BYTE(10))))  |
          (BYTE3WORD(T1(STATE_BYTE(15)))))  ^
          *roundkeyw++;
    C1 = ((BYTE0WORD(T2(STATE_BYTE(4))))   |
          (BYTE1WORD(T3(STATE_BYTE(9))))   |
          (BYTE2WORD(T0(STATE_BYTE(14))))  |
          (BYTE3WORD(T1(STATE_BYTE(3)))))   ^
          *roundkeyw++;
    C2 = ((BYTE0WORD(T2(STATE_BYTE(8))))   |
          (BYTE1WORD(T3(STATE_BYTE(13))))  |
          (BYTE2WORD(T0(STATE_BYTE(2))))   |
          (BYTE3WORD(T1(STATE_BYTE(7)))))   ^
          *roundkeyw++;
    C3 = ((BYTE0WORD(T2(STATE_BYTE(12))))  |
          (BYTE1WORD(T3(STATE_BYTE(1))))   |
          (BYTE2WORD(T0(STATE_BYTE(6))))   |
          (BYTE3WORD(T1(STATE_BYTE(11)))))  ^
          *roundkeyw++;
    *((PRUint32 *) pOut     )  = C0;
    *((PRUint32 *)(pOut + 4))  = C1;
    *((PRUint32 *)(pOut + 8))  = C2;
    *((PRUint32 *)(pOut + 12)) = C3;
#if defined(_X86_)
#undef pIn
#undef pOut
#else
    if ((ptrdiff_t)output & 0x3) {
       memcpy(output, outBuf, sizeof outBuf);
    }
#endif
    return SECSuccess;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static SECStatus rijndael_encryptCBC ( AESContext *  cx,
unsigned char *  output,
unsigned int outputLen,
unsigned int  maxOutputLen,
const unsigned char *  input,
unsigned int  inputLen,
unsigned int  blocksize 
) [static]

Definition at line 863 of file rijndael.c.

{
    unsigned int j;
    SECStatus rv;
    AESBlockFunc *encryptor;
    unsigned char *lastblock;
    unsigned char inblock[RIJNDAEL_MAX_STATE_SIZE * 8];

    if (!inputLen)
       return SECSuccess;
    lastblock = cx->iv;
    encryptor = (blocksize == RIJNDAEL_MIN_BLOCKSIZE) 
                              ? &rijndael_encryptBlock128 
                              : &rijndael_encryptBlock;
    while (inputLen > 0) {
       /* XOR with the last block (IV if first block) */
       for (j=0; j<blocksize; ++j)
           inblock[j] = input[j] ^ lastblock[j];
       /* encrypt */
        rv = (*encryptor)(cx, output, inblock);
       if (rv != SECSuccess)
           return rv;
       /* move to the next block */
       lastblock = output;
       output += blocksize;
       input += blocksize;
       inputLen -= blocksize;
    }
    memcpy(cx->iv, lastblock, blocksize);
    return SECSuccess;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static SECStatus rijndael_encryptECB ( AESContext *  cx,
unsigned char *  output,
unsigned int outputLen,
unsigned int  maxOutputLen,
const unsigned char *  input,
unsigned int  inputLen,
unsigned int  blocksize 
) [static]

Definition at line 841 of file rijndael.c.

{
    SECStatus rv;
    AESBlockFunc *encryptor;
    encryptor = (blocksize == RIJNDAEL_MIN_BLOCKSIZE) 
                              ? &rijndael_encryptBlock128 
                              : &rijndael_encryptBlock;
    while (inputLen > 0) {
        rv = (*encryptor)(cx, output, input);
       if (rv != SECSuccess)
           return rv;
       output += blocksize;
       input += blocksize;
       inputLen -= blocksize;
    }
    return SECSuccess;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static SECStatus rijndael_invkey_expansion ( AESContext *  cx,
const unsigned char *  key,
unsigned int  Nk 
) [static]

Definition at line 469 of file rijndael.c.

{
    unsigned int r;
    PRUint32 *roundkeyw;
    PRUint8 *b;
    int Nb = cx->Nb;
    /* begins like usual key expansion ... */
    if (rijndael_key_expansion(cx, key, Nk) != SECSuccess)
       return SECFailure;
    /* ... but has the additional step of InvMixColumn,
     * excepting the first and last round keys.
     */
    roundkeyw = cx->expandedKey + cx->Nb;
    for (r=1; r<cx->Nr; ++r) {
       /* each key word, roundkeyw, represents a column in the key
        * matrix.  Each column is multiplied by the InvMixColumn matrix.
        *   [ 0E 0B 0D 09 ]   [ b0 ]
        *   [ 09 0E 0B 0D ] * [ b1 ]
        *   [ 0D 09 0E 0B ]   [ b2 ]
        *   [ 0B 0D 09 0E ]   [ b3 ]
        */
       b = (PRUint8 *)roundkeyw;
       *roundkeyw++ = IMXC0(b[0]) ^ IMXC1(b[1]) ^ IMXC2(b[2]) ^ IMXC3(b[3]);
       b = (PRUint8 *)roundkeyw;
       *roundkeyw++ = IMXC0(b[0]) ^ IMXC1(b[1]) ^ IMXC2(b[2]) ^ IMXC3(b[3]);
       b = (PRUint8 *)roundkeyw;
       *roundkeyw++ = IMXC0(b[0]) ^ IMXC1(b[1]) ^ IMXC2(b[2]) ^ IMXC3(b[3]);
       b = (PRUint8 *)roundkeyw;
       *roundkeyw++ = IMXC0(b[0]) ^ IMXC1(b[1]) ^ IMXC2(b[2]) ^ IMXC3(b[3]);
       if (Nb <= 4)
           continue;
       switch (Nb) {
       case 8: b = (PRUint8 *)roundkeyw;
               *roundkeyw++ = IMXC0(b[0]) ^ IMXC1(b[1]) ^ 
                              IMXC2(b[2]) ^ IMXC3(b[3]);
       case 7: b = (PRUint8 *)roundkeyw;
               *roundkeyw++ = IMXC0(b[0]) ^ IMXC1(b[1]) ^ 
                              IMXC2(b[2]) ^ IMXC3(b[3]);
       case 6: b = (PRUint8 *)roundkeyw;
               *roundkeyw++ = IMXC0(b[0]) ^ IMXC1(b[1]) ^ 
                              IMXC2(b[2]) ^ IMXC3(b[3]);
       case 5: b = (PRUint8 *)roundkeyw;
               *roundkeyw++ = IMXC0(b[0]) ^ IMXC1(b[1]) ^ 
                              IMXC2(b[2]) ^ IMXC3(b[3]);
       }
    }
    return SECSuccess;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static SECStatus rijndael_key_expansion ( AESContext *  cx,
const unsigned char *  key,
unsigned int  Nk 
) [static]

Definition at line 405 of file rijndael.c.

{
    unsigned int i;
    PRUint32 *W;
    PRUint32 *pW;
    PRUint32 tmp;
    unsigned int round_key_words = cx->Nb * (cx->Nr + 1);
    if (Nk == 7)
       return rijndael_key_expansion7(cx, key, Nk);
    W = cx->expandedKey;
    /* The first Nk words contain the input cipher key */
    memcpy(W, key, Nk * 4);
    i = Nk;
    pW = W + i - 1;
    /* Loop over all sets of Nk words, except the last */
    while (i < round_key_words - Nk) {
       tmp = *pW++;
       tmp = SUBBYTE(ROTBYTE(tmp)) ^ Rcon[i / Nk - 1];
       *pW = W[i++ - Nk] ^ tmp;
       tmp = *pW++; *pW = W[i++ - Nk] ^ tmp;
       tmp = *pW++; *pW = W[i++ - Nk] ^ tmp;
       tmp = *pW++; *pW = W[i++ - Nk] ^ tmp;
       if (Nk == 4)
           continue;
       switch (Nk) {
       case 8: tmp = *pW++; tmp = SUBBYTE(tmp); *pW = W[i++ - Nk] ^ tmp;
       case 7: tmp = *pW++; *pW = W[i++ - Nk] ^ tmp;
       case 6: tmp = *pW++; *pW = W[i++ - Nk] ^ tmp;
       case 5: tmp = *pW++; *pW = W[i++ - Nk] ^ tmp;
       }
    }
    /* Generate the last word */
    tmp = *pW++;
    tmp = SUBBYTE(ROTBYTE(tmp)) ^ Rcon[i / Nk - 1];
    *pW = W[i++ - Nk] ^ tmp;
    /* There may be overflow here, if Nk % (Nb * (Nr + 1)) > 0.  However,
     * since the above loop generated all but the last Nk key words, there
     * is no more need for the SubByte transformation.
     */
    if (Nk < 8) {
       for (; i < round_key_words; ++i) {
           tmp = *pW++; 
           *pW = W[i - Nk] ^ tmp;
       }
    } else {
       /* except in the case when Nk == 8.  Then one more SubByte may have
        * to be performed, at i % Nk == 4.
        */
       for (; i < round_key_words; ++i) {
           tmp = *pW++;
           if (i % Nk == 4)
              tmp = SUBBYTE(tmp);
           *pW = W[i - Nk] ^ tmp;
       }
    }
    return SECSuccess;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static SECStatus rijndael_key_expansion7 ( AESContext *  cx,
const unsigned char *  key,
unsigned int  Nk 
) [static]

Definition at line 377 of file rijndael.c.

{
    unsigned int i;
    PRUint32 *W;
    PRUint32 *pW;
    PRUint32 tmp;
    W = cx->expandedKey;
    /* 1.  the first Nk words contain the cipher key */
    memcpy(W, key, Nk * 4);
    i = Nk;
    /* 2.  loop until full expanded key is obtained */
    pW = W + i - 1;
    for (; i < cx->Nb * (cx->Nr + 1); ++i) {
       tmp = *pW++;
       if (i % Nk == 0)
           tmp = SUBBYTE(ROTBYTE(tmp)) ^ Rcon[i / Nk - 1];
       else if (i % Nk == 4)
           tmp = SUBBYTE(tmp);
       *pW = W[i - Nk] ^ tmp;
    }
    return SECSuccess;
}

Here is the call graph for this function:

Here is the caller graph for this function: