/**********
 * Copyright (c) 2003-2004 Greg Parker.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 **********/

#include "cryptlib.h"
#include "cryptorsrc.h"
#include "aes.h"
#include "aes_armstubs.h"
#include "assert.h"
#include "aes_tables.h"

static MemHandle Te0_h = NULL;
static MemHandle Te1_h = NULL;
static MemHandle Te2_h = NULL;
static MemHandle Te3_h = NULL;
static MemHandle Te4_h = NULL;
static MemHandle Td0_h = NULL;
static MemHandle Td1_h = NULL;
static MemHandle Td2_h = NULL;
static MemHandle Td3_h = NULL;
static MemHandle Td4_h = NULL;


void aes_init_tables(void)
{
    // fixme error handling
    Te0_h = DmGetResource('adwd', AES_Te0_id);
    Te1_h = DmGetResource('adwd', AES_Te1_id);
    Te2_h = DmGetResource('adwd', AES_Te2_id);
    Te3_h = DmGetResource('adwd', AES_Te3_id);
    Te4_h = DmGetResource('adwd', AES_Te4_id);
    Td0_h = DmGetResource('adwd', AES_Td0_id);
    Td1_h = DmGetResource('adwd', AES_Td1_id);
    Td2_h = DmGetResource('adwd', AES_Td2_id);
    Td3_h = DmGetResource('adwd', AES_Td3_id);
    Td4_h = DmGetResource('adwd', AES_Td4_id);

    // adwd resource is prefixed with 4-byte word count
    // AES tables should be 256 words long, plus the count word

    // verify handle sizes
    assert(MemHandleSize(Te0_h) == 4*(1+256));
    assert(MemHandleSize(Te1_h) == 4*(1+256));
    assert(MemHandleSize(Te2_h) == 4*(1+256));
    assert(MemHandleSize(Te3_h) == 4*(1+256));
    assert(MemHandleSize(Te4_h) == 4*(1+256));
    assert(MemHandleSize(Td0_h) == 4*(1+256));
    assert(MemHandleSize(Td1_h) == 4*(1+256));
    assert(MemHandleSize(Td2_h) == 4*(1+256));
    assert(MemHandleSize(Td3_h) == 4*(1+256));
    assert(MemHandleSize(Td4_h) == 4*(1+256));
}


void aes_lock_tables(aes_globals *g)
{
    g->Te0 = MemHandleLock(Te0_h);
    g->Te1 = MemHandleLock(Te1_h);
    g->Te2 = MemHandleLock(Te2_h);
    g->Te3 = MemHandleLock(Te3_h);
    g->Te4 = MemHandleLock(Te4_h);
    g->Td0 = MemHandleLock(Td0_h);
    g->Td1 = MemHandleLock(Td1_h);
    g->Td2 = MemHandleLock(Td2_h);
    g->Td3 = MemHandleLock(Td3_h);
    g->Td4 = MemHandleLock(Td4_h);

    // skip word count
    g->Te0 += 1;
    g->Te1 += 1;
    g->Te2 += 1;
    g->Te3 += 1;
    g->Te4 += 1;
    g->Td0 += 1;
    g->Td1 += 1;
    g->Td2 += 1;
    g->Td3 += 1;
    g->Td4 += 1;
}


void aes_unlock_tables(aes_globals *g)
{
    MemHandleUnlock(Te0_h); g->Te0 = NULL;
    MemHandleUnlock(Te1_h); g->Te1 = NULL;
    MemHandleUnlock(Te2_h); g->Te2 = NULL;
    MemHandleUnlock(Te3_h); g->Te3 = NULL;
    MemHandleUnlock(Te4_h); g->Te4 = NULL;
    MemHandleUnlock(Td0_h); g->Td0 = NULL;
    MemHandleUnlock(Td1_h); g->Td1 = NULL;
    MemHandleUnlock(Td2_h); g->Td2 = NULL;
    MemHandleUnlock(Td3_h); g->Td3 = NULL;
    MemHandleUnlock(Td4_h); g->Td4 = NULL;
}
