Exemplo n.º 1
0
/**
 * @brief Computes MIC
 *
 * This function computes the MIC according to CCM.
 *
 * The key was initialized in other functions before.
 *
 * @param[in]  buffer  Input data (frame, not padded yet)
 * @param[out] mic     Computed MIC of size AES_BLOCKSIZE
 * @param[in]  nonce   The nonce: Initialization Vector (IV) as used in
 *                     cryptography; the ZigBee nonce are the bytes 2...14
 *                     of this nonce
 * @param[in]  hdr_len  Size of plain text header in bytes (may be 0)
 * @param[in]  pld_len Length of payload in bytes (may be 0)
 */
void compute_mic(uint8_t *buffer,
		uint8_t *mic,
		uint8_t *nonce,
		uint8_t hdr_len,
		uint8_t pld_len)
{
	sal_aes_setup(NULL, AES_MODE_ECB, AES_DIR_ENCRYPT);
#if (SAL_TYPE == AT86RF2xx)
	sal_aes_wrrd(nonce, NULL);
#else
	sal_aes_exec(nonce);
#endif
	sal_aes_setup(NULL, AES_MODE_CBC, AES_DIR_ENCRYPT);

	if (hdr_len) {
		uint8_t locbuf[AES_BLOCKSIZE];
		uint8_t firstlen;

		firstlen = MIN(AES_BLOCKSIZE - 2, hdr_len);

		/* Prepend L(a). */
		locbuf[0] = 0;
		locbuf[1] = hdr_len;
		memcpy(locbuf + 2, buffer, firstlen);

		encrypt_with_padding(locbuf, firstlen + 2);

		if (firstlen < hdr_len) {
			/* No padding up to now since firstlen is AES_BLOCKSIZE
			 *- 2. */
			encrypt_with_padding(buffer + firstlen,
					hdr_len - firstlen);
		}
	}

	encrypt_with_padding(buffer + hdr_len, pld_len);

	sal_aes_read(mic);
}
Exemplo n.º 2
0
void encrypt_pldmic(uint8_t *buffer,
		uint8_t *nonce,
		uint8_t mic_len,
		uint8_t pld_len)
{
	uint8_t ctr;
	uint8_t i;
	uint8_t keystream[AES_BLOCKSIZE];
	uint8_t *keystreamptr;
	int spld_len;

	spld_len = (int)pld_len; /* max. value: 0x7f */

	sal_aes_setup(NULL, AES_MODE_ECB, AES_DIR_ENCRYPT);

	ctr = 0;

	while (spld_len > 0) {
		/* Compute the keystream block. */
		nonce[AES_BLOCKSIZE - 1] = ++ctr;
		sal_aes_exec(nonce);
		sal_aes_read(keystream);

		/* En/decrypt payload. */

		for (i = MIN(spld_len, AES_BLOCKSIZE), keystreamptr = keystream;
				i--;
		                /* */) {
			*buffer++ ^= *keystreamptr++;
		}

		spld_len -= AES_BLOCKSIZE;
	}

	/* En/decrypt MIC. */

	if (mic_len) {
		/* Prepare the keystream for MIC. */
		nonce[AES_BLOCKSIZE - 1] = 0;
		sal_aes_exec(nonce);
		sal_aes_read(keystream);

		for (i = mic_len, keystreamptr = keystream; i--; /* */) {
			*buffer++ ^= *keystreamptr++;
		}
	}
}
Exemplo n.º 3
0
int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits)
{
    int retval = 0;

    switch (keybits)
    {
    case 128:
        sal_aes_setup((uint8_t *)key, AES_MODE_ECB, AES_DIR_DECRYPT);
        break;

    default:
        retval = MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
        break;
    }

    return retval;
}
Exemplo n.º 4
0
void sal_aes_dec_key(uint8_t dir)
{
	uint8_t i;
	if(dir==AES_DIR_ENCRYPT)
	{
		aes_buf[0]=AES_MODE_KEY;
		for(i=1;i<AES_KEYSIZE;i++)
		{
			aes_buf[i]=0x00;
		}
		 hal_sram_write(AES_CON, AES_BLOCKSIZE+1, aes_buf);
		 hal_sram_read(AES_STATE_KEY, AES_KEYSIZE, dec_key);
		 setup_flag = true;
	}
	else if((dir==AES_DIR_DECRYPT)&&setup_flag)
	{
		sal_aes_setup(dec_key);
		setup_flag=false;
	}
}
Exemplo n.º 5
0
/*************************************************************************//**
*****************************************************************************/
void PHY_EncryptReq(uint8_t *text, uint8_t *key)
{
	sal_aes_setup(key, AES_MODE_ECB, AES_DIR_ENCRYPT);
	sal_aes_exec(text);
	sal_aes_read(text);
}
Exemplo n.º 6
0
/**
 * @brief Secure one block with CCM*
 *
 * This functions secures one block with CCM* according to 802.15.4.
 *
 * @param[in,out] buffer Input: plaintext header and payload concatenated;
 *                       for encryption: MUST HAVE 'AES_BLOCKSIZE'
 *                       BYTES SPACE AT THE END FOR THE MIC!
 *                       Output: frame secured (with MIC at end)/unsecured
 * @param[in]  nonce   The nonce: Initialization Vector (IV) as used in
 *                     cryptography; the ZigBee nonce (13 bytes long)
 *                     are the bytes 2...14 of this nonce
 * @param[in] key The key to be used; if NULL, use the current key
 * @param[in] hdr_len Length of plaintext header (will not be encrypted)
 * @param[in] pld_len Length of payload to be encrypted; if 0, then only MIC
 *                    authentication implies
 * @param[in] sec_level Security level according to IEEE 802.15.4,
 *                    7.6.2.2.1, Table 95:
 *                    - the value may be 0 ... 7;
 *                    - the two LSBs contain the MIC length in bytes
 *                      (0, 4, 8 or 16);
 *                    - bit 2 indicates whether encryption applies or not
 * @param[in] aes_dir AES_DIR_ENCRYPT if secure, AES_DIR_DECRYPT if unsecure
 *
 * @return STB CCM Status
 */
stb_ccm_t stb_ccm_secure(uint8_t *buffer,
                         uint8_t nonce[AES_BLOCKSIZE],
                                 uint8_t *key,
                         uint8_t hdr_len,
                         uint8_t pld_len,
                         uint8_t sec_level,
                         uint8_t aes_dir)
{
    uint8_t nonce_0;    /* nonce[0] for MIC computation. */
    uint8_t mic_len;
    uint8_t enc_flag;

    if (stb_restart_required)
    {
        sal_aes_restart();
        stb_restart_required = false;
    }

    if (sec_level & 3)
    {
        mic_len = 1 << ((sec_level & 3) + 1);
    }
    else
    {
        mic_len = 0;
    }

    enc_flag = sec_level & 4;

    /* Test on correct parameters. */

    if ((sec_level & ~0x7) ||
        (buffer == NULL) ||
        (nonce == NULL) ||
        ((uint16_t)pld_len + (uint16_t)hdr_len + (uint16_t)mic_len > aMaxPHYPacketSize)
       )
    {
        sal_aes_clean_up();
        return (STB_CCM_ILLPARM);
    }

    if (key_change && (key == NULL))
    {
        sal_aes_clean_up();
        return (STB_CCM_KEYMISS);   /* Initial call, but no key given. */
    }

    /* Setup key if necessary. */

    if(!key_change && key != NULL)    /* There was some previous key. */
    {
        uint8_t i;

        /* Test on changed key. */
        for (i = AES_BLOCKSIZE; i--; /* */)
        {
            key_change |= (last_key[i] ^ key[i]);
        }
    }

    if (key_change)
    {
        /*
         * Key must be non-NULL because of test above, and
         * ECB encryption is always the initial encryption mode.
         */
        sal_aes_setup(key, AES_MODE_ECB, AES_DIR_ENCRYPT);
        memcpy(last_key, key, AES_KEYSIZE);
        key_change = false;
    }

    /* Prepare nonce. */

    nonce[0] = 1;   /* Always 2 bytes for length field. */

    if (mic_len > 0)
    {
        nonce[0] |= ((mic_len - 2) >> 1) << 3;
    }
Exemplo n.º 7
0
/**
 * @brief Encrypts and decrypts payload and MIC
 *
 * This function perform encryption and decryption of the payload and the MIC.
 *
 * @param[in]  buffer  Input data (frame, not padded yet)
 * @param[in]  nonce   The nonce
 * @param[in]  mic_len  Size of MIC in bytes (may be 0)
 * @param[in]  pld_len Length of payload in bytes (may be 0)
 */
void encrypt_pldmic(uint8_t *buffer,
		uint8_t *nonce,
		uint8_t mic_len,
		uint8_t pld_len)
{
	uint8_t ctr;
	uint8_t i;
	uint8_t keystream[AES_BLOCKSIZE];
	uint8_t *keystreamptr;

	sal_aes_setup(NULL, AES_MODE_ECB, AES_DIR_ENCRYPT);

	/* Init first keystream block. */
	nonce[AES_BLOCKSIZE - 1] = ctr = 1;

	if (pld_len > 0) {
		sal_aes_wrrd(nonce, NULL);
	}

	while (true) {
		/* Compute next keystream block and get the previous one. */
		if (pld_len <= AES_BLOCKSIZE) { /* Last block */
			if (mic_len) {
				/* Prepare the keystream for MIC. */
				nonce[AES_BLOCKSIZE - 1] = 0;

				sal_aes_wrrd(nonce, keystream);
			} else {
				sal_aes_read(keystream);
			}
		} else {
			/* Prepare the next keystream block. */
			nonce[AES_BLOCKSIZE - 1] = ++ctr;

			sal_aes_wrrd(nonce, keystream);
		}

		/* En/decrypt payload. */

		for (i = MIN(pld_len, AES_BLOCKSIZE), keystreamptr = keystream;
				i--;
		                /* */) {
			*buffer++ ^= *keystreamptr++;
		}

		if (pld_len <= AES_BLOCKSIZE) {
			break;
		}

		pld_len -= AES_BLOCKSIZE;
	}

	/* En/decrypt MIC. */

	if (mic_len) {
		sal_aes_read(keystream);

		for (i = mic_len, keystreamptr = keystream; i--; /* */) {
			*buffer++ ^= *keystreamptr++;
		}
	}
}
Exemplo n.º 8
0
/**
 * @brief Secure one block with CCM*
 *
 * This functions secures one block with CCM* according to 802.15.4.
 *
 * @param[in,out] buffer Input: plaintext header and payload concatenated;
 *                       for encryption: MUST HAVE 'AES_BLOCKSIZE'
 *                       BYTES SPACE AT THE END FOR THE MIC!
 *                       Output: frame secured (with MIC at end)/unsecured
 * @param[in]  nonce   The nonce: Initialization Vector (IV) as used in
 *                     cryptography; the ZigBee nonce (13 bytes long)
 *                     are the bytes 2...14 of this nonce
 * @param[in] key The key to be used; if NULL, use the current key
 * @param[in] hdr_len Length of plain text header (will not be encrypted)
 * @param[in] pld_len Length of payload to be encrypted; if 0, then only MIC
 *                    authentication implies
 * @param[in] sec_level Security level according to IEEE 802.15.4,
 *                    7.6.2.2.1, Table 95:
 *                    - the value may be 0 ... 7;
 *                    - the two LSBs contain the MIC length in bytes
 *                      (0, 4, 8 or 16);
 *                    - bit 2 indicates whether encryption applies or not
 * @param[in] aes_dir AES_DIR_ENCRYPT if secure, AES_DIR_DECRYPT if unsecured
 *
 * @return STB CCM Status
 */
stb_ccm_t stb_ccm_secure(uint8_t *buffer,
		uint8_t nonce[AES_BLOCKSIZE],
		uint8_t *key,
		uint8_t hdr_len,
		uint8_t pld_len,
		uint8_t sec_level,
		uint8_t aes_dir)
{
	uint8_t nonce_0; /* nonce[0] for MIC computation. */
	uint8_t mic_len = 0;
	uint8_t enc_flag = ENCRYPTION_NOT_REQD;

	if (stb_restart_required) {
#if (SAL_TYPE != ATXMEGA_SAL)
		prev_trx_status = tal_trx_status;
		if (tal_trx_status == TRX_SLEEP) {
			tal_trx_wakeup();
		}
#endif
		sal_aes_restart();
		stb_restart_required = false;
	}

	switch (sec_level) {
	case SECURITY_00_LEVEL:
		/* No MIC & No Encryption at Security Level -0 */
		mic_len = LEN_MIC_00;
		break;

	case SECURITY_01_LEVEL:
		/* MIC-32 & No Encryption at Security Level -1 */
		mic_len = LEN_MIC_32;
		break;

	case SECURITY_02_LEVEL:
		/* MIC-64 & No Encryption at Security Level -2 */
		mic_len = LEN_MIC_64;
		break;

	case SECURITY_03_LEVEL:
		/* MIC-128 & No Encryption at Security Level -3 */
		mic_len = LEN_MIC_128;
		break;

	case SECURITY_04_LEVEL:
		/* No MIC & Encryption at Security Level -4 */
		mic_len = LEN_MIC_00;
		enc_flag = ENCRYPTION_REQD;
		break;

	case SECURITY_05_LEVEL:
		/* MIC-32 & Encryption at Security Level -5 */
		mic_len = LEN_MIC_32;
		enc_flag = ENCRYPTION_REQD;
		break;

	case SECURITY_06_LEVEL:
		/* MIC-64 & Encryption at Security Level -6 */
		mic_len = LEN_MIC_64;
		enc_flag = ENCRYPTION_REQD;
		break;

	case SECURITY_07_LEVEL:
		/* MIC-128 & Encryption at Security Level -7 */
		mic_len = LEN_MIC_128;
		enc_flag = ENCRYPTION_REQD;
		break;

	default:
		break;
	}

	/* Test on correct parameters. */

	if ((sec_level & ~0x7) ||
			(buffer == NULL) ||
			(nonce == NULL) ||
			((uint16_t)pld_len + (uint16_t)hdr_len +
			(uint16_t)mic_len > aMaxPHYPacketSize)
			) {
#if (SAL_TYPE != ATXMEGA_SAL)
		TRX_SLEEP();
		sal_aes_clean_up();
#endif
		return (STB_CCM_ILLPARM);
	}

	if (key_change && (key == NULL)) {
#if (SAL_TYPE != ATXMEGA_SAL)
		TRX_SLEEP();
		sal_aes_clean_up();
#endif
		/* Initial call, but no key given. */
		return (STB_CCM_KEYMISS);
	}

	/* Setup key if necessary. */

	if (!key_change && key != NULL) { /* There was some previous key. */
		uint8_t i;

		/* Test on changed key. */
		for (i = AES_BLOCKSIZE; i--; /* */) {
			key_change |= (last_key[i] ^ key[i]);
		}
	}

	if (key_change) {
		/*
		 * Key must be non-NULL because of test above, and
		 * ECB encryption is always the initial encryption mode.
		 */
		sal_aes_setup(key, AES_MODE_ECB, AES_DIR_ENCRYPT);
		memcpy(last_key, key, AES_KEYSIZE);
		key_change = false;
	}

	/* Prepare nonce. */
	nonce[0] = LEN_FIELD; /* Always 2 bytes for length field. */

	if (mic_len > 0) {
		nonce[0] |= (uint8_t)(((mic_len - 2) >> 1) << 3);
	}