📄 tinysecm.nc
字号:
if(receiveMode == TINYSEC_RECEIVE_AUTHENTICATED) return signal Receive.receive(msg); else return msg; } else { if(receiveMode == TINYSEC_RECEIVE_CRC) return signal Receive.receive(msg); else return msg; } } command result_t TinySecMode.setTransmitMode(uint8_t mode) { if(mode == TINYSEC_ENCRYPT_AND_AUTH || mode == TINYSEC_AUTH_ONLY || mode == TINYSEC_DISABLED) { sendMode = mode; return SUCCESS; } else return FAIL; } command result_t TinySecMode.setReceiveMode(uint8_t mode) { if(mode == TINYSEC_RECEIVE_AUTHENTICATED || mode == TINYSEC_RECEIVE_CRC || mode == TINYSEC_RECEIVE_ANY) { receiveMode = mode; return SUCCESS; } else return FAIL; } command uint8_t TinySecMode.getTransmitMode() { return sendMode; } command uint8_t TinySecMode.getReceiveMode() { return receiveMode; } result_t decryptIncrementalInit(); result_t decryptIncremental(uint8_t incr_decrypt_start, uint8_t amount); result_t MACincrementalInit(); result_t computeMACIncremental(uint8_t incr_mac_start, uint8_t amount); result_t computeMACIncrementalFinish(); result_t verifyMAC(); result_t computeMAC(); result_t encrypt(); result_t noEncrypt(); result_t checkedQueuedCrypto(); bool interruptDisable() { bool result = (inp(SREG) & 0x80) != 0; cli(); return result; } result_t interruptEnable() { sei(); return SUCCESS; } result_t postIncrementalMACInit() { computeMACBuffer.computeMACInitWaiting = TRUE; return SUCCESS; } result_t postIncrementalMAC(uint8_t incr_mac_start, uint8_t amount) { if(computeMACBuffer.computeMACWaiting) { computeMACBuffer.amount += amount; } else { computeMACBuffer.computeMACWaiting = TRUE; computeMACBuffer.position = incr_mac_start; computeMACBuffer.amount = amount; } return SUCCESS; } result_t postIncrementalMACFinish() { computeMACBuffer.finishMACWaiting = TRUE; return SUCCESS; } result_t postIncrementalDecryptInit() { decryptBuffer.decryptInitWaiting = TRUE; return SUCCESS; } result_t postIncrementalDecrypt(uint8_t incr_decrypt_start, uint8_t amount) { if(decryptBuffer.decryptWaiting) { decryptBuffer.amount += amount; } else { decryptBuffer.decryptWaiting = TRUE; decryptBuffer.position = incr_decrypt_start; decryptBuffer.amount = amount; } return SUCCESS; } result_t checkQueuedCrypto() { result_t result = SUCCESS; // crypto operation already in progress if(compute_mac_state == COMPUTE_MAC_BUSY || decrypt_state == DECRYPT_BUSY) return SUCCESS; if(computeMACBuffer.computeMACInitWaiting) { computeMACBuffer.computeMACInitWaiting = FALSE; result = rcombine(result,MACincrementalInit()); } if(computeMACBuffer.computeMACWaiting) { computeMACBuffer.computeMACWaiting = FALSE; result = rcombine(result,computeMACIncremental(computeMACBuffer.position, computeMACBuffer.amount)); } // check waiting state and finish up work if(computeMACBuffer.finishMACWaiting) { computeMACBuffer.finishMACWaiting = FALSE; result = rcombine(result,computeMACIncrementalFinish()); } if(decryptBuffer.decryptInitWaiting) { decryptBuffer.decryptInitWaiting = FALSE; result = rcombine(result,decryptIncrementalInit()); } if(decryptBuffer.decryptWaiting) { decryptBuffer.decryptWaiting = FALSE; if(decrypt_state == DECRYPT_INITIALIZED) { result = rcombine(result,decryptIncremental(decryptBuffer.position, decryptBuffer.amount)); } else if (decrypt_state == DECRYPT_IDLE) { result = rcombine(result,decryptIncrementalInit()); } else { return FAIL; } } return result; } // WARNING: this function makes assumptions about the stucture of TinySec_Msg! // Incremental MAC computation must be initialized before this is called. result_t decryptIncrementalInit() { uint8_t decrypt_iv[TINYSECM_MAX_BLOCK_SIZE]; int i; result_t result; uint16_t ivLengthRemaining = sizeof(ciphertext_rec_ptr->addr) + sizeof(ciphertext_rec_ptr->type) + sizeof(ciphertext_rec_ptr->length); if(decrypt_state != DECRYPT_IDLE || !initialized) return FAIL; decrypt_state = DECRYPT_BUSY; interruptEnable(); if(ivLengthRemaining > (blockSize - TINYSEC_IV_LENGTH)) ivLengthRemaining = blockSize - TINYSEC_IV_LENGTH; // copy current iv into cipher buffer iv field memcpy(decrypt_iv,ciphertext_rec_ptr->iv,TINYSEC_IV_LENGTH); // fill in remaining space with addr, AM type, and length memcpy(decrypt_iv+TINYSEC_IV_LENGTH,&(ciphertext_rec_ptr->addr), ivLengthRemaining); // zero out the rest of the iv for(i=ivLengthRemaining+TINYSEC_IV_LENGTH;i<blockSize;i++) { decrypt_iv[i] = 0; } // if less than one block, then use one block. // assumes buffer has been padded. if(recDataLength < blockSize) { result = call BlockCipherMode.initIncrementalDecrypt(&cipherModeContext, decrypt_iv, blockSize); dbg(DBG_CRYPTO,"DECRYPT: init size=%d\n",blockSize); } else { result = call BlockCipherMode.initIncrementalDecrypt(&cipherModeContext, decrypt_iv, recDataLength); dbg(DBG_CRYPTO,"DECRYPT: init size=%d\n",recDataLength); } interruptDisable(); decrypt_state = DECRYPT_INITIALIZED; result = rcombine(result,checkQueuedCrypto()); return result; } result_t decryptIncremental(uint8_t incr_decrypt_start, uint8_t amount) { result_t result; uint16_t done; if(!initialized) return FAIL; if(decrypt_state == DECRYPT_IDLE) { return FAIL; // error } else if(decrypt_state == DECRYPT_INITIALIZED) { decrypt_state = DECRYPT_BUSY; interruptEnable(); result = call BlockCipherMode.incrementalDecrypt( &cipherModeContext, (ciphertext_rec_ptr->enc)+incr_decrypt_start, cleartext_rec_ptr->data,amount, &done); interruptDisable(); decrypt_state = DECRYPT_INITIALIZED; if(recDataLength < blockSize) { if(done == blockSize) { decrypt_state = DECRYPT_IDLE; } } else { if(done == recDataLength) { decrypt_state = DECRYPT_IDLE; } } // shouldn't have any pending decrypts but if someone decides to reorder // mac computes and decrypts, we should keep this here (mac computes are // currently given priority) result = rcombine(result,checkQueuedCrypto()); return result; } else { return FAIL; // error } } result_t MACincrementalInit() { result_t result; if(compute_mac_state != COMPUTE_MAC_IDLE || !initialized) return FAIL; compute_mac_state = COMPUTE_MAC_BUSY; interruptEnable(); result = call MAC.initIncrementalMAC(&macContext,rxlength); dbg(DBG_CRYPTO,"MAC init called: rxlength=%d.\n",rxlength); interruptDisable(); compute_mac_state = COMPUTE_MAC_INITIALIZED; result = rcombine(result,checkQueuedCrypto()); return result; } result_t computeMACIncremental(uint8_t incr_mac_start, uint8_t amount) { if(!initialized) return FAIL; if(incr_mac_start >= TINYSEC_MSG_DATA_SIZE - TINYSEC_MAC_LENGTH) return FAIL; if(compute_mac_state == COMPUTE_MAC_IDLE) { return FAIL; // has not been initialized } 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->MACcomputed = 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->MACcomputed) { 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->MACcomputed = 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -