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++; } } }
/** * \brief AES-ECB block encryption/decryption * * \param ctx AES context * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT * \param input 16-byte input block * \param output 16-byte output block * * \return 0 if successful */ int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx, int mode, const unsigned char input[16], unsigned char output[16]) { int retval = 0; sal_aes_wrrd((uint8_t *)input, NULL); sal_aes_read((uint8_t *)output); return retval; }
/** * @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); }
/*************************************************************************//** *****************************************************************************/ 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); }
/** * @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++; } } }