00001
00028
00029
00030 #include <string.h>
00031
00032 #include "roboot.h"
00033 #include "xtea.h"
00034
00035
00036 #define GET_BYTE(val, byte_no) ((uint8_t) (((val) >> ((byte_no)*8)) & 0xff))
00037
00038 #define MIN(val1, val2) ((((uint32_t) (val1)) > ((uint32_t) (val2))) ? ((uint32_t) (val2)) : ((uint32_t) (val1)))
00039
00040 #define PS_FILE_MAGIC_LEN 4
00041
00042 #define PS_DEV_MAGIC_TYPE_LEN 1
00043 #define APP_ID_LEN 5
00044 #define DEV_VER_LEN 1
00045 #define PS_DEV_MAGIC_LEN (PS_DEV_MAGIC_TYPE_LEN + APP_ID_LEN + 2 * DEV_VER_LEN)
00046
00047 #define PS_FILE_MAGIC_OFF 0
00048 #define IMG_VER_MSB_OFF PS_FILE_MAGIC_OFF
00049 #define HASH_CIPHER_OFF (IMG_VER_MSB_OFF + 1)
00050 #define CIPHER_PARAMS_OFF (HASH_CIPHER_OFF + 1)
00051 #define IMG_VER_LSB_OFF (CIPHER_PARAMS_OFF + 1)
00052
00053 #define PS_DEV_MAGIC_OFF 0
00054 #define PS_DEV_MAGIC_TYPE_OFF PS_DEV_MAGIC_OFF
00055 #define DEV_ID_OFF (PS_DEV_MAGIC_TYPE_OFF + PS_DEV_MAGIC_TYPE_LEN)
00056 #define APP_ID_OFF (PS_DEV_MAGIC_TYPE_OFF + PS_DEV_MAGIC_TYPE_LEN)
00057 #define DEV_VER_MIN_OFF (APP_ID_OFF + APP_ID_LEN)
00058 #define DEV_VER_MAX_OFF (DEV_VER_MIN_OFF + DEV_VER_LEN)
00059
00060 #define KEY_LEN 128
00061
00062 #define USER_DATA_LEN 128
00063 #define NO_SECTIONS_LEN 4
00064 #define PS_CHECK_AREA_LEN (PS_FILE_MAGIC_LEN + PS_DEV_MAGIC_LEN + USER_DATA_LEN + NO_SECTIONS_LEN)
00065
00066 #define FM_CHECK_OFF 0
00067 #define DM_CHECK_OFF (FM_CHECK_OFF + PS_FILE_MAGIC_LEN)
00068 #define USER_DATA_OFF (DM_CHECK_OFF + PS_DEV_MAGIC_LEN)
00069 #define NO_SECTIONS_OFF (USER_DATA_OFF + USER_DATA_LEN)
00070
00071
00072 #define SECTION_MAGIC_LEN 4
00073 #define SECTION_ADDR_LEN 4
00074 #define SECTION_LEN_LEN 4
00075 #define SECTION_HASH_LEN 32
00076
00077 #define SECTION_MAGIC_OFF 0
00078 #define SECTION_ADDR_OFF (SECTION_MAGIC_OFF + SECTION_MAGIC_LEN)
00079 #define SECTION_LEN_OFF (SECTION_ADDR_OFF + SECTION_ADDR_LEN)
00080 #define SECTION_HASH_OFF (SECTION_LEN_OFF + SECTION_LEN_LEN)
00081 #define PS_SECTION_DATA_OFF (SECTION_HASH_OFF + SECTION_HASH_LEN)
00082
00083 #define PS_SECTION_HEADER_LEN (SECTION_MAGIC_LEN + SECTION_ADDR_LEN + SECTION_LEN_LEN + SECTION_HASH_LEN)
00084
00085
00086 #define GET_HASH_TYPE(byte) (((byte) & 0xf0) >> 4)
00087
00088 #define GET_CIPHER_TYPE(byte) ((byte) & 0x0f)
00089
00090 #define GET_ASSYMETRIC_FLAG(byte) (((byte) & 0x80) != 0)
00091
00092 #define GET_CIPHER_KEY_LEN(byte) ((byte) & 0x7f)
00093
00094
00095 #define IMG_VER_MAGIC_MSB 0xa2
00096 #define IMG_VER_MAGIC_LSB 0x75
00097 #define SECTION_MAGIC 0xdeadbeefUL
00098
00099
00100 static uint8_t input_buffer[ROBOOT_IMG_BUFFER_SIZE];
00101 static uint8_t fmagic[PS_FILE_MAGIC_LEN];
00102 static uint8_t dmagic[PS_DEV_MAGIC_LEN];
00103 static uint8_t udata[USER_DATA_LEN];
00104 static ROBOOT_ProcesingStage_T pstage;
00105 static uint32_t in_buffer;
00106 static uint32_t req_chunk_size;
00107
00108 static const ROBOOT_FLASH_Operations_T* flash_operations;
00109
00110 static uint8_t hash_type;
00111 static uint8_t cipher_type;
00112 static uint8_t use_assymetric;
00113 static uint8_t dev_key_bytes;
00114 static uint32_t expected_no_sections;
00115 static uint32_t cur_section;
00116 static uint32_t flash_update_address;
00117 static uint32_t section_start_address;
00118 static uint32_t section_len;
00119 static uint32_t section_data_processed;
00120
00121 #if ROBOOT_CIPHER_TYPE != ROBOOT_CIPHER_NONE
00122
00123 #if ROBOOT_CIPHER_TYPE == ROBOOT_CIPHER_XTEA
00124
00125 #define ROBOOT_CIPHER_KEY_SIZE XTEA_KEYLEN
00126 static XteaStateKey_T skey;
00127 #endif
00128 static uint8_t cipher_key[ROBOOT_CIPHER_KEY_SIZE];
00129 #endif
00130
00131 #if ROBOOT_HASH_TYPE != ROBOOT_HASH_NONE
00132
00133 #if ROBOOT_HASH_TYPE != ROBOOT_HASH_NONE
00134 #if ROBOOT_HASH_TYPE == ROBOOT_HASH_CRC32
00135 #define HASH_SIZE 4
00136 #elif ROBOOT_HASH_TYPE == ROBOOT_HASH_MD5
00137 #define HASH_SIZE 16
00138 #else
00139 #error "Wrong checksum type defined"
00140 #endif
00141 #endif
00142
00143 static uint8_t section_hash[HASH_SIZE];
00144
00145 typedef union {
00146 uint8_t hash_arr[HASH_SIZE];
00147 uint32_t hash_uint32;
00148 } HashField_t;
00149
00150 static HashField_t actual_hash;
00151
00152 #endif
00153
00154 #if defined(ROBOOT_USE_ASSYMETRIC_CIPHER) && (ROBOOT_USE_ASSYMETRIC_CIPHER != 0)
00155
00156
00157
00158 static void decrypt_key(uint8_t *key, uint32_t len);
00159 #endif
00160
00161 #if ROBOOT_CIPHER_TYPE != ROBOOT_CIPHER_NONE
00162
00163
00164
00165 static void setup_cipher(void);
00166 static void decrypt_data(uint8_t *data, uint32_t len);
00167 #endif
00168
00169 #if ROBOOT_HASH_TYPE != ROBOOT_HASH_NONE
00170 static void init_hash(void);
00171 static void update_hash(const uint8_t *data, uint32_t len);
00172 static uint8_t check_hash(void);
00173 #endif
00174
00175 static uint32_t deserialize_32b(const uint8_t *data);
00176
00177 static int32_t process_file_magic(void);
00178 static int32_t process_dev_magic(void);
00179 static int32_t process_crypto_key(void);
00180 static int32_t process_check_area(void);
00181 static int32_t process_section_header(void);
00182 static int32_t process_section_data(void);
00183
00184
00185
00186
00187 const uint8_t* ROBOOT_GetFileMagic(void)
00188 {
00189 return fmagic;
00190 }
00191
00192
00193
00194
00195 const uint8_t* ROBOOT_GetDeviceMagic(void)
00196 {
00197 return dmagic;
00198 }
00199
00200
00201
00202
00203 const uint8_t* ROBOOT_GetUserData(void)
00204 {
00205 return udata;
00206 }
00207
00208
00209
00210 uint8_t ROBOOT_GetHashType(void)
00211 {
00212 return hash_type;
00213 }
00214
00215
00216
00217 uint8_t ROBOOT_GetCipherType(void)
00218 {
00219 return ROBOOT_CIPHER_TYPE;
00220 }
00221
00222
00223
00224
00225 bool ROBOOT_IsAsymetricKeyCipherUsed(void)
00226 {
00227 return use_assymetric;
00228 }
00229
00230
00231
00232
00233 uint32_t ROBOOT_GetNumberOfSections(void)
00234 {
00235 return expected_no_sections;
00236 }
00237
00238
00239
00240
00241 uint8_t* ROBOOT_InitProcessing(const ROBOOT_FLASH_Operations_T* flash_oper)
00242 {
00243 in_buffer = 0;
00244 pstage = ROBOOT_PS_FILE_MAGIC;
00245 req_chunk_size = PS_FILE_MAGIC_LEN;
00246
00247 expected_no_sections = 0;
00248 cur_section = 0;
00249
00250 if (flash_oper &&
00251 ((NULL == flash_oper->FlashUnlock) || (NULL == flash_oper->FlashLock) ||
00252 (NULL == flash_oper->FlashErasePage) || (NULL == flash_oper->FlashWriteData)))
00253 {
00254
00255 flash_oper = NULL;
00256 }
00257
00258 flash_operations = flash_oper;
00259
00260 return input_buffer;
00261 }
00262
00263
00264
00265
00266 int8_t ROBOOT_ProcessPacket(uint32_t size, uint8_t **new_buf)
00267 {
00268 int32_t to_eat;
00269
00270 in_buffer += size;
00271
00272 while (in_buffer >= req_chunk_size)
00273 {
00274 switch (pstage)
00275 {
00276 case ROBOOT_PS_FILE_MAGIC:
00277 to_eat = process_file_magic();
00278 break;
00279
00280 case ROBOOT_PS_DEV_MAGIC:
00281 to_eat = process_dev_magic();
00282 break;
00283
00284 case ROBOOT_PS_CRYPTO_KEY:
00285 to_eat = process_crypto_key();
00286 break;
00287
00288 case ROBOOT_PS_CHECK_AREA:
00289 to_eat = process_check_area();
00290 break;
00291
00292 case ROBOOT_PS_SECTION_HEADER:
00293 to_eat = process_section_header();
00294 break;
00295
00296 case ROBOOT_PS_SECTION_DATA:
00297 to_eat = process_section_data();
00298 break;
00299
00300 case ROBOOT_PS_FILE_END:
00301 return ROBOOT_PS_FILE_END;
00302
00303 default:
00304 return ROBOOT_INTERNAL_ERROR;
00305 }
00306
00307 if (to_eat < 0)
00308 {
00309
00310 return to_eat;
00311 }
00312 else if (to_eat > 0)
00313 {
00314 if (in_buffer < (uint32_t) to_eat)
00315 {
00316
00317 return ROBOOT_INTERNAL_ERROR;
00318 }
00319
00320
00321 in_buffer -= to_eat;
00322 if (in_buffer)
00323 {
00324
00325 memmove(input_buffer, &input_buffer[to_eat], in_buffer);
00326 }
00327 }
00328 else
00329 {
00330 }
00331 }
00332
00333
00334 *new_buf = &input_buffer[in_buffer];
00335
00336 return pstage;
00337 }
00338
00339
00340
00341
00342 static int32_t process_file_magic(void)
00343 {
00344
00345 if ((input_buffer[IMG_VER_MSB_OFF] != IMG_VER_MAGIC_MSB) || (input_buffer[IMG_VER_LSB_OFF] != IMG_VER_MAGIC_LSB))
00346 {
00347 return ROBOOT_IMG_VERSION_ERROR;
00348 }
00349
00350
00351 hash_type = GET_HASH_TYPE(input_buffer[HASH_CIPHER_OFF]);
00352
00353 cipher_type = GET_CIPHER_TYPE(input_buffer[HASH_CIPHER_OFF]);
00354
00355
00356 if (hash_type != ROBOOT_HASH_TYPE)
00357 {
00358 return ROBOOT_IMG_HASH_MATCH_ERROR;
00359 }
00360
00361
00362 if (cipher_type != ROBOOT_CIPHER_TYPE)
00363 {
00364 return ROBOOT_IMG_CIPHER_MATCH_ERROR;
00365 }
00366
00367 use_assymetric = GET_ASSYMETRIC_FLAG(input_buffer[CIPHER_PARAMS_OFF]);
00368
00369 #if !defined(ROBOOT_USE_ASSYMETRIC_CIPHER) || (ROBOOT_USE_ASSYMETRIC_CIPHER == 0)
00370 if (use_assymetric)
00371 {
00372 return ROBOOT_IMG_ACIPHER_MATCH_ERROR;
00373 }
00374 #endif
00375
00376 dev_key_bytes = GET_CIPHER_KEY_LEN(input_buffer[CIPHER_PARAMS_OFF]);
00377
00378 if (dev_key_bytes > sizeof(ROBOOT_DeviceKey))
00379 {
00380 return ROBOOT_IMG_DEVKEY_LEN_ERROR;
00381 }
00382
00383 memcpy(fmagic, input_buffer, PS_FILE_MAGIC_LEN);
00384
00385 pstage = ROBOOT_PS_DEV_MAGIC;
00386 req_chunk_size = PS_DEV_MAGIC_LEN;
00387
00388 return PS_FILE_MAGIC_LEN;
00389 }
00390
00391
00392
00393
00394 static int32_t process_dev_magic(void)
00395 {
00396 if (ROBOOT_IMAGE_CHECK_TYPE != input_buffer[PS_DEV_MAGIC_TYPE_OFF])
00397 {
00398 return ROBOOT_IMG_CHECK_TYPE_ERROR;
00399 }
00400
00401 #if defined(ROBOOT_IMAGE_CHECK_TYPE) && (ROBOOT_IMAGE_CHECK_TYPE == ROBOOT_IMAGE_CHECK_APPVER)
00402
00403 if (((uint8_t)ROBOOT_DEVICE_VERSION < input_buffer[DEV_VER_MIN_OFF]) || ((uint8_t)ROBOOT_DEVICE_VERSION > input_buffer[DEV_VER_MAX_OFF]))
00404 {
00405 return ROBOOT_IMG_DEV_VERSION_ERROR;
00406 }
00407
00408 if (memcmp(&input_buffer[APP_ID_OFF], ROBOOT_ApplicationIdVer, sizeof(ROBOOT_ApplicationIdVer)))
00409 {
00410 return ROBOOT_IMG_APP_VERSION_ERROR;
00411 }
00412 #elif defined(ROBOOT_IMAGE_CHECK_TYPE) && (ROBOOT_IMAGE_CHECK_TYPE == ROBOOT_IMAGE_CHECK_APPID)
00413
00414 if (memcmp(&input_buffer[APP_ID_OFF], ROBOOT_ApplicationIdVer, sizeof(ROBOOT_ApplicationIdVer)))
00415 {
00416 return ROBOOT_IMG_APP_VERSION_ERROR;
00417 }
00418 #elif defined(ROBOOT_IMAGE_CHECK_TYPE) && (ROBOOT_IMAGE_CHECK_TYPE == ROBOOT_IMAGE_CHECK_DEVID)
00419
00420 if (memcmp(&input_buffer[DEV_ID_OFF], ROBOOT_DeviceID, sizeof(DeviceID)))
00421 {
00422 return ROBOOT_IMG_DEV_ID_ERROR;
00423 }
00424 #else
00425 #error "ROBOOT_IMAGE_CHECK_TYPE has wrong value"
00426 #endif
00427
00428 memcpy(dmagic, &input_buffer[PS_DEV_MAGIC_OFF], PS_DEV_MAGIC_LEN);
00429
00430 pstage = ROBOOT_PS_CRYPTO_KEY;
00431 req_chunk_size = KEY_LEN;
00432
00433 return PS_DEV_MAGIC_LEN;
00434 }
00435
00436
00437
00438
00439 static int32_t process_crypto_key(void)
00440 {
00441 #if ROBOOT_CIPHER_TYPE != ROBOOT_CIPHER_NONE
00442 uint32_t i;
00443 uint32_t buf_idx;
00444
00445 #if defined(ROBOOT_USE_ASSYMETRIC_CIPHER) && (ROBOOT_USE_ASSYMETRIC_CIPHER != 0)
00446 if (use_assymetric)
00447 {
00448
00449 decrypt_key(input_buffer, KEY_LEN);
00450 }
00451 #endif
00452
00453
00454 for (i=0; (i < dev_key_bytes) && (i < ROBOOT_CIPHER_KEY_SIZE); i++)
00455 {
00456 cipher_key[i] = ROBOOT_DeviceKey[i];
00457 }
00458
00459
00460 buf_idx = 0;
00461 for ( ; i < ROBOOT_CIPHER_KEY_SIZE; i++)
00462 {
00463 cipher_key[i] = input_buffer[buf_idx];
00464 buf_idx++;
00465 }
00466
00467 setup_cipher();
00468 #endif
00469
00470 pstage = ROBOOT_PS_CHECK_AREA;
00471 req_chunk_size = PS_CHECK_AREA_LEN;
00472
00473 return KEY_LEN;
00474 }
00475
00476
00477
00478
00479 static int32_t process_check_area(void)
00480 {
00481 #if ROBOOT_CIPHER_TYPE != ROBOOT_CIPHER_NONE
00482 decrypt_data(input_buffer, PS_CHECK_AREA_LEN);
00483 #endif
00484
00485
00486 if (memcmp(&input_buffer[FM_CHECK_OFF], fmagic, PS_FILE_MAGIC_LEN))
00487 {
00488 return ROBOOT_IMG_CHECK_FM_ERROR;
00489 }
00490
00491 if (memcmp(&input_buffer[DM_CHECK_OFF], dmagic, PS_DEV_MAGIC_LEN))
00492 {
00493 return ROBOOT_IMG_CHECK_DM_ERROR;
00494 }
00495
00496 memcpy(udata, &input_buffer[USER_DATA_OFF], USER_DATA_LEN);
00497
00498 expected_no_sections = deserialize_32b(&input_buffer[NO_SECTIONS_OFF]);
00499 cur_section = 1;
00500
00501 pstage = ROBOOT_PS_SECTION_HEADER;
00502 req_chunk_size = PS_SECTION_HEADER_LEN;
00503
00504 return PS_CHECK_AREA_LEN;
00505 }
00506
00507
00508
00509
00510 static int32_t process_section_header(void)
00511 {
00512 #if ROBOOT_CIPHER_TYPE != ROBOOT_CIPHER_NONE
00513 decrypt_data(input_buffer, PS_SECTION_HEADER_LEN);
00514 #endif
00515
00516 if (deserialize_32b(&input_buffer[SECTION_MAGIC_OFF]) != SECTION_MAGIC)
00517 {
00518 return ROBOOT_IMG_SM_ERROR;
00519 }
00520
00521 section_start_address = deserialize_32b(&input_buffer[SECTION_ADDR_OFF]);
00522 flash_update_address = section_start_address;
00523
00524 section_len = deserialize_32b(&input_buffer[SECTION_LEN_OFF]);
00525
00526 #if ROBOOT_HASH_TYPE != ROBOOT_HASH_NONE
00527 memcpy(section_hash, &input_buffer[SECTION_HASH_OFF], HASH_SIZE);
00528 init_hash();
00529 #endif
00530
00531 if (flash_operations && flash_operations->FlashUnlock(section_start_address))
00532 {
00533 return ROBOOT_FLS_UNLOCK_ERROR;
00534 }
00535
00536 if (flash_operations && flash_operations->FlashErasePage(flash_update_address))
00537 {
00538 flash_operations->FlashLock(section_start_address);
00539 return ROBOOT_FLS_ERASE_ERROR;
00540 }
00541
00542
00543 section_data_processed = 0;
00544
00545 pstage = ROBOOT_PS_SECTION_DATA;
00546 req_chunk_size = MIN(ROBOOT_FLASH_WRITE_CHUNK_LEN, section_len);
00547
00548 return PS_SECTION_HEADER_LEN;
00549 }
00550
00551
00552
00553
00554 static int32_t process_section_data(void)
00555 {
00556 uint32_t processed_chunk_size;
00557
00558 #if ROBOOT_CIPHER_TYPE != ROBOOT_CIPHER_NONE
00559 decrypt_data(input_buffer, req_chunk_size);
00560 #endif
00561
00562 #if ROBOOT_HASH_TYPE != ROBOOT_HASH_NONE
00563 update_hash(input_buffer, req_chunk_size);
00564
00565
00566 if (((section_data_processed + req_chunk_size) == section_len) && check_hash())
00567 {
00568 if (flash_operations)
00569 {
00570 flash_operations->FlashLock(section_start_address);
00571 }
00572 return ROBOOT_IMG_SECTION_CRC_ERROR;
00573 }
00574 #endif
00575
00576 if (flash_operations && flash_operations->FlashWriteData(flash_update_address, input_buffer, req_chunk_size))
00577 {
00578 return ROBOOT_FLS_WRITE_ERROR;
00579 }
00580
00581 processed_chunk_size = req_chunk_size;
00582
00583 section_data_processed += req_chunk_size;
00584 if (section_data_processed == section_len)
00585 {
00586
00587 if (flash_operations)
00588 {
00589 flash_operations->FlashLock(section_start_address);
00590 }
00591
00592 cur_section++;
00593 if (cur_section > expected_no_sections)
00594 {
00595
00596 pstage = ROBOOT_PS_FILE_END;
00597 req_chunk_size = 0;
00598 }
00599 else
00600 {
00601
00602 pstage = ROBOOT_PS_SECTION_HEADER;
00603 req_chunk_size = PS_SECTION_HEADER_LEN;
00604 }
00605 }
00606 else
00607 {
00608
00609 flash_update_address += req_chunk_size;
00610 pstage = ROBOOT_PS_SECTION_DATA;
00611 req_chunk_size = MIN(ROBOOT_FLASH_WRITE_CHUNK_LEN, section_len - section_data_processed);
00612 }
00613
00614 return processed_chunk_size;
00615 }
00616
00617
00618 #if ROBOOT_HASH_TYPE != ROBOOT_HASH_NONE
00619
00620 #if ROBOOT_HASH_TYPE == ROBOOT_HASH_CRC32
00621
00627 typedef uint32_t crc_t;
00628
00632 static const crc_t crc_table[16] = {
00633 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
00634 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
00635 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
00636 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
00637 };
00638
00639 #endif
00640
00641
00642 static void init_hash(void)
00643 {
00644 #if ROBOOT_HASH_TYPE == ROBOOT_HASH_CRC32
00645 actual_hash.hash_uint32 = 0xffffffffUL;
00646 #endif
00647 }
00648
00649
00650
00651
00652 static void update_hash(const uint8_t *data, uint32_t len)
00653 {
00654 #if HASH_TYPE == HASH_CRC32
00655
00656 uint8_t tbl_idx;
00657 crc_t crc;
00658
00659 crc = actual_hash.hash_uint32;
00660
00661 while (len--)
00662 {
00663 tbl_idx = (crc ^ (*data >> (0 * 4))) & 0x0fU;
00664 crc = crc_table[tbl_idx] ^ (crc >> 4);
00665 tbl_idx = (crc ^ (*data >> (1 * 4))) & 0x0fU;
00666 crc = crc_table[tbl_idx] ^ (crc >> 4);
00667
00668 data++;
00669 }
00670
00671 actual_hash.hash_uint32 = crc;
00672 #endif
00673 }
00674
00675
00676
00677
00678 static uint8_t check_hash(void)
00679 {
00680 #if ROBOOT_HASH_TYPE == ROBOOT_HASH_CRC32
00681 return (actual_hash.hash_uint32 ^ deserialize_32b(section_hash)) != 0xffffffffUL;
00682 #else
00683 return memcmp(section_hash, actual_hash.hash_arr, HASH_SIZE) != 0;
00684 #endif
00685 }
00686
00687 #endif
00688
00689
00690
00691
00692 static uint32_t deserialize_32b(const uint8_t *data)
00693 {
00694
00695 #ifdef __AVR_ARCH__
00696 return *(uint32_t*) data;
00697 #else
00698
00699 return (((uint32_t) data[3]) << 24) | (((uint32_t) data[2]) << 16) | (((uint32_t) data[1]) << 8) | ((uint32_t) data[0]);
00700 #endif
00701 }
00702
00703
00704 #if defined(ROBOOT_USE_ASSYMETRIC_CIPHER) && (ROBOOT_USE_ASSYMETRIC_CIPHER != 0)
00705
00706
00707 static void decrypt_key(uint8_t *key, uint32_t len)
00708 {
00709 }
00710 #endif
00711
00712
00713 #if ROBOOT_CIPHER_TYPE != ROBOOT_CIPHER_NONE
00714
00715
00716 static void setup_cipher(void)
00717 {
00718 #if ROBOOT_CIPHER_TYPE == ROBOOT_CIPHER_XTEA
00719 XteaSetup(cipher_key, NULL, &skey);
00720 #endif
00721 }
00722
00723
00724
00725 static void decrypt_data(uint8_t *data, uint32_t len)
00726 {
00727 #if ROBOOT_CIPHER_TYPE == ROBOOT_CIPHER_XTEA
00728 XteaDecrypt(data, data, len, &skey);
00729 #endif
00730 }
00731 #endif