• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
limitChunkSize(struct AppSecState * state)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 
appSecSetCurState(struct AppSecState * state,uint32_t curState)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 
appSecGetCurState(const struct AppSecState * state)135 static inline uint32_t appSecGetCurState(const struct AppSecState *state)
136 {
137     return state->curState;
138 }
139 
140 //init/deinit
appSecInit(AppSecWriteCbk writeCbk,AppSecPubKeyFindCbk pubKeyFindCbk,AppSecGetAesKeyCbk aesKeyAccessCbk,bool mandateSigning)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 
appSecDeinit(struct AppSecState * state)160 void appSecDeinit(struct AppSecState *state)
161 {
162     heapFree(state);
163 }
164 
165 //if needed, decrypt and hash incoming data
appSecBlockRx(struct AppSecState * state)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 
appSecProcessIncomingHdr(struct AppSecState * state,uint32_t * needBytesOut)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 
appSecProcessIncomingData(struct AppSecState * state)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 
appSecDoSomeProcessing(struct AppSecState * state)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 
appSecProcessIncomingSigData(struct AppSecState * state)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 
appSecVerifyEncryptedData(struct AppSecState * state)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 
appSecRxData(struct AppSecState * state,const void * dataP,uint32_t len,uint32_t * lenUnusedP)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 
appSecRxDataOver(struct AppSecState * state)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