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