コード例 #1
0
/**
 * @brief CBC Encrypt data stream with null padding at the end.
 *
 * This function preforms CBC Encryption in the actual mode with actual key
 * and portions of AES_BLOCKSIZE length.
 * If the last block has less than AES_BLOCKSIZE bytes, it is padded with
 * null bytes to this length and then encrypted.
 *
 * No result is return; the CBC-MAC must be read separately.
 *
 * @param start Pointer to start address
 * @param buflen Number of bytes to be encrypted; if 0, nothing happens
 */
void encrypt_with_padding(uint8_t *start, uint8_t buflen)
{
	/* Encrypt the "full blocks". */
	while (buflen >= AES_BLOCKSIZE) {
#if (SAL_TYPE == AT86RF2xx)
		sal_aes_wrrd(start, NULL);
#else
		sal_aes_exec(start);
#endif
		start += AES_BLOCKSIZE;
		buflen -= AES_BLOCKSIZE;
	}

	/* Pad the possible rest and encrypt it. */
	if (buflen) {
		uint8_t locbuf[AES_BLOCKSIZE];

		memcpy(locbuf, start, buflen);
		memset(locbuf + buflen, 0, AES_BLOCKSIZE - buflen);
#if (SAL_TYPE == AT86RF2xx)
		sal_aes_wrrd(locbuf, NULL);
#else
		sal_aes_exec(locbuf);
#endif
	}
}
コード例 #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++;
		}
	}
}
コード例 #3
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);
}
コード例 #4
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);
}
コード例 #5
0
ファイル: sal.c プロジェクト: AndreyMostovov/asf
/**
 * @brief Setup AES unit
 *
 * This function performs the following tasks as part of the setup of the
 * AES unit: key initialization, set encryption direction and encryption mode.
 *
 * In general, the contents of SRAM buffer is destroyed. When using
 * sal_aes_wrrd(), sal_aes_read() needs to be called in order to get the result
 * of the last AES operation before you may call sal_aes_setup() again.
 *
 * @param[in] key AES key or NULL (NULL: use last key)
 * @param[in] enc_mode  AES_MODE_ECB or AES_MODE_CBC
 * @param[in] dir AES_DIR_ENCRYPT or AES_DIR_DECRYPT
 *
 * @return  False if some parameter was illegal, true else
 */
bool sal_aes_setup(uint8_t *key,
		uint8_t enc_mode,
		uint8_t dir)
{
	uint8_t i;

	/* Init mode_byte: AES low-level interrupt and autostart enabled */

	mode_byte = COMP_SR(AES_INTLVL0, 1) | COMP_SR(AES_AUTO, 1);

	if (key != NULL) {
		/* Setup for new key. */
		dec_initialized = false;

		last_dir = AES_DIR_VOID;

		/* Save key for later use after decryption or sleep. */
		memcpy(enc_key, key, AES_KEYSIZE);

		keyp = enc_key;
	}

	/* Set encryption direction. */
	switch (dir) {
	case AES_DIR_ENCRYPT:
		if (last_dir == AES_DIR_DECRYPT) {
			/*
			 * If the last operation was decryption, the encryption
			 * key must be stored in enc_key, so re-initialize it.
			 */
			keyp = enc_key;
		}

		break;

	case AES_DIR_DECRYPT:
		if (last_dir != AES_DIR_DECRYPT) {
			if (!dec_initialized) {
				uint8_t dummy[AES_BLOCKSIZE];

				/* Compute decryption key. */

				/* Dummy ECB encryption. */
				AES_CTRL = mode_byte;

				keyp = enc_key;
				sal_aes_exec(dummy);

				/* Read last round key. */
				for (i = 0; i < AES_BLOCKSIZE; ++i) {
					dec_key[i] = AES_KEY;
				}

				dec_initialized = true;
			}

			keyp = dec_key;
		}

		break;

	default:
		return false;
	}

	last_dir = dir;

	/* Set encryption mode and direction. */
	switch (enc_mode) {
	case AES_MODE_ECB:
	case AES_MODE_CBC:
	{
		uint8_t xorflag;
		uint8_t dirflag = 0;

		xorflag = (enc_mode == AES_MODE_CBC);
		dirflag = (dir == AES_DIR_DECRYPT);

		mode_byte
			|= COMP_SR(AES_XOR, xorflag) | COMP_SR(AES_DECRYPT,
				dirflag);
		AES_CTRL = mode_byte;
	}
	break;

	default:
		return (false);
	}

	return (true);
}