Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <inttypes.h>
     18 #include <stdint.h>
     19 #include <stdio.h>
     20 #include <string.h>
     21 
     22 #include <nanohub/aes.h>
     23 #include <nanohub/rsa.h>
     24 #include <nanohub/sha2.h>
     25 
     26 #include <appSec.h>
     27 #include <bl.h>
     28 #include <heap.h>
     29 #include <seos.h>
     30 
     31 #define APP_HDR_SIZE                (sizeof(struct ImageHeader))
     32 #define APP_HDR_MAX_SIZE            (sizeof(struct ImageHeader) + sizeof(struct AppSecSignHdr) + sizeof(struct AppSecEncrHdr))
     33 #define APP_DATA_CHUNK_SIZE         (AES_BLOCK_WORDS * sizeof(uint32_t))  //data blocks are this size
     34 #define APP_SIG_SIZE                RSA_BYTES
     35 
     36 // verify block is SHA placed in integral number of encryption blocks (for SHA256 and AES256 happens to be exactly 2 AES blocks)
     37 #define APP_VERIFY_BLOCK_SIZE       ((SHA2_HASH_SIZE + AES_BLOCK_SIZE - 1) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE
     38 
     39 #define APP_SEC_SIG_ALIGN           APP_DATA_CHUNK_SIZE
     40 #define APP_SEC_ENCR_ALIGN          APP_DATA_CHUNK_SIZE
     41 
     42 #define STATE_INIT                  0 // nothing gotten yet
     43 #define STATE_RXING_HEADERS         1 // variable size headers (min APP_HDR_SIZE, max APP_HDR_MAX_SIZE)
     44 #define STATE_RXING_DATA            2 // each data block is AES_BLOCK_WORDS 32-bit words (for AES reasons)
     45 #define STATE_RXING_SIG_HASH        3 // each is RSA_BYTES bytes
     46 #define STATE_RXING_SIG_PUBKEY      4 // each is RSA_BYTES bytes
     47 #define STATE_VERIFY                5 // decryption of ciphertext done; now decrypting and verifying the encrypted plaintext SHA2
     48 #define STATE_DONE                  6 // all is finished and well
     49 #define STATE_BAD                   7 // unrecoverable badness has happened. this will *NOT* fix itself. It is now ok to give up, start over, cry, or pray to your favourite deity for help
     50 #define STATE_MAX                   8 // total number of states
     51 
     52 //#define DEBUG_FSM
     53 
     54 struct AppSecState {
     55     union { //we save some memory by reusing this space.
     56         struct {
     57             struct AesCbcContext cbc;
     58             struct Sha2state sha;
     59             struct Sha2state cbcSha;
     60         };
     61         struct {
     62             struct RsaState rsa;
     63             uint32_t rsaState1, rsaState2, rsaStep;
     64         };
     65     };
     66     uint32_t rsaTmp[RSA_WORDS];
     67     uint32_t lastHash[SHA2_HASH_WORDS];
     68 
     69     AppSecWriteCbk writeCbk;
     70     AppSecPubKeyFindCbk pubKeyFindCbk;
     71     AppSecGetAesKeyCbk aesKeyAccessCbk;
     72 
     73     union {
     74         union { //make the compiler work to make sure we have enough space
     75             uint8_t placeholderAppHdr[APP_HDR_MAX_SIZE];
     76             uint8_t placeholderDataChunk[APP_DATA_CHUNK_SIZE];
     77             uint8_t placeholderSigChunk[APP_SIG_SIZE];
     78             uint8_t placeholderAesKey[AES_KEY_WORDS * sizeof(uint32_t)];
     79         };
     80         uint8_t dataBytes[0]; //we actually use these two for access
     81         uint32_t dataWords[0];
     82     };
     83 
     84     uint32_t signedBytesIn;
     85     uint32_t encryptedBytesIn;
     86     uint32_t signedBytesOut;
     87     uint32_t encryptedBytesOut;
     88 
     89     uint16_t haveBytes;       //in dataBytes...
     90     uint16_t chunkSize;
     91     uint8_t curState;
     92     uint8_t needSig    :1;
     93     uint8_t haveSig    :1;
     94     uint8_t haveEncr   :1;
     95     uint8_t haveTrustedKey :1;
     96     uint8_t doingRsa   :1;
     97 };
     98 
     99 static void limitChunkSize(struct AppSecState *state)
    100 {
    101     if (state->haveSig && state->chunkSize > state->signedBytesIn)
    102         state->chunkSize = state->signedBytesIn;
    103     if (state->haveEncr && state->chunkSize > state->encryptedBytesIn)
    104         state->chunkSize = state->signedBytesIn;
    105 }
    106 
    107 static void appSecSetCurState(struct AppSecState *state, uint32_t curState)
    108 {
    109     const static uint16_t chunkSize[STATE_MAX] = {
    110         [STATE_RXING_HEADERS] = APP_HDR_SIZE,
    111         [STATE_RXING_DATA] = APP_DATA_CHUNK_SIZE,
    112         [STATE_VERIFY] = APP_VERIFY_BLOCK_SIZE,
    113         [STATE_RXING_SIG_HASH] = APP_SIG_SIZE,
    114         [STATE_RXING_SIG_PUBKEY] = APP_SIG_SIZE,
    115     };
    116     if (curState >= STATE_MAX)
    117         curState = STATE_BAD;
    118     if (curState != state->curState || curState == STATE_INIT) {
    119 #ifdef DEBUG_FSM
    120         osLog(LOG_INFO, "%s: oldState=%" PRIu8
    121                         "; new state=%" PRIu32
    122                         "; old chunk size=%" PRIu16
    123                         "; new chunk size=%" PRIu16
    124                         "; have bytes=%" PRIu16
    125                         "\n",
    126               __func__, state->curState, curState,
    127               state->chunkSize, chunkSize[curState],
    128               state->haveBytes);
    129 #endif
    130         state->curState = curState;
    131         state->chunkSize = chunkSize[curState];
    132     }
    133 }
    134 
    135 static inline uint32_t appSecGetCurState(const struct AppSecState *state)
    136 {
    137     return state->curState;
    138 }
    139 
    140 //init/deinit
    141 struct AppSecState *appSecInit(AppSecWriteCbk writeCbk, AppSecPubKeyFindCbk pubKeyFindCbk, AppSecGetAesKeyCbk aesKeyAccessCbk, bool mandateSigning)
    142 {
    143     struct AppSecState *state = heapAlloc(sizeof(struct AppSecState));
    144 
    145     if (!state)
    146         return NULL;
    147 
    148     memset(state, 0, sizeof(struct AppSecState));
    149 
    150     state->writeCbk = writeCbk;
    151     state->pubKeyFindCbk = pubKeyFindCbk;
    152     state->aesKeyAccessCbk = aesKeyAccessCbk;
    153     appSecSetCurState(state, STATE_INIT);
    154     if (mandateSigning)
    155         state->needSig = 1;
    156 
    157     return state;
    158 }
    159 
    160 void appSecDeinit(struct AppSecState *state)
    161 {
    162     heapFree(state);
    163 }
    164 
    165 //if needed, decrypt and hash incoming data
    166 static AppSecErr appSecBlockRx(struct AppSecState *state)
    167 {
    168     //if signatures are on, hash it
    169     if (state->haveSig) {
    170 
    171         //make sure we do not get too much data & account for the data we got
    172         if (state->haveBytes > state->signedBytesIn)
    173             return APP_SEC_TOO_MUCH_DATA;
    174         state->signedBytesIn -= state->haveBytes;
    175 
    176         //make sure we do not produce too much data (discard padding) & make sure we account for it
    177         if (state->signedBytesOut < state->haveBytes)
    178             state->haveBytes = state->signedBytesOut;
    179         state->signedBytesOut -= state->haveBytes;
    180 
    181         //hash the data
    182         BL.blSha2processBytes(&state->sha, state->dataBytes, state->haveBytes);
    183     }
    184 
    185     // decrypt if encryption is on
    186     if (state->haveEncr) {
    187 
    188         uint32_t *dataP = state->dataWords;
    189         uint32_t i, numBlocks = state->haveBytes / APP_DATA_CHUNK_SIZE;
    190 
    191         //we should not be called with partial encr blocks
    192         if (state->haveBytes % APP_DATA_CHUNK_SIZE)
    193             return APP_SEC_TOO_LITTLE_DATA;
    194 
    195         // make sure we do not get too much data & account for the data we got
    196         if (state->haveBytes > state->encryptedBytesIn)
    197             return APP_SEC_TOO_MUCH_DATA;
    198         state->encryptedBytesIn -= state->haveBytes;
    199 
    200         // decrypt
    201         for (i = 0; i < numBlocks; i++, dataP += AES_BLOCK_WORDS)
    202             BL.blAesCbcDecr(&state->cbc, dataP, dataP);
    203 
    204         // make sure we do not produce too much data (discard padding) & make sure we account for it
    205         if (state->encryptedBytesOut < state->haveBytes)
    206             state->haveBytes = state->encryptedBytesOut;
    207         state->encryptedBytesOut -= state->haveBytes;
    208 
    209         if (state->haveBytes)
    210             BL.blSha2processBytes(&state->cbcSha, state->dataBytes, state->haveBytes);
    211     }
    212 
    213     limitChunkSize(state);
    214 
    215     return APP_SEC_NO_ERROR;
    216 }
    217 
    218 static AppSecErr appSecProcessIncomingHdr(struct AppSecState *state, uint32_t *needBytesOut)
    219 {
    220     struct ImageHeader *image;
    221     struct nano_app_binary_t *aosp;
    222     uint32_t flags;
    223     uint32_t needBytes;
    224     struct AppSecSignHdr *signHdr = NULL;
    225     struct AppSecEncrHdr *encrHdr = NULL;
    226     uint8_t *hdr = state->dataBytes;
    227     AppSecErr ret;
    228 
    229     image = (struct ImageHeader *)hdr; hdr += sizeof(*image);
    230     aosp = &image->aosp;
    231     flags = aosp->flags;
    232     if (aosp->header_version != 1 ||
    233         aosp->magic != NANOAPP_AOSP_MAGIC ||
    234         image->layout.version != 1 ||
    235         image->layout.magic != GOOGLE_LAYOUT_MAGIC)
    236         return APP_SEC_HEADER_ERROR;
    237 
    238     needBytes = sizeof(*image);
    239     if ((flags & NANOAPP_SIGNED_FLAG) != 0)
    240         needBytes += sizeof(*signHdr);
    241     if ((flags & NANOAPP_ENCRYPTED_FLAG) != 0)
    242         needBytes += sizeof(*encrHdr);
    243 
    244     *needBytesOut = needBytes;
    245 
    246     if (needBytes > state->haveBytes)
    247         return APP_SEC_NO_ERROR;
    248 
    249     *needBytesOut = 0;
    250 
    251     if ((flags & NANOAPP_SIGNED_FLAG) != 0) {
    252         signHdr = (struct AppSecSignHdr *)hdr; hdr += sizeof(*signHdr);
    253         osLog(LOG_INFO, "%s: signed size=%" PRIu32 "\n",
    254                         __func__, signHdr->appDataLen);
    255         if (!signHdr->appDataLen) {
    256             //no data bytes
    257             return APP_SEC_INVALID_DATA;
    258         }
    259         state->signedBytesIn = state->signedBytesOut = signHdr->appDataLen;
    260         state->haveSig = 1;
    261         BL.blSha2init(&state->sha);
    262         BL.blSha2processBytes(&state->sha, state->dataBytes, needBytes);
    263     }
    264 
    265     if ((flags & NANOAPP_ENCRYPTED_FLAG) != 0) {
    266         uint32_t k[AES_KEY_WORDS];
    267 
    268         encrHdr = (struct AppSecEncrHdr *)hdr; hdr += sizeof(*encrHdr);
    269         osLog(LOG_INFO, "%s: encrypted data size=%" PRIu32
    270                         "; key ID=%016" PRIX64 "\n",
    271                         __func__, encrHdr->dataLen, encrHdr->keyID);
    272 
    273         if (!encrHdr->dataLen || !encrHdr->keyID)
    274             return APP_SEC_INVALID_DATA;
    275         ret = state->aesKeyAccessCbk(encrHdr->keyID, k);
    276         if (ret != APP_SEC_NO_ERROR) {
    277             osLog(LOG_ERROR, "%s: Secret key not found\n", __func__);
    278             return ret;
    279         }
    280 
    281         BL.blAesCbcInitForDecr(&state->cbc, k, encrHdr->IV);
    282         BL.blSha2init(&state->cbcSha);
    283         state->encryptedBytesOut = encrHdr->dataLen;
    284         state->encryptedBytesIn = ((state->encryptedBytesOut + APP_SEC_ENCR_ALIGN - 1) / APP_SEC_ENCR_ALIGN) * APP_SEC_ENCR_ALIGN;
    285         state->haveEncr = 1;
    286         osLog(LOG_INFO, "%s: encrypted aligned data size=%" PRIu32 "\n",
    287                         __func__, state->encryptedBytesIn);
    288 
    289         if (state->haveSig) {
    290             state->signedBytesIn = state->signedBytesOut = signHdr->appDataLen - sizeof(*encrHdr);
    291             // at this point, signedBytesOut must equal encryptedBytesIn
    292             if (state->signedBytesOut != (state->encryptedBytesIn + SHA2_HASH_SIZE)) {
    293                 osLog(LOG_ERROR, "%s: sig data size does not match encrypted data\n", __func__);
    294                 return APP_SEC_INVALID_DATA;
    295             }
    296         }
    297     }
    298 
    299     //if we are in must-sign mode and no signature was provided, fail
    300     if (!state->haveSig && state->needSig) {
    301         osLog(LOG_ERROR, "%s: only signed images can be uploaded\n", __func__);
    302         return APP_SEC_SIG_VERIFY_FAIL;
    303     }
    304 
    305     // now, transform AOSP header to FW common header
    306     struct FwCommonHdr common = {
    307         .magic   = APP_HDR_MAGIC,
    308         .appId   = aosp->app_id,
    309         .fwVer   = APP_HDR_VER_CUR,
    310         .fwFlags = image->layout.flags,
    311         .appVer  = aosp->app_version,
    312         .payInfoType = image->layout.payload,
    313         .chreApiMajor = 0xFF,
    314         .chreApiMinor = 0xFF,
    315     };
    316 
    317     if (image->layout.flags & FL_APP_HDR_CHRE) {
    318         if (aosp->chre_api_major || aosp->chre_api_minor) {
    319             common.chreApiMajor = aosp->chre_api_major;
    320             common.chreApiMinor = aosp->chre_api_minor;
    321         } else {
    322             // fields not defined prior to CHRE 1.1
    323             common.chreApiMajor = 0x01;
    324             common.chreApiMinor = 0x00;
    325         }
    326     }
    327 
    328     // check to see if this is special system types of payload
    329     switch(image->layout.payload) {
    330     case LAYOUT_APP:
    331         common.fwFlags = (common.fwFlags | FL_APP_HDR_APPLICATION) & ~FL_APP_HDR_INTERNAL;
    332         common.payInfoSize = sizeof(struct AppInfo);
    333         osLog(LOG_INFO, "App container found\n");
    334         break;
    335     case LAYOUT_KEY:
    336         common.fwFlags |= FL_APP_HDR_SECURE;
    337         common.payInfoSize = sizeof(struct KeyInfo);
    338         osLog(LOG_INFO, "Key container found\n");
    339         break;
    340     case LAYOUT_OS:
    341         common.payInfoSize = sizeof(struct OsUpdateHdr);
    342         osLog(LOG_INFO, "OS update container found\n");
    343         break;
    344     default:
    345         break;
    346     }
    347 
    348     memcpy(state->dataBytes, &common, sizeof(common));
    349     state->haveBytes = sizeof(common);
    350 
    351     //we're now in data-accepting state
    352     appSecSetCurState(state, STATE_RXING_DATA);
    353 
    354     return APP_SEC_NO_ERROR;
    355 }
    356 
    357 static AppSecErr appSecProcessIncomingData(struct AppSecState *state)
    358 {
    359     //check for data-ending conditions
    360     if (state->haveSig && !state->signedBytesIn) {
    361         // we're all done with the signed portion of the data, now come the signatures
    362         appSecSetCurState(state, STATE_RXING_SIG_HASH);
    363 
    364         //collect the hash
    365         memcpy(state->lastHash, BL.blSha2finish(&state->sha), SHA2_HASH_SIZE);
    366     } else if (state->haveEncr && !state->encryptedBytesIn) {
    367         if (appSecGetCurState(state) == STATE_RXING_DATA) {
    368             //we're all done with encrypted plaintext
    369             state->encryptedBytesIn = sizeof(state->cbcSha);
    370             appSecSetCurState(state, STATE_VERIFY);
    371         }
    372     }
    373 
    374     //pass to caller
    375     return state->haveBytes ? state->writeCbk(state->dataBytes, state->haveBytes) : APP_SEC_NO_ERROR;
    376 }
    377 
    378 AppSecErr appSecDoSomeProcessing(struct AppSecState *state)
    379 {
    380     const uint32_t *result;
    381 
    382     if (!state->doingRsa) {
    383         //shouldn't be calling us then...
    384         return APP_SEC_BAD;
    385     }
    386 
    387     result = BL.blRsaPubOpIterative(&state->rsa, state->rsaTmp, state->dataWords, &state->rsaState1, &state->rsaState2, &state->rsaStep);
    388     if (state->rsaStep)
    389         return APP_SEC_NEED_MORE_TIME;
    390 
    391     //we just finished the RSA-ing
    392     state->doingRsa = 0;
    393 
    394     //verify signature padding (and thus likely: correct decryption)
    395     result = BL.blSigPaddingVerify(result);
    396     if (!result)
    397         return APP_SEC_SIG_DECODE_FAIL;
    398 
    399     //check if hashes match
    400     if (memcmp(state->lastHash, result, SHA2_HASH_SIZE))
    401         return APP_SEC_SIG_VERIFY_FAIL;
    402 
    403     //hash the provided pubkey
    404     BL.blSha2init(&state->sha);
    405     BL.blSha2processBytes(&state->sha, state->dataBytes, APP_SIG_SIZE);
    406     memcpy(state->lastHash, BL.blSha2finish(&state->sha), SHA2_HASH_SIZE);
    407     appSecSetCurState(state, STATE_RXING_SIG_HASH);
    408 
    409     return APP_SEC_NO_ERROR;
    410 }
    411 
    412 static AppSecErr appSecProcessIncomingSigData(struct AppSecState *state)
    413 {
    414     bool keyFound = false;
    415 
    416     //if we're RXing the hash, just stash it away and move on
    417     if (appSecGetCurState(state) == STATE_RXING_SIG_HASH) {
    418         state->haveTrustedKey = 0;
    419         memcpy(state->rsaTmp, state->dataWords, APP_SIG_SIZE);
    420         appSecSetCurState(state, STATE_RXING_SIG_PUBKEY);
    421         return APP_SEC_NO_ERROR;
    422     }
    423 
    424     // verify it is a known root
    425     state->pubKeyFindCbk(state->dataWords, &keyFound);
    426     state->haveTrustedKey = keyFound;
    427 
    428     //we now have the pubKey. decrypt over time
    429     state->doingRsa = 1;
    430     state->rsaStep = 0;
    431     return APP_SEC_NEED_MORE_TIME;
    432 }
    433 
    434 static AppSecErr appSecVerifyEncryptedData(struct AppSecState *state)
    435 {
    436     const uint32_t *hash = BL.blSha2finish(&state->cbcSha);
    437     bool verified = memcmp(hash, state->dataBytes, SHA2_BLOCK_SIZE) == 0;
    438 
    439     osLog(LOG_INFO, "%s: decryption verification: %s\n", __func__, verified ? "passed" : "failed");
    440 
    441 // TODO: fix verify logic
    442 //    return verified ? APP_SEC_NO_ERROR : APP_SEC_VERIFY_FAILED;
    443     return APP_SEC_NO_ERROR;
    444 }
    445 
    446 AppSecErr appSecRxData(struct AppSecState *state, const void *dataP, uint32_t len, uint32_t *lenUnusedP)
    447 {
    448     const uint8_t *data = (const uint8_t*)dataP;
    449     AppSecErr ret = APP_SEC_NO_ERROR;
    450     uint32_t needBytes;
    451 
    452     if (appSecGetCurState(state) == STATE_INIT)
    453         appSecSetCurState(state, STATE_RXING_HEADERS);
    454 
    455     while (len) {
    456         len--;
    457         state->dataBytes[state->haveBytes++] = *data++;
    458         if (state->haveBytes < state->chunkSize)
    459             continue;
    460         switch (appSecGetCurState(state)) {
    461         case STATE_RXING_HEADERS:
    462             // AOSP header is never encrypted; if it is signed, it will hash itself
    463             needBytes = 0;
    464             ret = appSecProcessIncomingHdr(state, &needBytes);
    465             if (ret != APP_SEC_NO_ERROR)
    466                 goto out;
    467             if (needBytes > state->chunkSize) {
    468                 state->chunkSize = needBytes;
    469                 // get more data and try again
    470                 continue;
    471             }
    472             // done with parsing header(s); we might have something to write to flash
    473             if (state->haveBytes) {
    474                 osLog(LOG_INFO, "%s: save converted header [%" PRIu16 " bytes] to flash\n", __func__, state->haveBytes);
    475                 ret = appSecProcessIncomingData(state);
    476                 state->haveBytes = 0;
    477             }
    478             limitChunkSize(state);
    479             goto out;
    480 
    481         case STATE_RXING_DATA:
    482             ret = appSecBlockRx(state);
    483             if (ret != APP_SEC_NO_ERROR)
    484                 goto out;
    485 
    486             ret = appSecProcessIncomingData(state);
    487             state->haveBytes = 0;
    488             if (ret != APP_SEC_NO_ERROR)
    489                 goto out;
    490             break;
    491 
    492         case STATE_VERIFY:
    493             ret = appSecBlockRx(state);
    494             if (ret == APP_SEC_NO_ERROR)
    495                 ret = appSecProcessIncomingData(state);
    496             if (ret == APP_SEC_NO_ERROR)
    497                 ret = appSecVerifyEncryptedData(state);
    498             goto out;
    499 
    500         case STATE_RXING_SIG_HASH:
    501         case STATE_RXING_SIG_PUBKEY:
    502             //no need for calling appSecBlockRx() as sigs are not signed, and encryption cannot be done after signing
    503             ret = appSecProcessIncomingSigData(state);
    504             state->haveBytes = 0;
    505             goto out;
    506 
    507         default:
    508             appSecSetCurState(state, STATE_BAD);
    509             state->haveBytes = 0;
    510             len = 0;
    511             ret = APP_SEC_BAD;
    512             break;
    513         }
    514     }
    515 
    516 out:
    517     *lenUnusedP = len;
    518 
    519     if (ret != APP_SEC_NO_ERROR && ret != APP_SEC_NEED_MORE_TIME) {
    520         osLog(LOG_ERROR, "%s: failed: state=%" PRIu32 "; err=%" PRIu32 "\n",
    521               __func__, appSecGetCurState(state), ret);
    522         appSecSetCurState(state,  STATE_BAD);
    523     }
    524 
    525     return ret;
    526 }
    527 
    528 AppSecErr appSecRxDataOver(struct AppSecState *state)
    529 {
    530     AppSecErr ret;
    531 
    532     // Feed remaining data to data processor, if any
    533     if (state->haveBytes) {
    534         // if we are using encryption and/or signing, we are supposed to consume all data at this point.
    535         if (state->haveSig || state->haveEncr) {
    536             appSecSetCurState(state, STATE_BAD);
    537             return APP_SEC_TOO_LITTLE_DATA;
    538         }
    539         // Not in data rx stage when the incoming data ends? This is not good (if we had encr or sign we'd not be here)
    540         if (appSecGetCurState(state) != STATE_RXING_DATA) {
    541             appSecSetCurState(state, STATE_BAD);
    542             return APP_SEC_TOO_LITTLE_DATA;
    543         }
    544         // Feed the remaining data to the data processor
    545         ret = appSecProcessIncomingData(state);
    546         if (ret != APP_SEC_NO_ERROR) {
    547             appSecSetCurState(state, STATE_BAD);
    548             return ret;
    549         }
    550     } else {
    551         // we don't know in advance how many signature packs we shall receive,
    552         // so we evaluate every signature pack as if it is the last, but do not
    553         // return error if public key is not trusted; only here we make the final
    554         // determination
    555         if (state->haveSig) {
    556             // check the most recent key status
    557             if (!state->haveTrustedKey) {
    558                 appSecSetCurState(state, STATE_BAD);
    559                 return APP_SEC_SIG_ROOT_UNKNOWN;
    560             } else {
    561                 appSecSetCurState(state, STATE_DONE);
    562             }
    563         }
    564     }
    565 
    566     //for unsigned/unencrypted case we have no way to judge length, so we assume it is over when we're told it is
    567     //this is potentially dangerous, but then again so is allowing unsigned uploads in general.
    568     if (!state->haveSig && !state->haveEncr && appSecGetCurState(state) == STATE_RXING_DATA)
    569         appSecSetCurState(state, STATE_DONE);
    570 
    571     //Check the state and return our verdict
    572     if(appSecGetCurState(state) == STATE_DONE)
    573         return APP_SEC_NO_ERROR;
    574 
    575     appSecSetCurState(state, STATE_BAD);
    576     return APP_SEC_TOO_LITTLE_DATA;
    577 }
    578