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
54struct 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
99static 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
107static 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
135static inline uint32_t appSecGetCurState(const struct AppSecState *state)
136{
137    return state->curState;
138}
139
140//init/deinit
141struct 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
160void appSecDeinit(struct AppSecState *state)
161{
162    heapFree(state);
163}
164
165//if needed, decrypt and hash incoming data
166static 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
218static 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        .rfu = { 0xFF, 0xFF },
314    };
315
316    // check to see if this is special system types of payload
317    switch(image->layout.payload) {
318    case LAYOUT_APP:
319        common.fwFlags = (common.fwFlags | FL_APP_HDR_APPLICATION) & ~FL_APP_HDR_INTERNAL;
320        common.payInfoSize = sizeof(struct AppInfo);
321        osLog(LOG_INFO, "App container found\n");
322        break;
323    case LAYOUT_KEY:
324        common.fwFlags |= FL_APP_HDR_SECURE;
325        common.payInfoSize = sizeof(struct KeyInfo);
326        osLog(LOG_INFO, "Key container found\n");
327        break;
328    case LAYOUT_OS:
329        common.payInfoSize = sizeof(struct OsUpdateHdr);
330        osLog(LOG_INFO, "OS update container found\n");
331        break;
332    default:
333        break;
334    }
335
336    memcpy(state->dataBytes, &common, sizeof(common));
337    state->haveBytes = sizeof(common);
338
339    //we're now in data-accepting state
340    appSecSetCurState(state, STATE_RXING_DATA);
341
342    return APP_SEC_NO_ERROR;
343}
344
345static AppSecErr appSecProcessIncomingData(struct AppSecState *state)
346{
347    //check for data-ending conditions
348    if (state->haveSig && !state->signedBytesIn) {
349        // we're all done with the signed portion of the data, now come the signatures
350        appSecSetCurState(state, STATE_RXING_SIG_HASH);
351
352        //collect the hash
353        memcpy(state->lastHash, BL.blSha2finish(&state->sha), SHA2_HASH_SIZE);
354    } else if (state->haveEncr && !state->encryptedBytesIn) {
355        if (appSecGetCurState(state) == STATE_RXING_DATA) {
356            //we're all done with encrypted plaintext
357            state->encryptedBytesIn = sizeof(state->cbcSha);
358            appSecSetCurState(state, STATE_VERIFY);
359        }
360    }
361
362    //pass to caller
363    return state->haveBytes ? state->writeCbk(state->dataBytes, state->haveBytes) : APP_SEC_NO_ERROR;
364}
365
366AppSecErr appSecDoSomeProcessing(struct AppSecState *state)
367{
368    const uint32_t *result;
369
370    if (!state->doingRsa) {
371        //shouldn't be calling us then...
372        return APP_SEC_BAD;
373    }
374
375    result = BL.blRsaPubOpIterative(&state->rsa, state->rsaTmp, state->dataWords, &state->rsaState1, &state->rsaState2, &state->rsaStep);
376    if (state->rsaStep)
377        return APP_SEC_NEED_MORE_TIME;
378
379    //we just finished the RSA-ing
380    state->doingRsa = 0;
381
382    //verify signature padding (and thus likely: correct decryption)
383    result = BL.blSigPaddingVerify(result);
384    if (!result)
385        return APP_SEC_SIG_DECODE_FAIL;
386
387    //check if hashes match
388    if (memcmp(state->lastHash, result, SHA2_HASH_SIZE))
389        return APP_SEC_SIG_VERIFY_FAIL;
390
391    //hash the provided pubkey
392    BL.blSha2init(&state->sha);
393    BL.blSha2processBytes(&state->sha, state->dataBytes, APP_SIG_SIZE);
394    memcpy(state->lastHash, BL.blSha2finish(&state->sha), SHA2_HASH_SIZE);
395    appSecSetCurState(state, STATE_RXING_SIG_HASH);
396
397    return APP_SEC_NO_ERROR;
398}
399
400static AppSecErr appSecProcessIncomingSigData(struct AppSecState *state)
401{
402    bool keyFound = false;
403
404    //if we're RXing the hash, just stash it away and move on
405    if (appSecGetCurState(state) == STATE_RXING_SIG_HASH) {
406        state->haveTrustedKey = 0;
407        memcpy(state->rsaTmp, state->dataWords, APP_SIG_SIZE);
408        appSecSetCurState(state, STATE_RXING_SIG_PUBKEY);
409        return APP_SEC_NO_ERROR;
410    }
411
412    // verify it is a known root
413    state->pubKeyFindCbk(state->dataWords, &keyFound);
414    state->haveTrustedKey = keyFound;
415
416    //we now have the pubKey. decrypt over time
417    state->doingRsa = 1;
418    state->rsaStep = 0;
419    return APP_SEC_NEED_MORE_TIME;
420}
421
422static AppSecErr appSecVerifyEncryptedData(struct AppSecState *state)
423{
424    const uint32_t *hash = BL.blSha2finish(&state->cbcSha);
425    bool verified = memcmp(hash, state->dataBytes, SHA2_BLOCK_SIZE) == 0;
426
427    osLog(LOG_INFO, "%s: decryption verification: %s\n", __func__, verified ? "passed" : "failed");
428
429// TODO: fix verify logic
430//    return verified ? APP_SEC_NO_ERROR : APP_SEC_VERIFY_FAILED;
431    return APP_SEC_NO_ERROR;
432}
433
434AppSecErr appSecRxData(struct AppSecState *state, const void *dataP, uint32_t len, uint32_t *lenUnusedP)
435{
436    const uint8_t *data = (const uint8_t*)dataP;
437    AppSecErr ret = APP_SEC_NO_ERROR;
438    uint32_t needBytes;
439
440    if (appSecGetCurState(state) == STATE_INIT)
441        appSecSetCurState(state, STATE_RXING_HEADERS);
442
443    while (len) {
444        len--;
445        state->dataBytes[state->haveBytes++] = *data++;
446        if (state->haveBytes < state->chunkSize)
447            continue;
448        switch (appSecGetCurState(state)) {
449        case STATE_RXING_HEADERS:
450            // AOSP header is never encrypted; if it is signed, it will hash itself
451            needBytes = 0;
452            ret = appSecProcessIncomingHdr(state, &needBytes);
453            if (ret != APP_SEC_NO_ERROR)
454                goto out;
455            if (needBytes > state->chunkSize) {
456                state->chunkSize = needBytes;
457                // get more data and try again
458                continue;
459            }
460            // done with parsing header(s); we might have something to write to flash
461            if (state->haveBytes) {
462                osLog(LOG_INFO, "%s: save converted header [%" PRIu16 " bytes] to flash\n", __func__, state->haveBytes);
463                ret = appSecProcessIncomingData(state);
464                state->haveBytes = 0;
465            }
466            limitChunkSize(state);
467            goto out;
468
469        case STATE_RXING_DATA:
470            ret = appSecBlockRx(state);
471            if (ret != APP_SEC_NO_ERROR)
472                goto out;
473
474            ret = appSecProcessIncomingData(state);
475            state->haveBytes = 0;
476            if (ret != APP_SEC_NO_ERROR)
477                goto out;
478            break;
479
480        case STATE_VERIFY:
481            ret = appSecBlockRx(state);
482            if (ret == APP_SEC_NO_ERROR)
483                ret = appSecProcessIncomingData(state);
484            if (ret == APP_SEC_NO_ERROR)
485                ret = appSecVerifyEncryptedData(state);
486            goto out;
487
488        case STATE_RXING_SIG_HASH:
489        case STATE_RXING_SIG_PUBKEY:
490            //no need for calling appSecBlockRx() as sigs are not signed, and encryption cannot be done after signing
491            ret = appSecProcessIncomingSigData(state);
492            state->haveBytes = 0;
493            goto out;
494
495        default:
496            appSecSetCurState(state, STATE_BAD);
497            state->haveBytes = 0;
498            len = 0;
499            ret = APP_SEC_BAD;
500            break;
501        }
502    }
503
504out:
505    *lenUnusedP = len;
506
507    if (ret != APP_SEC_NO_ERROR && ret != APP_SEC_NEED_MORE_TIME) {
508        osLog(LOG_ERROR, "%s: failed: state=%" PRIu32 "; err=%" PRIu32 "\n",
509              __func__, appSecGetCurState(state), ret);
510        appSecSetCurState(state,  STATE_BAD);
511    }
512
513    return ret;
514}
515
516AppSecErr appSecRxDataOver(struct AppSecState *state)
517{
518    AppSecErr ret;
519
520    // Feed remaining data to data processor, if any
521    if (state->haveBytes) {
522        // if we are using encryption and/or signing, we are supposed to consume all data at this point.
523        if (state->haveSig || state->haveEncr) {
524            appSecSetCurState(state, STATE_BAD);
525            return APP_SEC_TOO_LITTLE_DATA;
526        }
527        // 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)
528        if (appSecGetCurState(state) != STATE_RXING_DATA) {
529            appSecSetCurState(state, STATE_BAD);
530            return APP_SEC_TOO_LITTLE_DATA;
531        }
532        // Feed the remaining data to the data processor
533        ret = appSecProcessIncomingData(state);
534        if (ret != APP_SEC_NO_ERROR) {
535            appSecSetCurState(state, STATE_BAD);
536            return ret;
537        }
538    } else {
539        // we don't know in advance how many signature packs we shall receive,
540        // so we evaluate every signature pack as if it is the last, but do not
541        // return error if public key is not trusted; only here we make the final
542        // determination
543        if (state->haveSig) {
544            // check the most recent key status
545            if (!state->haveTrustedKey) {
546                appSecSetCurState(state, STATE_BAD);
547                return APP_SEC_SIG_ROOT_UNKNOWN;
548            } else {
549                appSecSetCurState(state, STATE_DONE);
550            }
551        }
552    }
553
554    //for unsigned/unencrypted case we have no way to judge length, so we assume it is over when we're told it is
555    //this is potentially dangerous, but then again so is allowing unsigned uploads in general.
556    if (!state->haveSig && !state->haveEncr && appSecGetCurState(state) == STATE_RXING_DATA)
557        appSecSetCurState(state, STATE_DONE);
558
559    //Check the state and return our verdict
560    if(appSecGetCurState(state) == STATE_DONE)
561        return APP_SEC_NO_ERROR;
562
563    appSecSetCurState(state, STATE_BAD);
564    return APP_SEC_TOO_LITTLE_DATA;
565}
566