⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tinysecm.nc

📁 传感器网络中的嵌入式操作系统源代码
💻 NC
📖 第 1 页 / 共 2 页
字号:
    } else if(compute_mac_state == COMPUTE_MAC_INITIALIZED) {      result_t result;      compute_mac_state = COMPUTE_MAC_BUSY;      interruptEnable();      result = call MAC.incrementalMAC(			 &macContext,		         ((uint8_t*) ciphertext_rec_ptr)+incr_mac_start,amount);      interruptDisable();      compute_mac_state = COMPUTE_MAC_INITIALIZED;      result = rcombine(result,checkQueuedCrypto());      return result;    } else {      return FAIL;    }  }  result_t computeMACIncrementalFinish() {    if(!initialized)      return FAIL;        if(compute_mac_state == COMPUTE_MAC_IDLE) {      // this is an error. state should be unreachable      return FAIL;    } else if(compute_mac_state == COMPUTE_MAC_INITIALIZED) {       result_t result;      compute_mac_state = COMPUTE_MAC_BUSY;      interruptEnable();      result = call MAC.getIncrementalMAC(				     &macContext,				     ciphertext_rec_ptr->calc_mac,				     TINYSEC_MAC_LENGTH+TINYSEC_ACK_LENGTH);      interruptDisable();      ciphertext_rec_ptr->validMAC = TRUE;      if(ciphertext_rec_ptr->receiveDone) {	verifyMAC();      }      compute_mac_state = COMPUTE_MAC_IDLE;      result = rcombine(result,checkQueuedCrypto());      return result;    } else {      return FAIL;    }  }  result_t verifyMAC() {    int i;    if(!initialized)       return FAIL;    // indicates incremental MAC computation has not completed    if(!ciphertext_rec_ptr->validMAC) {      return FAIL;    }    dbg(DBG_CRYPTO,"MAC computed: %hx %hx %hx %hx, "	"MAC received: %hx %hx %hx %hx\n",	(ciphertext_rec_ptr->calc_mac)[0],	(ciphertext_rec_ptr->calc_mac)[1],	(ciphertext_rec_ptr->calc_mac)[2],	(ciphertext_rec_ptr->calc_mac)[3],	(ciphertext_rec_ptr->mac)[0],	(ciphertext_rec_ptr->mac)[1],	(ciphertext_rec_ptr->mac)[2],	(ciphertext_rec_ptr->mac)[3]);    // verify calculated MAC with one received in packet    for(i=0;i<TINYSEC_MAC_LENGTH;i++) {      if((ciphertext_rec_ptr->calc_mac)[i] != (ciphertext_rec_ptr->mac)[i]) {        dbg(DBG_CRYPTO,"Invalid MAC byte %d - calcmac:%hx ciphermac:%hx\n",i,	    (ciphertext_rec_ptr->calc_mac)[i],	    (ciphertext_rec_ptr->mac)[i]);	ciphertext_rec_ptr->validMAC = FALSE;	cleartext_rec_ptr->crc = 0;	return SUCCESS;      }    }    cleartext_rec_ptr->crc = 1;    return SUCCESS;  }  /***************** Receive code *****************************/  async command result_t TinySec.receiveInit(				        TOS_Msg_TinySecCompat* cleartext_ptr) {    ciphertext_rec_ptr = &tinysec_rec_buffer;    cleartext_rec_ptr = cleartext_ptr;    RxByteCnt = 0;    rxlength = TINYSEC_MSG_DATA_SIZE-TINYSEC_MAC_LENGTH;    rxdecrypt = FALSE;        // initialize state variables in receive buffer    ciphertext_rec_ptr->cryptoDone = FALSE;    ciphertext_rec_ptr->receiveDone = FALSE;    ciphertext_rec_ptr->validMAC = FALSE;        // reset crypto buffer variables    computeMACBuffer.computeMACWaiting = FALSE;    computeMACBuffer.computeMACInitWaiting = FALSE;    decryptBuffer.decryptWaiting = FALSE;    decryptBuffer.decryptInitWaiting = FALSE;    computeMACBuffer.finishMACWaiting = FALSE;        // flush crc    cleartext_rec_ptr->crc = 0;     return SUCCESS;  }      async event result_t TinySecRadio.byteReceived(uint8_t byte) {    int8_t macRecCount=-1, decryptRecCount=-1;    if(RxByteCnt < rxlength) {      // this branch statement is a hack for when we skip      // over the IV for non-encrypted packets. we add the TINYSEC_IV_SIZE       if(!rxdecrypt && RxByteCnt == offsetof(struct TinySec_Msg,iv)) {	RxByteCnt += TINYSEC_IV_LENGTH;	((uint8_t *) ciphertext_rec_ptr)[(int)RxByteCnt] = byte;	RxByteCnt++;	macRecCount = ((RxByteCnt - TINYSEC_IV_LENGTH) & (blockSize-1)) +	  TINYSEC_IV_LENGTH;	decryptRecCount = RxByteCnt - offsetof(struct TinySec_Msg,enc);       } else {	((uint8_t *) ciphertext_rec_ptr)[(int)RxByteCnt] = byte;	RxByteCnt++;	macRecCount = RxByteCnt & (blockSize-1);	decryptRecCount = RxByteCnt - offsetof(struct TinySec_Msg,enc);      }    } else if(RxByteCnt < rxlength + TINYSEC_IV_LENGTH) {      ciphertext_rec_ptr->mac[RxByteCnt-rxlength] = byte;      RxByteCnt++;    }        dbg(DBG_CRYPTO,"TINYSEC: byteReceived() RxByteCnt=%d data=%hx "	"recDataLength=%d macRecCount=%d decryptRecCount=%d.\n",	RxByteCnt,byte,recDataLength,macRecCount,decryptRecCount);	        if(RxByteCnt < rxlength) {      if(RxByteCnt == (offsetof(struct TinySec_Msg,length) + 		       sizeof(((struct TinySec_Msg *)0)->length))) {	// get real length	recDataLength = ciphertext_rec_ptr->length &	  (TINYSEC_ENCRYPT_ENABLED_BIT-1);	if(recDataLength > DATA_LENGTH)	  signal TinySec.receiveInitDone(FAIL,0,FALSE);		if(ciphertext_rec_ptr->length & TINYSEC_ENABLED_BIT) {	  dbg(DBG_CRYPTO,"Detected TinySec bit.\n");	  if(ciphertext_rec_ptr->length & TINYSEC_ENCRYPT_ENABLED_BIT) {	    dbg(DBG_CRYPTO,"Encryption enabled.\n");	    rxdecrypt = TRUE;	  } else {	    dbg(DBG_CRYPTO,"Encryption disabled.\n");	    rxdecrypt = FALSE;	  }	  rxlength = offsetof(struct TinySec_Msg,enc);	  	  if(recDataLength < blockSize && rxdecrypt)	    rxlength += blockSize;	  else	    rxlength += recDataLength;	  	  if(rxdecrypt) {	    signal TinySec.receiveInitDone(SUCCESS,rxlength,TRUE);	  } else {	    // zero out iv if encryption is not enabled	    memset(ciphertext_rec_ptr->iv,0,TINYSEC_IV_LENGTH);	    signal TinySec.receiveInitDone(SUCCESS,					   rxlength-TINYSEC_IV_LENGTH,TRUE);	  }	  postIncrementalMACInit();	} else { // TinySec not enabled	  rxlength = recDataLength + offsetof(struct TOS_Msg_TinySecCompat,					      data);	  signal TinySec.receiveInitDone(SUCCESS,rxlength,FALSE);	}      } else { // not length byte.	// bytes before length byte will fail following checks.	// this weird check is needed because of when we	// skip RxByteCnt over the IV when encryption in not enabled.	if(macRecCount == 0)	  macRecCount = blockSize;	if(macRecCount >= blockSize) {	  // post MAC operation	  postIncrementalMAC(RxByteCnt-macRecCount,blockSize);	}		if(rxdecrypt) {	  if(decryptRecCount == 0) {	    postIncrementalDecryptInit();	  } else if((decryptRecCount & (blockSize-1)) == 0) {	    postIncrementalDecrypt(decryptRecCount-blockSize,blockSize);	  }	}      }      checkQueuedCrypto();    } else if(RxByteCnt == rxlength) {      if(macRecCount == 0)	macRecCount = blockSize;      postIncrementalMAC(RxByteCnt-macRecCount,macRecCount);      postIncrementalMACFinish();      if(rxdecrypt) {	if((decryptRecCount & (blockSize-1)) == 0) {	  postIncrementalDecrypt(decryptRecCount-blockSize,blockSize);	}	else {	  postIncrementalDecrypt(			   decryptRecCount-(decryptRecCount & (blockSize-1)),			   decryptRecCount & (blockSize-1));	}      } else {	memcpy(cleartext_rec_ptr->data,ciphertext_rec_ptr->enc,recDataLength);      }      checkQueuedCrypto();      ciphertext_rec_ptr->cryptoDone = TRUE;      cleartext_rec_ptr->group = TOS_AM_GROUP;      if(ciphertext_rec_ptr->receiveDone) {		signal TinySec.receiveDone(SUCCESS);      }    } else if(RxByteCnt == rxlength + TINYSEC_IV_LENGTH) {       ciphertext_rec_ptr->receiveDone = TRUE;      if(ciphertext_rec_ptr->validMAC)	verifyMAC();      if(ciphertext_rec_ptr->cryptoDone) {	signal TinySec.receiveDone(SUCCESS);      }    } else { // we have an error      return FAIL;    }         return SUCCESS;  }      /****************** Send code ****************************/  async command uint16_t TinySec.sendInit(TOS_Msg_TinySecCompat* cleartext_ptr) {    cleartext_send_ptr = cleartext_ptr;    ciphertext_send_ptr = &tinysec_send_buffer;    ciphertext_send_ptr->addr = cleartext_send_ptr->addr;    ciphertext_send_ptr->length = cleartext_send_ptr->length;    ciphertext_send_ptr->type = cleartext_send_ptr->type;    sendDataLength = cleartext_send_ptr->length &      (TINYSEC_ENCRYPT_ENABLED_BIT-1);    dbg(DBG_CRYPTO,"TINYSEC: sendInit() Sending length = %d\n",sendDataLength);    dbg(DBG_CRYPTO,"TINYSEC: sendInit() Length field = %d\n",	ciphertext_send_ptr->length);    // fix length fields that are too long    if(sendDataLength > DATA_LENGTH) {      sendDataLength = DATA_LENGTH;      ciphertext_send_ptr->length = DATA_LENGTH | TINYSEC_ENABLED_BIT |	(cleartext_send_ptr->length & TINYSEC_ENCRYPT_ENABLED_BIT);    }        if(cleartext_send_ptr->length & TINYSEC_ENCRYPT_ENABLED_BIT)      txencrypt = TRUE;    else      txencrypt = FALSE;    if(sendDataLength < blockSize && txencrypt) {      txlength = blockSize + TINYSEC_MSG_DATA_SIZE - DATA_LENGTH -	TINYSEC_MAC_LENGTH;    } else {      txlength = sendDataLength + TINYSEC_MSG_DATA_SIZE - DATA_LENGTH -	TINYSEC_MAC_LENGTH;    }    TxByteCnt = -1;        return txlength;      }  result_t computeMAC() {    result_t result = call MAC.MAC(&macContext,				   (uint8_t*) &(ciphertext_send_ptr->addr),     				   txlength,				   ciphertext_send_ptr->calc_mac,				   TINYSEC_MAC_LENGTH+TINYSEC_ACK_LENGTH);    // copy calculated mac to mac field. reason is because extra byte    // was calculated and stored in ack_byte. ack_byte is    // currently not used.    memcpy(ciphertext_send_ptr->mac,ciphertext_send_ptr->calc_mac,	   TINYSEC_MAC_LENGTH);    dbg(DBG_CRYPTO,"MAC: computed: %hx %hx %hx %hx\n",	(ciphertext_send_ptr->mac)[0],	(ciphertext_send_ptr->mac)[1],	(ciphertext_send_ptr->mac)[2],	(ciphertext_send_ptr->mac)[3]);    return result;  }  // for padding out input less than a block size  result_t addPadding(TOS_Msg_TinySecCompat* bufptr, uint16_t dataLength) {    uint16_t r = call Random.rand();    uint8_t i = 0;    for(i=dataLength;i<blockSize-1;i=i+2) {      memcpy((bufptr->data)+i,&r,2);      r = call Random.rand();    }    if(i == (blockSize-1)) {      memcpy((bufptr->data)+i,&r,1);    }    return SUCCESS;  }    result_t encrypt() {    // number of header bytes we use for implicit IV    uint16_t ivLengthRemaining = sizeof(ciphertext_send_ptr->addr) +      sizeof(ciphertext_send_ptr->type) + sizeof(ciphertext_send_ptr->length);    result_t result;    uint8_t i;        if(ivLengthRemaining > (blockSize - TINYSEC_IV_LENGTH))      ivLengthRemaining = blockSize - TINYSEC_IV_LENGTH;    // copy current iv into cipher buffer iv field    memcpy(&(ciphertext_send_ptr->iv),iv,TINYSEC_IV_LENGTH);    // fill in remaining space with addr, AM type, and length    memcpy(iv+TINYSEC_IV_LENGTH,&(ciphertext_send_ptr->addr),ivLengthRemaining);     // zero out the rest of the iv    for(i=ivLengthRemaining+TINYSEC_IV_LENGTH;i<blockSize;i++) {      iv[i] = 0;    }    if(sendDataLength < blockSize) {      // pad if data length less than blockSize      addPadding(cleartext_send_ptr,sendDataLength);      result = call BlockCipherMode.encrypt(&cipherModeContext,					    cleartext_send_ptr->data,					    ciphertext_send_ptr->enc,					    blockSize,iv);    } else {      result = call BlockCipherMode.encrypt(&cipherModeContext,					    cleartext_send_ptr->data,					    ciphertext_send_ptr->enc,					    sendDataLength,iv);    }        i=0;    // update IV by one    // last two bytes of explicit IV is TOS_LOCAL_ADDRESS    while(i<TINYSEC_IV_LENGTH-TINYSEC_NODE_ID_SIZE) {       if(iv[i] == 0xff) {	iv[i] = 0;      } else {	iv[i] = iv[i] + 1;	break;      }      i++;    }    return result;      }  result_t noEncrypt() {    // zero out IV if no encryption    memset(ciphertext_send_ptr->iv,0,TINYSEC_IV_LENGTH);    memcpy(ciphertext_send_ptr->enc,cleartext_send_ptr->data,sendDataLength);    return SUCCESS;  }      async command result_t TinySec.send() {    result_t r1,r2;        interruptEnable();    if(txencrypt)      r1 = encrypt();    else       r1 = noEncrypt();    r2 = computeMAC();    interruptDisable();        return rcombine(r1,r2);      }    async event uint8_t TinySecRadio.getTransmitByte() {    uint8_t NextTxByte=0;    TxByteCnt++;    if (TxByteCnt < txlength) {      // skip iv if encryption not enabled      if(TxByteCnt == offsetof(struct TinySec_Msg, iv) && !txencrypt)	TxByteCnt += TINYSEC_IV_LENGTH;      NextTxByte = ((uint8_t *)&tinysec_send_buffer)[(TxByteCnt)];      dbg(DBG_CRYPTO,"TINYSEC: getTransmitByte() byte=%d data=%hx\n",	  TxByteCnt+1,NextTxByte);    } else if(TxByteCnt < txlength + TINYSEC_MAC_LENGTH) {      NextTxByte = tinysec_send_buffer.mac[TxByteCnt-txlength];      dbg(DBG_CRYPTO,"TINYSEC: getTransmitByte() byte=%d data=%hx\n",	  TxByteCnt+1,NextTxByte);      if(TxByteCnt == txlength + TINYSEC_MAC_LENGTH - 1) {	signal TinySec.sendDone(SUCCESS);	dbg(DBG_CRYPTO,"TINYSEC: getTransmitByte() signaling send done\n");      }    } else { // this is an error state      dbg(DBG_CRYPTO,"TINYSEC: getTransmitByte() signaling send done (FAIL)\n");      signal TinySec.sendDone(FAIL);    }        return NextTxByte;  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -