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

📄 tinysecm.nc

📁 传感器网络中的嵌入式操作系统源代码
💻 NC
📖 第 1 页 / 共 2 页
字号:
// $Id: TinySecM.nc,v 1.1.2.5 2003/08/26 09:08:14 cssharp Exp $/*									tab:4 * "Copyright (c) 2000-2003 The Regents of the University  of California.   * All rights reserved. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose, without fee, and without written agreement is * hereby granted, provided that the above copyright notice, the following * two paragraphs and the author appear in all copies of this software. *  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." * * Copyright (c) 2002-2003 Intel Corporation * All rights reserved. * * This file is distributed under the terms in the attached INTEL-LICENSE      * file. If you do not find these files, copies can be found by writing to * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA,  * 94704.  Attention:  Intel License Inquiry. *//* Authors: Chris Karlof * Date:    8/1/03 *//** * @author Chris Karlof */module TinySecM{  provides {    interface TinySec;    interface TinySecControl;  }  uses {    interface BlockCipherMode;    interface MAC;    interface Random;    interface BlockCipherInfo;    interface TinySecRadio;    interface Leds;  }}implementation{  bool initialized;   enum {    // we allocate some static buffers on the stack; they have to be less    // than this size    TINYSECM_MAX_BLOCK_SIZE = 16,    COMPUTE_MAC_IDLE, // no verify in progress    COMPUTE_MAC_INITIALIZED, // verify has been initialized and                             //ready for incremental computation    COMPUTE_MAC_BUSY, // verify in the middle of incremental computation    DECRYPT_IDLE, // no decrypt in progress    DECRYPT_INITIALIZED, // decrypt has been initialized and                         //is ready for incremental decryption    DECRYPT_BUSY }; // incremental decrypt in progress  int16_t txlength = 0;  int16_t rxlength = 0;  bool txencrypt = TRUE;  bool rxdecrypt = TRUE;    int16_t TxByteCnt = 0;  int16_t RxByteCnt = 0;  int16_t recDataLength = 0;  int16_t sendDataLength = 0;    uint8_t compute_mac_state;  uint8_t decrypt_state;  uint8_t blockSize;  // buffer for posting mac opration for receive  struct computeMACBuffer {    bool computeMACWaiting;    bool computeMACInitWaiting;    uint8_t position;    uint8_t amount;    bool finishMACWaiting;  } computeMACBuffer;  // buffer for posting decrypt operations on receive  struct decryptBuffer {    bool decryptWaiting;    bool decryptInitWaiting;    uint8_t position;    uint8_t amount;  } decryptBuffer;  CipherModeContext cipherModeContext;  MACContext macContext;  uint8_t iv[TINYSECM_MAX_BLOCK_SIZE];  // TinySec buffers  TinySec_Msg tinysec_rec_buffer;  TinySec_Msg tinysec_send_buffer;  TinySec_Msg* ciphertext_send_ptr;  TinySec_Msg* ciphertext_rec_ptr;  TOS_Msg_TinySecCompat* cleartext_send_ptr;  TOS_Msg_TinySecCompat* cleartext_rec_ptr;  bool test_state = FALSE;    /**   * Initializes TinySec. BlockCipherMode and MAC contexts are initialized    * with respective keys, key size, and block size.   *   * @param blockSize block size of the block cipher in bytes   * @param keySize key size of the block cipher in bytes   * @param encryptionKey pointer to an array of keySize bytes    *        representing the key used for encryption   * @param MACKey pointer to an array of keySize bytes    *        representing the key used for calculating MAC's   * @return Whether TinySec initialization was successful. Reasons    *         for failure include BlockCipherMode or MAC init()   */  command result_t TinySecControl.init(uint8_t keySize,				       uint8_t * encryptionKey,				       uint8_t * MACKey) {    result_t r1, r2, r3, r4;    int i, local_addr;    uint8_t tmp = call BlockCipherInfo.getPreferredBlockSize();    atomic {      if(tmp > TINYSECM_MAX_BLOCK_SIZE) {	blockSize = 0;	r3 = FAIL;      }      else {	blockSize = tmp;	r3 = SUCCESS;      }          computeMACBuffer.computeMACWaiting = FALSE;      computeMACBuffer.computeMACInitWaiting = FALSE;      compute_mac_state = COMPUTE_MAC_IDLE;      decrypt_state = DECRYPT_IDLE;      decryptBuffer.decryptWaiting = FALSE;      decryptBuffer.decryptInitWaiting = FALSE;            computeMACBuffer.finishMACWaiting = FALSE;          // FIXME: replace this with EEPROM read or random IV      // since IV is reset on reboots, this is bad      for(i=0;i<blockSize;i++) {	iv[i] = 0;      }      if(TINYSEC_IV_LENGTH < TINYSEC_NODE_ID_SIZE)	r4 = FAIL;      else	r4 = SUCCESS;      // write the source address into the 3rd and 4th bytes of iv      local_addr = TOS_LOCAL_ADDRESS;      iv[TINYSEC_IV_LENGTH-TINYSEC_NODE_ID_SIZE] = local_addr & 0xff;      for(i=1;i<TINYSEC_NODE_ID_SIZE;i++) {	local_addr = local_addr >> 8;	iv[TINYSEC_IV_LENGTH-TINYSEC_NODE_ID_SIZE+i] = local_addr & 0xff;      }    }    r1 = call BlockCipherMode.init(&cipherModeContext,keySize,encryptionKey);    r2 = call MAC.init(&macContext,keySize,MACKey);    if(rcombine(rcombine(r1,r2),rcombine(r3,r4)) == FAIL)      return FAIL;    else {      atomic {	initialized = TRUE;      }      return SUCCESS;    }  }  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.position += 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);    test_state = FALSE;    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

⌨️ 快捷键说明

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