From: razvanm Date: Sat, 22 Dec 2007 08:29:29 +0000 (+0000) Subject: Add image verification at boot time. To make this possible I had to reintroduce the... X-Git-Tag: release_tinyos_2_1_0_0~614 X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=commitdiff_plain;h=7538b51c5737223b679143838726911829823006;p=tinyos-2.x.git Add image verification at boot time. To make this possible I had to reintroduce the old meaning for some DELUGE_ constants. The ones with a new meaning are prefixed with DELUGET2 instead of DELUGE. --- diff --git a/tos/lib/net/Deluge/DelugeMsgs.h b/tos/lib/net/Deluge/DelugeMsgs.h index 449bcf1d..3096a41c 100644 --- a/tos/lib/net/Deluge/DelugeMsgs.h +++ b/tos/lib/net/Deluge/DelugeMsgs.h @@ -54,14 +54,14 @@ typedef nx_struct DelugeReqMsg { nx_uint16_t sourceAddr; nx_object_id_t objid; nx_page_num_t pgNum; - nx_uint8_t requestedPkts[DELUGE_PKT_BITVEC_SIZE]; + nx_uint8_t requestedPkts[DELUGET2_PKT_BITVEC_SIZE]; } DelugeReqMsg; typedef nx_struct DelugeDataMsg { nx_object_id_t objid; nx_page_num_t pgNum; nx_uint8_t pktNum; - nx_uint8_t data[DELUGE_PKT_PAYLOAD_SIZE]; + nx_uint8_t data[DELUGET2_PKT_PAYLOAD_SIZE]; } DelugeDataMsg; #endif diff --git a/tos/lib/net/Deluge/DelugePageTransfer.h b/tos/lib/net/Deluge/DelugePageTransfer.h index 44455b56..b5eb166b 100644 --- a/tos/lib/net/Deluge/DelugePageTransfer.h +++ b/tos/lib/net/Deluge/DelugePageTransfer.h @@ -53,10 +53,15 @@ typedef uint8_t page_num_t; typedef nx_uint8_t nx_page_num_t; enum { - DELUGE_PKT_PAYLOAD_SIZE = TOSH_DATA_LENGTH - sizeof(nx_object_id_t) - sizeof(nx_page_num_t) - sizeof(nx_uint8_t), - DELUGE_BYTES_PER_PAGE = 1024, - DELUGE_PKTS_PER_PAGE = ((DELUGE_BYTES_PER_PAGE - 1) / DELUGE_PKT_PAYLOAD_SIZE) + 1, - + DELUGET2_PKT_PAYLOAD_SIZE = TOSH_DATA_LENGTH - sizeof(nx_object_id_t) - sizeof(nx_page_num_t) - sizeof(nx_uint8_t), + DELUGET2_BYTES_PER_PAGE = 1024, + DELUGET2_PKTS_PER_PAGE = ((DELUGET2_BYTES_PER_PAGE - 1) / DELUGET2_PKT_PAYLOAD_SIZE) + 1, + DELUGET2_PKT_BITVEC_SIZE = (((DELUGET2_PKTS_PER_PAGE - 1) / 8) + 1), + + DELUGE_PKT_PAYLOAD_SIZE = 23, + DELUGE_PKTS_PER_PAGE = 48, + DELUGE_BYTES_PER_PAGE = (DELUGE_PKTS_PER_PAGE*DELUGE_PKT_PAYLOAD_SIZE), + DELUGE_VERSION = 2, DELUGE_MAX_ADV_PERIOD_LOG2 = 22, DELUGE_NUM_NEWDATA_ADVS_REQUIRED = 2, @@ -70,7 +75,6 @@ enum { DELUGE_INVALID_ADDR = (0x7fffffffL), DELUGE_MAX_REQ_DELAY = (0x1L << (DELUGE_MIN_ADV_PERIOD_LOG2 - 1)), DELUGE_NACK_TIMEOUT = (DELUGE_MAX_REQ_DELAY >> 0x1), - DELUGE_PKT_BITVEC_SIZE = (((DELUGE_PKTS_PER_PAGE - 1) / 8) + 1), DELUGE_MAX_IMAGE_SIZE = (128L * 1024L), DELUGE_MAX_PAGES = 128, DELUGE_CRC_SIZE = sizeof(uint16_t), diff --git a/tos/lib/net/Deluge/DelugePageTransferP.nc b/tos/lib/net/Deluge/DelugePageTransferP.nc index 2ceb3ed0..57e6757b 100644 --- a/tos/lib/net/Deluge/DelugePageTransferP.nc +++ b/tos/lib/net/Deluge/DelugePageTransferP.nc @@ -56,8 +56,8 @@ module DelugePageTransferP implementation { // send/receive page buffers, and state variables for buffers - uint8_t pktsToSend[DELUGE_PKT_BITVEC_SIZE]; // bit vec of packets to send - uint8_t pktsToReceive[DELUGE_PKT_BITVEC_SIZE]; // bit vec of packets to receive + uint8_t pktsToSend[DELUGET2_PKT_BITVEC_SIZE]; // bit vec of packets to send + uint8_t pktsToReceive[DELUGET2_PKT_BITVEC_SIZE]; // bit vec of packets to receive DelugeDataMsg rxQueue[DELUGE_QSIZE]; uint8_t head, size; @@ -133,7 +133,7 @@ implementation // send req message else { uint32_t i; - for (i = 0; i < DELUGE_PKT_BITVEC_SIZE; i++) { + for (i = 0; i < DELUGET2_PKT_BITVEC_SIZE; i++) { pReqMsg->requestedPkts[i] = pktsToReceive[i]; } //memcpy(pReqMsg->requestedPkts, pktsToReceive, DELUGE_PKT_BITVEC_SIZE); @@ -146,8 +146,8 @@ implementation storage_addr_t calcOffset(page_num_t pgNum, uint8_t pktNum) { - return (storage_addr_t)pgNum * (storage_addr_t)DELUGE_BYTES_PER_PAGE - + (uint16_t)pktNum * (uint16_t)DELUGE_PKT_PAYLOAD_SIZE; + return (storage_addr_t)pgNum * (storage_addr_t)DELUGET2_BYTES_PER_PAGE + + (uint16_t)pktNum * (uint16_t)DELUGET2_PKT_PAYLOAD_SIZE; //+ DELUGE_METADATA_SIZE; } @@ -173,13 +173,13 @@ implementation pDataMsg->pktNum = 0; } - if (call BitVecUtils.indexOf(&nextPkt, pDataMsg->pktNum, pktsToSend, DELUGE_PKTS_PER_PAGE) != SUCCESS) { + if (call BitVecUtils.indexOf(&nextPkt, pDataMsg->pktNum, pktsToSend, DELUGET2_PKTS_PER_PAGE) != SUCCESS) { // no more packets to send //dbg(DBG_USR1, "DELUGE: SEND_DONE\n"); changeState(S_IDLE); } else { pDataMsg->pktNum = nextPkt; - if (call BlockRead.read[imgNum](calcOffset(pageToSend, nextPkt), pDataMsg->data, DELUGE_PKT_PAYLOAD_SIZE) != SUCCESS) { + if (call BlockRead.read[imgNum](calcOffset(pageToSend, nextPkt), pDataMsg->data, DELUGET2_PKT_PAYLOAD_SIZE) != SUCCESS) { call Timer.startOneShot(DELUGE_FAILED_SEND_DELAY); } } @@ -215,7 +215,7 @@ implementation if (objid < objToSend || (objid == objToSend && pgNum < pageToSend)) { uint32_t i; changeState(S_IDLE); - for (i = 0; i < DELUGE_PKT_BITVEC_SIZE; i++) { + for (i = 0; i < DELUGET2_PKT_BITVEC_SIZE; i++) { pktsToSend[i] = 0x00; } //memset(pktsToSend, 0x00, DELUGE_PKT_BITVEC_SIZE); @@ -231,7 +231,7 @@ implementation void writeData() { if(call BlockWrite.write[imgNum](calcOffset(rxQueue[head].pgNum, rxQueue[head].pktNum), - rxQueue[head].data, DELUGE_PKT_PAYLOAD_SIZE) != SUCCESS) { + rxQueue[head].data, DELUGET2_PKT_PAYLOAD_SIZE) != SUCCESS) { size = 0; } } @@ -245,10 +245,10 @@ implementation workingObjid = DELUGE_INVALID_OBJID; workingPgNum = DELUGE_INVALID_PGNUM; - for (i = 0; i < DELUGE_PKT_BITVEC_SIZE; i++) { + for (i = 0; i < DELUGET2_PKT_BITVEC_SIZE; i++) { pktsToReceive[i] = 0x00; } - for (i = 0; i < DELUGE_PKT_BITVEC_SIZE; i++) { + for (i = 0; i < DELUGET2_PKT_BITVEC_SIZE; i++) { pktsToSend[i] = 0x00; } //memset(pktsToReceive, 0x00, DELUGE_PKT_BITVEC_SIZE); @@ -268,7 +268,7 @@ implementation workingObjid = new_objid; workingPgNum = new_pgNum; - for (i = 0; i < DELUGE_PKT_BITVEC_SIZE; i++) { + for (i = 0; i < DELUGET2_PKT_BITVEC_SIZE; i++) { pktsToReceive[i] = 0xFF; } //memset(pktsToReceive, (nx_uint8_t)0xff, DELUGE_PKT_BITVEC_SIZE); @@ -346,7 +346,7 @@ implementation && objid == objToSend && pgNum == pageToSend)) { // take union of packet bit vectors - for (i = 0; i < DELUGE_PKT_BITVEC_SIZE; i++) { + for (i = 0; i < DELUGET2_PKT_BITVEC_SIZE; i++) { pktsToSend[i] |= rxReqMsg->requestedPkts[i]; } } @@ -460,7 +460,7 @@ call Leds.led1Toggle(); // failed to write if (error != SUCCESS) { uint32_t i; - for (i = 0; i < DELUGE_PKT_BITVEC_SIZE; i++) { + for (i = 0; i < DELUGET2_PKT_BITVEC_SIZE; i++) { pktsToReceive[i] = 0xFF; } size = 0; @@ -472,7 +472,7 @@ call Leds.led1Toggle(); head = (head + 1) % DELUGE_QSIZE; size--; - if (call BitVecUtils.indexOf(&tmp, 0, pktsToReceive, DELUGE_PKTS_PER_PAGE) != SUCCESS) { + if (call BitVecUtils.indexOf(&tmp, 0, pktsToReceive, DELUGET2_PKTS_PER_PAGE) != SUCCESS) { // For collecting stats //call StatsCollector.endRecvPageTransTime(publisher_addr); dbg("Deluge", "%.3f 115 116 116 117 115 2 %d\n", ((float)((sim_time() * 1000) / sim_ticks_per_sec())) / 1000, publisher_addr); diff --git a/tos/lib/net/Deluge/DelugeStorageC.nc b/tos/lib/net/Deluge/DelugeStorageC.nc index 78d56ce3..214f4a86 100644 --- a/tos/lib/net/Deluge/DelugeStorageC.nc +++ b/tos/lib/net/Deluge/DelugeStorageC.nc @@ -34,7 +34,7 @@ configuration DelugeStorageC interface DelugeStorage[uint8_t img_num]; interface DelugeMetadata; - interface Notify; + interface Notify as ReadyNotify; } } @@ -92,5 +92,5 @@ implementation DelugeStorageP.Leds -> LedsC; DelugeStorageP.Boot -> MainC; - Notify = DelugeStorageP.Notify; + ReadyNotify = DelugeStorageP.ReadyNotify; } diff --git a/tos/lib/net/Deluge/DelugeStorageP.nc b/tos/lib/net/Deluge/DelugeStorageP.nc index 67c9f6cc..563ecd12 100644 --- a/tos/lib/net/Deluge/DelugeStorageP.nc +++ b/tos/lib/net/Deluge/DelugeStorageP.nc @@ -25,6 +25,7 @@ */ #include "Deluge.h" +#include "DelugePageTransfer.h" module DelugeStorageP { @@ -45,21 +46,46 @@ module DelugeStorageP interface DelugeStorage[uint8_t img_num]; interface DelugeMetadata; - interface Notify; + interface Notify as ReadyNotify; } } implementation { enum { - S_INIT, + S_READ_META, + S_READ_CRC, + S_CRC, S_READY, }; - uint8_t state = S_INIT; - uint8_t last_init_img_num = 0; + uint8_t state; + uint8_t current_image; + uint8_t current_page; + uint16_t current_crc; DelugeImgDesc imgDesc[DELUGE_NUM_VOLUMES]; + void nextImage() + { + if (current_image < DELUGE_NUM_VOLUMES) { + state = S_READ_META; + call SubBlockRead.read[current_image](0, &(imgDesc[current_image]), sizeof(DelugeImgDesc)); + } else { + signal ReadyNotify.notify(SUCCESS); + state = S_READY; + } + } + + uint32_t calcCrcAddr() + { + return DELUGE_METADATA_SIZE + current_page * sizeof(uint16_t); + } + + uint32_t calcPageAddr() + { + return DELUGE_METADATA_SIZE + current_page * DELUGE_BYTES_PER_PAGE; + } + event void Boot.booted() { uint32_t i; @@ -74,11 +100,14 @@ implementation imgDesc[i].size = 0; } - // Reads image descriptions - state = S_INIT; - if (DELUGE_NUM_VOLUMES > 0) { - call SubBlockRead.read[last_init_img_num](0, &(imgDesc[last_init_img_num]), sizeof(DelugeImgDesc)); - } + // We are going to iterate over all the images and verify their + // integrity. For each image we first read the metadata to find + // the number of pages and then iterate over all of them, compute + // the CRC and check it against the corresponding value from the CRCs + // block. + state = S_READ_META; + current_image = 0; + nextImage(); } command DelugeImgDesc* DelugeMetadata.getImgDesc(imgnum_t imgNum) @@ -105,25 +134,56 @@ implementation // BlockRead events event void SubBlockRead.readDone[uint8_t img_num](storage_addr_t addr, void* buf, storage_len_t len, error_t error) { - if (state == S_READY) { + switch (state) { + case S_READY: signal BlockRead.readDone[img_num](addr, buf, len, error); - } else { - // Continues reading image descriptions + break; + case S_READ_META: if (error == SUCCESS) { - last_init_img_num++; - if (last_init_img_num >= DELUGE_NUM_VOLUMES) { - signal Notify.notify(SUCCESS); - state = S_READY; - } else { - call SubBlockRead.read[last_init_img_num](0, &(imgDesc[last_init_img_num]), sizeof(DelugeImgDesc)); - } + if (imgDesc[current_image].uid != DELUGE_INVALID_UID) { + current_page = 0; + state = S_READ_CRC; + call SubBlockRead.read[current_image](calcCrcAddr(), ¤t_crc, sizeof(current_crc)); + } else { + current_image++; + nextImage(); + } + } + break; + case S_READ_CRC: + state = S_CRC; + if (current_page == 0) { + call SubBlockRead.computeCrc[current_image](calcPageAddr() + DELUGE_CRC_BLOCK_SIZE, + DELUGE_BYTES_PER_PAGE - DELUGE_CRC_BLOCK_SIZE, 0); + } else { + call SubBlockRead.computeCrc[current_image](calcPageAddr(), DELUGE_BYTES_PER_PAGE, 0); } + break; } } event void SubBlockRead.computeCrcDone[uint8_t img_num](storage_addr_t addr, storage_len_t len, uint16_t crc, error_t error) { - signal BlockRead.computeCrcDone[img_num](addr, len, crc, error); + switch (state) { + case S_READY: + signal BlockRead.computeCrcDone[img_num](addr, len, crc, error); + break; + case S_CRC: + if (crc != current_crc) { + // invalidate the image by erasing it + call SubBlockWrite.erase[current_image](); + } else { + current_page++; + if (current_page < imgDesc[current_image].numPgs) { + state = S_READ_CRC; + call SubBlockRead.read[current_image](calcCrcAddr(), ¤t_crc, sizeof(current_crc)); + } else { + current_image++; + nextImage(); + } + } + break; + } } // SubBlockWrite commands @@ -167,8 +227,16 @@ implementation imgDesc[img_num].reserved = 0; imgDesc[img_num].size = 0; } - - signal BlockWrite.eraseDone[img_num](error); + + switch (state) { + case S_READY: + signal BlockWrite.eraseDone[img_num](error); + break; + case S_CRC: + current_image++; + nextImage(); + break; + } } event void SubBlockWrite.syncDone[uint8_t img_num](error_t error) @@ -206,8 +274,8 @@ implementation default command error_t SubBlockRead.computeCrc[uint8_t img_num](storage_addr_t addr, storage_len_t len, uint16_t crc) { return FAIL; } default command storage_len_t SubBlockRead.getSize[uint8_t img_num]() { return 0; } - command error_t Notify.enable() { return SUCCESS; } - command error_t Notify.disable() { return SUCCESS; } + command error_t ReadyNotify.enable() { return SUCCESS; } + command error_t ReadyNotify.disable() { return SUCCESS; } #if defined(PLATFORM_TELOSB) default command storage_addr_t StorageMap.getPhysicalAddress[uint8_t img_num](storage_addr_t addr) { return 0xFFFFFFFF; } diff --git a/tos/lib/net/Deluge/ObjectTransferP.nc b/tos/lib/net/Deluge/ObjectTransferP.nc index 8c6b4996..88878217 100644 --- a/tos/lib/net/Deluge/ObjectTransferP.nc +++ b/tos/lib/net/Deluge/ObjectTransferP.nc @@ -170,7 +170,7 @@ implementation state = S_INITIALIZING_PUB; curObjDesc.objid = new_objid; - curObjDesc.numPgs = ((new_size - 1) / DELUGE_BYTES_PER_PAGE) + 1; // Number of pages to transmit + curObjDesc.numPgs = ((new_size - 1) / DELUGET2_BYTES_PER_PAGE) + 1; // Number of pages to transmit curObjDesc.numPgsComplete = curObjDesc.numPgs; // Publisher doesn't really care about this curObjDesc.crc = call Crc.crc16(&curObjDesc, sizeof(object_id_t) + sizeof(page_num_t)); @@ -191,7 +191,7 @@ implementation void cont_receive() { state = S_INITIALIZING_RECV; curObjDesc.objid = cont_receive_new_objid; - curObjDesc.numPgs = ((cont_receive_new_size - 1) / DELUGE_BYTES_PER_PAGE) + 1; // Number of pages to receive + curObjDesc.numPgs = ((cont_receive_new_size - 1) / DELUGET2_BYTES_PER_PAGE) + 1; // Number of pages to receive curObjDesc.numPgsComplete = 0; curObjDesc.crc = call Crc.crc16(&curObjDesc, sizeof(object_id_t) + sizeof(page_num_t));