/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <variant/variant.h>

#include <bl.h>

#include <plat/cmsis.h>
#include <plat/gpio.h>

#include <nanohub/sha2.h>
#include <nanohub/aes.h>
#include <nanohub/rsa.h>
#include <nanohub/nanohub.h>

#include <printf.h>
#include <string.h>

static uint32_t blVerifyOsImage(const uint8_t *addr, struct OsUpdateHdr **start, uint32_t *size);


//for comms protocol
#define BL_SYNC_IN                      0x5A
#define BL_ACK                          0x79
#define BL_NAK                          0x1F
#define BL_SYNC_OUT                     0xA5

#define BL_CMD_GET                      0x00
#define BL_CMD_READ_MEM                 0x11
#define BL_CMD_WRITE_MEM                0x31
#define BL_CMD_ERASE                    0x44
#define BL_CMD_GET_SIZES                0xEE /* our own command. reports: {u32 osSz, u32 sharedSz, u32 eeSz} all in big endian */
#define BL_CMD_UPDATE_FINISHED          0xEF /* our own command. attempts to verify the update -> ACK/NAK. MUST be called after upload to mark it as completed */

#define BL_ERROR                        0xDEADBEAF /* returned in place of command in case of exchange errors */


#define BL_SHARED_AREA_FAKE_ERASE_BLK   0xFFF0
#define BL_SHARED_AREA_FAKE_ADDR        0x50000000


//linker provides these
extern uint32_t __pubkeys_start[];
extern uint32_t __pubkeys_end[];
extern uint8_t __eedata_start[];
extern uint8_t __eedata_end[];
extern uint8_t __code_start[];
extern uint8_t __code_end[];
extern uint8_t __shared_start[];
extern uint8_t __shared_end[];

enum BlFlashType
{
    BL_FLASH_BL,
    BL_FLASH_EEDATA,
    BL_FLASH_KERNEL,
    BL_FLASH_SHARED
};

static const struct blFlashTable   // For erase code, we need to know which page a given memory address is in
{
    uint8_t *address;
    uint32_t length;
    uint32_t type;
} mBlFlashTable[] =
#ifndef BL_FLASH_TABLE
{
    { (uint8_t *)(&BL),                      0x04000, BL_FLASH_BL     },
    { (uint8_t *)(__eedata_start),           0x04000, BL_FLASH_EEDATA },
    { (uint8_t *)(__eedata_start + 0x04000), 0x04000, BL_FLASH_EEDATA },
    { (uint8_t *)(__code_start),             0x04000, BL_FLASH_KERNEL },
    { (uint8_t *)(__code_start + 0x04000),   0x10000, BL_FLASH_KERNEL },
    { (uint8_t *)(__shared_start),           0x20000, BL_FLASH_SHARED },
    { (uint8_t *)(__shared_start + 0x20000), 0x20000, BL_FLASH_SHARED },
    { (uint8_t *)(__shared_start + 0x40000), 0x20000, BL_FLASH_SHARED },
};
#else
BL_FLASH_TABLE;
#endif

static const char mOsUpdateMagic[] = OS_UPDT_MAGIC;

#ifdef DEBUG_UART_PIN

static bool blLogPutcharF(void *userData, char ch)
{
    if (ch == '\n')
        gpioBitbangedUartOut('\r');

    gpioBitbangedUartOut(ch);

    return true;
}

void blLog(const char *str, ...)
{
    va_list vl;

    va_start(vl, str);
    cvprintf(blLogPutcharF, NULL, str, vl);
    va_end(vl);
}

#else

#define blLog(...)

#endif

static uint32_t blExtApiGetVersion(void)
{
    return BL_VERSION_CUR;
}

static bool blProgramFlash(uint8_t *dst, const uint8_t *src, uint32_t length, uint32_t key1, uint32_t key2)
{
    const uint32_t sector_cnt = sizeof(mBlFlashTable) / sizeof(struct blFlashTable);
    uint32_t offset, i, j = 0;
    uint8_t *ptr;

    if (((length == 0)) ||
        ((0xFFFFFFFF - (uint32_t)dst) < (length - 1)) ||
        ((dst < mBlFlashTable[0].address)) ||
        ((dst + length) > (mBlFlashTable[sector_cnt-1].address +
                           mBlFlashTable[sector_cnt-1].length))) {
        return false;
    }

    // compute which flash block we are starting from
    for (i = 0; i < sector_cnt; i++) {
        if (dst >= mBlFlashTable[i].address &&
            dst < (mBlFlashTable[i].address + mBlFlashTable[i].length)) {
            break;
        }
    }

    // now loop through all the flash blocks and see if we have to do any
    // 0 -> 1 transitions of a bit. If so, return false
    // 1 -> 0 transitions of a bit do not require an erase
    offset = (uint32_t)(dst - mBlFlashTable[i].address);
    ptr = mBlFlashTable[i].address;
    while (j < length && i < sector_cnt) {
        if (offset == mBlFlashTable[i].length) {
            i++;
            offset = 0;
            ptr = mBlFlashTable[i].address;
        }

        if ((ptr[offset] & src[j]) != src[j]) {
            return false;
        } else {
            j++;
            offset++;
        }
    }

    if (!blPlatProgramFlash(dst, src, length, key1, key2))
        return false;

    return !memcmp(dst, src, length);
}

static void blExtApiGetSnum(uint32_t *snum, uint32_t length)
{
    blGetSnum(snum, length);
}

static bool blProgramTypedArea(uint8_t *dst, const uint8_t *src, uint32_t length, uint32_t type, uint32_t key1, uint32_t key2)
{
    const uint32_t sector_cnt = sizeof(mBlFlashTable) / sizeof(struct blFlashTable);
    uint32_t i;

    for (i = 0; i < sector_cnt; i++) {

        if ((dst >= mBlFlashTable[i].address &&
             dst < (mBlFlashTable[i].address + mBlFlashTable[i].length)) ||
            (dst < mBlFlashTable[i].address &&
             (dst + length > mBlFlashTable[i].address))) {
            if (mBlFlashTable[i].type != type)
                return false;
        }
    }

    return blProgramFlash(dst, src, length, key1, key2);
}

static bool blExtApiProgramSharedArea(uint8_t *dst, const uint8_t *src, uint32_t length, uint32_t key1, uint32_t key2)
{
    return blProgramTypedArea(dst, src, length, BL_FLASH_SHARED, key1, key2);
}

static bool blExtApiProgramEe(uint8_t *dst, const uint8_t *src, uint32_t length, uint32_t key1, uint32_t key2)
{
    return blProgramTypedArea(dst, src, length, BL_FLASH_EEDATA, key1, key2);
}

static bool blEraseTypedArea(uint32_t type, uint32_t key1, uint32_t key2)
{
    const uint32_t sector_cnt = sizeof(mBlFlashTable) / sizeof(struct blFlashTable);
    uint32_t i, erase_cnt = 0;
    uint8_t erase_mask[sector_cnt];

    for (i = 0; i < sector_cnt; i++) {
        if (mBlFlashTable[i].type == type) {
            erase_mask[i] = 1;
            erase_cnt++;
        } else {
            erase_mask[i] = 0;
        }
    }

    if (erase_cnt)
        blEraseSectors(sector_cnt, erase_mask, key1, key2);

    return true; //we assume erase worked
}

static bool blExtApiEraseSharedArea(uint32_t key1, uint32_t key2)
{
    return blEraseTypedArea(BL_FLASH_SHARED, key1, key2);
}

static uint32_t blVerifyOsUpdate(struct OsUpdateHdr **start, uint32_t *size)
{
    uint32_t ret;
    int i;

    for (i = 0; i < BL_SCAN_OFFSET; i += 4) {
        ret = blVerifyOsImage(__shared_start + i, start, size);
        if (ret != OS_UPDT_HDR_CHECK_FAILED)
            break;
    }

    return ret;
}

static uint32_t blExtApiVerifyOsUpdate(void)
{
    return blVerifyOsUpdate(NULL, NULL);
}

static void blExtApiReboot(void)
{
    blReboot();
}

static const uint32_t *blExtApiGetRsaKeyInfo(uint32_t *numKeys)
{
    uint32_t numWords = __pubkeys_end - __pubkeys_start;

    if (numWords % RSA_WORDS) // something is wrong
        return NULL;

    *numKeys = numWords / RSA_WORDS;
    return __pubkeys_start;
}

static const uint32_t* blExtApiSigPaddingVerify(const uint32_t *rsaResult)
{
    uint32_t i;

    //all but first and last word of padding MUST have no zero bytes
    for (i = SHA2_HASH_WORDS + 1; i < RSA_WORDS - 1; i++) {
        if (!(uint8_t)(rsaResult[i] >>  0))
            return NULL;
        if (!(uint8_t)(rsaResult[i] >>  8))
            return NULL;
        if (!(uint8_t)(rsaResult[i] >> 16))
            return NULL;
        if (!(uint8_t)(rsaResult[i] >> 24))
            return NULL;
    }

    //first padding word must have all nonzero bytes except low byte
    if ((rsaResult[SHA2_HASH_WORDS] & 0xff) || !(rsaResult[SHA2_HASH_WORDS] & 0xff00) || !(rsaResult[SHA2_HASH_WORDS] & 0xff0000) || !(rsaResult[SHA2_HASH_WORDS] & 0xff000000))
        return NULL;

    //last padding word must have 0x0002 in top 16 bits and nonzero random bytes in lower bytes
    if ((rsaResult[RSA_WORDS - 1] >> 16) != 2)
        return NULL;
    if (!(rsaResult[RSA_WORDS - 1] & 0xff00) || !(rsaResult[RSA_WORDS - 1] & 0xff))
        return NULL;

    return rsaResult;
}

static void blApplyVerifiedUpdate(const struct OsUpdateHdr *os) //only called if an update has been found to exist and be valid, signed, etc!
{
    //copy shared to code, and if successful, erase shared area
    if (blEraseTypedArea(BL_FLASH_KERNEL, BL_FLASH_KEY1, BL_FLASH_KEY2))
        if (blProgramTypedArea(__code_start, (const uint8_t*)(os + 1), os->size, BL_FLASH_KERNEL, BL_FLASH_KEY1, BL_FLASH_KEY2))
            (void)blExtApiEraseSharedArea(BL_FLASH_KEY1, BL_FLASH_KEY2);
}

static void blWriteMark(struct OsUpdateHdr *hdr, uint32_t mark)
{
    uint8_t dstVal = mark;

    (void)blExtApiProgramSharedArea(&hdr->marker, &dstVal, sizeof(hdr->marker), BL_FLASH_KEY1, BL_FLASH_KEY2);
}

static void blUpdateMark(uint32_t old, uint32_t new)
{
    struct OsUpdateHdr *hdr = (struct OsUpdateHdr *)__shared_start;

    if (hdr->marker != old)
        return;

    blWriteMark(hdr, new);
}

static uint32_t blVerifyOsImage(const uint8_t *addr, struct OsUpdateHdr **start, uint32_t *size)
{
    const uint32_t *rsaKey, *osSigHash, *osSigPubkey, *ourHash, *rsaResult, *expectedHash = NULL;
    struct OsUpdateHdr *hdr = (struct OsUpdateHdr*)addr;
    struct OsUpdateHdr cpy;
    uint32_t i, numRsaKeys = 0, rsaStateVar1, rsaStateVar2, rsaStep = 0;
    const uint8_t *updateBinaryData;
    bool isValid = false;
    struct Sha2state sha;
    struct RsaState rsa;
    uint32_t ret = OS_UPDT_HDR_CHECK_FAILED;
    const uint32_t overhead = sizeof(*hdr) + 2 * RSA_WORDS;

    // header does not fit or is not aligned
    if (addr < __shared_start || addr > (__shared_end - overhead) || ((uintptr_t)addr & 3))
        return OS_UPDT_HDR_CHECK_FAILED;

    // image does not fit
    if (hdr->size > (__shared_end - addr - overhead))
        return OS_UPDT_HDR_CHECK_FAILED;

    // OS magic does not match
    if (memcmp(hdr->magic, mOsUpdateMagic, sizeof(hdr->magic)) != 0)
        return OS_UPDT_HDR_CHECK_FAILED;

    // we don't allow shortcuts on success path, but we want to fail quickly
    if (hdr->marker == OS_UPDT_MARKER_INVALID)
        return OS_UPDT_HDR_MARKER_INVALID;

    // download did not finish
    if (hdr->marker == OS_UPDT_MARKER_INPROGRESS)
        return OS_UPDT_HDR_MARKER_INVALID;

    //get pointers
    updateBinaryData = (const uint8_t*)(hdr + 1);
    osSigHash = (const uint32_t*)(updateBinaryData + hdr->size);
    osSigPubkey = osSigHash + RSA_WORDS;

    //make sure the pub key is known
    for (i = 0, rsaKey = blExtApiGetRsaKeyInfo(&numRsaKeys); i < numRsaKeys; i++, rsaKey += RSA_WORDS) {
        if (memcmp(rsaKey, osSigPubkey, RSA_BYTES) == 0)
            break;
    }

    if (i == numRsaKeys) {
        ret = OS_UPDT_UNKNOWN_PUBKEY;
        //signed with an unknown key -> fail
        goto fail;
    }

    //decode sig using pubkey
    do {
        rsaResult = rsaPubOpIterative(&rsa, osSigHash, osSigPubkey, &rsaStateVar1, &rsaStateVar2, &rsaStep);
    } while (rsaStep);

    if (!rsaResult) {
        //decode fails -> invalid sig
        ret = OS_UPDT_INVALID_SIGNATURE;
        goto fail;
    }

    //verify padding
    expectedHash = blExtApiSigPaddingVerify(rsaResult);

    if (!expectedHash) {
        //padding check fails -> invalid sig
        ret = OS_UPDT_INVALID_SIGNATURE_HASH;
        goto fail;
    }

    //hash the update
    sha2init(&sha);

    memcpy(&cpy, hdr, sizeof(cpy));
    cpy.marker = OS_UPDT_MARKER_INPROGRESS;
    sha2processBytes(&sha, &cpy, sizeof(cpy));
    sha2processBytes(&sha, (uint8_t*)(hdr + 1), hdr->size);
    ourHash = sha2finish(&sha);

    //verify hash match
    if (memcmp(expectedHash, ourHash, SHA2_HASH_SIZE) != 0) {
        //hash does not match -> data tampered with
        ret = OS_UPDT_INVALID_SIGNATURE_HASH; // same error; do not disclose nature of hash problem
        goto fail;
    }

    //it is valid
    isValid = true;
    ret = OS_UPDT_SUCCESS;
    if (start)
        *start = hdr;
    if (size)
        *size = hdr->size;

fail:
    //mark it appropriately
    blWriteMark(hdr, isValid ? OS_UPDT_MARKER_VERIFIED : OS_UPDT_MARKER_INVALID);
    return ret;
}

static inline bool blUpdateVerify()
{
    return blVerifyOsImage(__shared_start, NULL, NULL) == OS_UPDT_SUCCESS;
}

static uint8_t blLoaderRxByte()
{
    return blSpiTxRxByte(0);
}

static void blLoaderTxByte(uint32_t val)
{
    blSpiTxRxByte(val);
}

static void blLoaderTxBytes(const void *data, uint32_t len)
{
    const uint8_t *buf = (const uint8_t*)data;

    blLoaderTxByte(len - 1);
    while (len--)
        blLoaderTxByte(*buf++);
}

static bool blLoaderSendSyncOut()
{
    return blSpiTxRxByte(BL_SYNC_OUT) == BL_SYNC_IN;
}

static bool blLoaderSendAck(bool ack)
{
    blLoaderRxByte();
    blLoaderTxByte(ack ? BL_ACK : BL_NAK);
    return blLoaderRxByte() == BL_ACK;
}

static uint32_t blLoaderRxCmd()
{
    uint8_t cmd = blLoaderRxByte();
    uint8_t cmdNot = blSpiTxRxByte(BL_ACK);
    return (cmd ^ cmdNot) == 0xFF ? cmd : BL_ERROR;
}

static void blLoader(bool force)
{
    bool seenErase = false;
    uint32_t nextAddr = 0;
    uint32_t expectedSize = 0;

    blSetup();

    //if int pin is not low, do not bother any further
    if (blHostActive() || force) {

        blConfigIo();

        //if we saw a sync, do the bootloader thing
        if (blSyncWait(BL_SYNC_IN)) {
            static const uint8_t supportedCmds[] = {BL_CMD_GET, BL_CMD_READ_MEM, BL_CMD_WRITE_MEM, BL_CMD_ERASE, BL_CMD_GET_SIZES, BL_CMD_UPDATE_FINISHED};
            uint32_t allSizes[] = {__builtin_bswap32(__code_end - __code_start), __builtin_bswap32(__shared_end - __shared_start), __builtin_bswap32(__eedata_end - __eedata_start)};
            bool ack = true;  //we ack the sync

            ack = blLoaderSendSyncOut();

            //loop forever listening to commands
            while (1) {
                uint32_t sync, cmd, addr = 0, len, checksum = 0, i;
                uint8_t data[256];

                //send ack or NAK for last thing
                if (!blLoaderSendAck(ack))
                    goto out;

                while ((sync = blLoaderRxByte()) != BL_SYNC_IN);
                cmd = blLoaderRxCmd();

                ack = false;
                if (sync == BL_SYNC_IN && cmd != BL_ERROR)
                switch (cmd) {
                case BL_CMD_GET:

                    //ACK the command
                    (void)blLoaderSendAck(true);

                    blLoaderTxBytes(supportedCmds, sizeof(supportedCmds));
                    ack = true;
                    break;

                case BL_CMD_READ_MEM:
                    if (!seenErase)  //no reading till we erase the shared area (this way we do not leak encrypted apps' plaintexts)
                        break;

                    //ACK the command
                    (void)blLoaderSendAck(true);

                    //get address
                    for (i = 0; i < 4; i++) {
                        uint32_t byte = blLoaderRxByte();
                        checksum ^= byte;
                        addr = (addr << 8) + byte;
                    }

                    //reject addresses outside of our fake area or on invalid checksum
                    if (blLoaderRxByte() != checksum || addr < BL_SHARED_AREA_FAKE_ADDR || addr - BL_SHARED_AREA_FAKE_ADDR > __shared_end - __shared_start)
                       break;

                    //ack the address
                    (void)blLoaderSendAck(true);

                    //get the length
                    len = blLoaderRxByte();

                    //reject invalid checksum
                    if (blLoaderRxByte() != (uint8_t)~len || addr + len - BL_SHARED_AREA_FAKE_ADDR > __shared_end - __shared_start)
                       break;

                    len++;

                    //reject reads past the end of the shared area
                    if (addr + len - BL_SHARED_AREA_FAKE_ADDR > __shared_end - __shared_start)
                       break;

                    //ack the length
                    (void)blLoaderSendAck(true);

                    //read the data & send it
                    blLoaderTxBytes(__shared_start + addr - BL_SHARED_AREA_FAKE_ADDR, len);
                    ack = true;
                    break;

                case BL_CMD_WRITE_MEM:
                    if (!seenErase)  //no writing till we erase the shared area (this way we do not purposefully modify encrypted apps' plaintexts in a nefarious fashion)
                        break;

                    //ACK the command
                    (void)blLoaderSendAck(true);

                    //get address
                    for (i = 0; i < 4; i++) {
                        uint32_t byte = blLoaderRxByte();
                        checksum ^= byte;
                        addr = (addr << 8) + byte;
                    }

                    //reject addresses outside of our fake area or on invalid checksum
                    if (blLoaderRxByte() != checksum ||
                        addr < BL_SHARED_AREA_FAKE_ADDR ||
                        addr - BL_SHARED_AREA_FAKE_ADDR > __shared_end - __shared_start)
                        break;

                    addr -= BL_SHARED_AREA_FAKE_ADDR;
                    if (addr != nextAddr)
                        break;

                    //ack the address
                    (void)blLoaderSendAck(true);

                    //get the length
                    checksum = len = blLoaderRxByte();
                    len++;

                    //get bytes
                    for (i = 0; i < len; i++) {
                        uint32_t byte = blLoaderRxByte();
                        checksum ^= byte;
                        data[i] = byte;
                    }

                    //reject writes that takes out outside fo shared area or invalid checksums
                    if (blLoaderRxByte() != checksum || addr + len > __shared_end - __shared_start)
                       break;

                    // OBSOLETE: superseded by sequential contiguous write requirement
                    //if (addr && addr < sizeof(struct OsUpdateHdr))
                    //    break;

                    //a write starting at zero must be big enough to contain a full OS update header
                    if (!addr) {
                        const struct OsUpdateHdr *hdr = (const struct OsUpdateHdr*)data;

                        //verify it is at least as big as the header
                        if (len < sizeof(struct OsUpdateHdr))
                            break;

                        //check for magic
                        for (i = 0; i < sizeof(hdr->magic) && hdr->magic[i] == mOsUpdateMagic[i]; i++);

                        //verify magic check passed & marker is properly set to inprogress
                        if (i != sizeof(hdr->magic) || hdr->marker != OS_UPDT_MARKER_INPROGRESS)
                            break;
                        expectedSize = sizeof(*hdr) + hdr->size + 2 * RSA_BYTES;
                    }
                    if (addr + len > expectedSize)
                        break;

                    //do it
                    ack = blExtApiProgramSharedArea(__shared_start + addr, data, len, BL_FLASH_KEY1, BL_FLASH_KEY2);
                    blResetRxData();
                    nextAddr += len;
                    break;

                case BL_CMD_ERASE:

                    //ACK the command
                    (void)blLoaderSendAck(true);

                    //get address
                    for (i = 0; i < 2; i++) {
                        uint32_t byte = blLoaderRxByte();
                        checksum ^= byte;
                        addr = (addr << 8) + byte;
                    }

                    //reject addresses that are not our magic address or on invalid checksum
                    if (blLoaderRxByte() != checksum || addr != BL_SHARED_AREA_FAKE_ERASE_BLK)
                        break;

                    //do it
                    ack = blExtApiEraseSharedArea(BL_FLASH_KEY1, BL_FLASH_KEY2);
                    if (ack) {
                        seenErase = true;
                        nextAddr = 0;
                        expectedSize = 0;
                    }
                    blResetRxData();
                    break;

                case BL_CMD_GET_SIZES:

                    //ACK the command
                    (void)blLoaderSendAck(true);

                    blLoaderTxBytes(allSizes, sizeof(allSizes));
                    break;

                case BL_CMD_UPDATE_FINISHED:
                    blUpdateMark(OS_UPDT_MARKER_INPROGRESS, OS_UPDT_MARKER_DOWNLOADED);
                    ack = blUpdateVerify();
                    break;
                }
            }
        }
    }

out:
    blCleanup();
}

void blMain(uint32_t appBase)
{
    bool forceLoad = false;

    blLog("NanohubOS bootloader up @ %p\n", &blMain);

    //enter SPI loader if requested
    do {
        uint32_t res;
        struct OsUpdateHdr *os;

        blLoader(forceLoad);
        res = blVerifyOsUpdate(&os, NULL);
        if (res == OS_UPDT_SUCCESS)
            blApplyVerifiedUpdate(os);
        else if (res != OS_UPDT_HDR_CHECK_FAILED)
            blExtApiEraseSharedArea(BL_FLASH_KEY1, BL_FLASH_KEY2);

        forceLoad = true;
    } while (*(volatile uint32_t*)appBase == 0xFFFFFFFF);
}

const struct BlApiTable __attribute__((section(".blapi"))) __BL_API =
{
    .blGetVersion = &blExtApiGetVersion,
    .blReboot = &blExtApiReboot,
    .blGetSnum = &blExtApiGetSnum,
    .blProgramShared = &blExtApiProgramSharedArea,
    .blEraseShared = &blExtApiEraseSharedArea,
    .blProgramEe = &blExtApiProgramEe,
    .blGetPubKeysInfo = &blExtApiGetRsaKeyInfo,
    .blRsaPubOpIterative = &rsaPubOpIterative,
    .blSha2init = &sha2init,
    .blSha2processBytes = &sha2processBytes,
    .blSha2finish = &sha2finish,
    .blAesInitForEncr = &aesInitForEncr,
    .blAesInitForDecr = &aesInitForDecr,
    .blAesEncr = &aesEncr,
    .blAesDecr = &aesDecr,
    .blAesCbcInitForEncr = &aesCbcInitForEncr,
    .blAesCbcInitForDecr = &aesCbcInitForDecr,
    .blAesCbcEncr = &aesCbcEncr,
    .blAesCbcDecr = &aesCbcDecr,
    .blSigPaddingVerify = &blExtApiSigPaddingVerify,
    .blVerifyOsUpdate = &blExtApiVerifyOsUpdate,
};
