diff options
Diffstat (limited to 'libopencm3/lib/stm32/common/crypto_common_f24.c')
-rw-r--r-- | libopencm3/lib/stm32/common/crypto_common_f24.c | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/libopencm3/lib/stm32/common/crypto_common_f24.c b/libopencm3/lib/stm32/common/crypto_common_f24.c new file mode 100644 index 0000000..46cef6b --- /dev/null +++ b/libopencm3/lib/stm32/common/crypto_common_f24.c @@ -0,0 +1,175 @@ +/** @addtogroup crypto_file + * + * @brief <b>libopencm3 STM32 Cryptographic controller</b> + * + * @version 1.0.0 + * + * @date 17 Jun 2013 + * + * This library supports the cryptographic coprocessor system for the + * STM32 series of ARM Cortex Microcontrollers + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Stephen Caudle <scaudle@doceme.com> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +/**@{*/ + +#include <libopencm3/stm32/crypto.h> + +#define CRYP_CR_ALGOMODE_MASK ((1 << 19) | CRYP_CR_ALGOMODE) + +/** + * @brief Wait, if the Controller is busy + */ +void crypto_wait_busy(void) +{ + while (CRYP_SR & CRYP_SR_BUSY); +} + +/** + * @brief Set key value to the controller + * @param[in] keysize enum crypto_keysize Specified size of the key. + * @param[in] key uint64_t[] Key value (array of 4 items) + */ +void crypto_set_key(enum crypto_keysize keysize, uint64_t key[]) +{ + int i; + + crypto_wait_busy(); + + CRYP_CR = (CRYP_CR & ~CRYP_CR_KEYSIZE) | + (keysize << CRYP_CR_KEYSIZE_SHIFT); + + for (i = 0; i < 4; i++) { + CRYP_KR(i) = key[i]; + } +} + +/** + * @brief Set Initialization Vector + * + * @param[in] iv uint64_t[] Initialization vector (array of 4 items) + + * @note Cryptographic controller must be in disabled state + */ +void crypto_set_iv(uint64_t iv[]) +{ + int i; + + crypto_wait_busy(); + + for (i = 0; i < 4; i++) { + CRYP_IVR(i) = iv[i]; + } +} + +/** + * @brief Set the order of the data to be crypted + * + * @param[in] datatype enum crypto_datatype Specified datatype of the key. + */ +void crypto_set_datatype(enum crypto_datatype datatype) +{ + CRYP_CR = (CRYP_CR & ~CRYP_CR_DATATYPE) | + (datatype << CRYP_CR_DATATYPE_SHIFT); +} + +/** + * @brief Set the algoritm for Encryption/decryption + * + *@param[in] mode enum crypto_mode Mode of execution + */ +void crypto_set_algorithm(enum crypto_mode mode) +{ + mode &= ~CRYP_CR_ALGOMODE_MASK; + + if ((mode == DECRYPT_AES_ECB) || (mode == DECRYPT_AES_CBC)) { + /* Unroll keys for the AES encoder for the user automatically */ + + CRYP_CR = (CRYP_CR & ~CRYP_CR_ALGOMODE_MASK) | + CRYP_CR_ALGOMODE_AES_PREP; + + crypto_start(); + crypto_wait_busy(); + /* module switches to DISABLE automatically */ + } + /* set algo mode */ + CRYP_CR = (CRYP_CR & ~CRYP_CR_ALGOMODE_MASK) | mode; + + /* flush buffers */ + CRYP_CR |= CRYP_CR_FFLUSH; +} + +/** + * @brief Enable the cryptographic controller and start processing + */ +void crypto_start(void) +{ + CRYP_CR |= CRYP_CR_CRYPEN; +} + +/** + * @brief Disable the cryptographic controller and stop processing + */ + +void crypto_stop(void) +{ + CRYP_CR &= ~CRYP_CR_CRYPEN; +} + +/** + * @brief Start of encryption or decryption on data buffers + * + * This blocking method transfers input buffer of specified length to the + * cryptographic coprocessor, and instructs him to begin of ciphering or + * deciphering. It waits for data to be ready, and then fills the processed + * data to output buffer. + * + * @param[in] inp uint32_t* Input array to crypt/decrypt. + * @param[in] outp uint32_t* Output array with crypted/encrypted data. + * @param[in] length uint32_t Length of the arrays + * + * @returns uint32_t Number of written words + */ +uint32_t crypto_process_block(uint32_t *inp, uint32_t *outp, uint32_t length) +{ + uint32_t rd = 0, wr = 0; + + /* Transfer the data */ + while (rd != length) { + if ((wr < length) && (CRYP_SR & CRYP_SR_IFNF)) { + CRYP_DIN = *inp++; + wr++; + } + + if (CRYP_SR & CRYP_SR_OFNE) { + *outp++ = CRYP_DOUT; + rd++; + } + } + + /* Wait to finish - Not needed ? */ + crypto_wait_busy(); + + return wr; +} + +/**@}*/ |