Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
cipher_mode_ctr.c
00001 /** 00002 * @file cipher_mode_ctr.c 00003 * @brief Counter(CTR) mode 00004 * 00005 * @section License 00006 * 00007 * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved. 00008 * 00009 * This file is part of CycloneCrypto Open. 00010 * 00011 * This program is free software; you can redistribute it and/or 00012 * modify it under the terms of the GNU General Public License 00013 * as published by the Free Software Foundation; either version 2 00014 * of the License, or (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License 00022 * along with this program; if not, write to the Free Software Foundation, 00023 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00024 * 00025 * @section Description 00026 * 00027 * The Counter (CTR) mode is a confidentiality mode that features the application 00028 * of the forward cipher to a set of input blocks, called counters, to produce 00029 * a sequence of output blocks that are exclusive-ORed with the plaintext to 00030 * produce the ciphertext, and vice versa. Refer to SP 800-38A for more details 00031 * 00032 * @author Oryx Embedded SARL (www.oryx-embedded.com) 00033 * @version 1.7.6 00034 **/ 00035 00036 //Switch to the appropriate trace level 00037 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL 00038 00039 //Dependencies 00040 #include <string.h> 00041 #include "crypto.h" 00042 #include "cipher_mode_ctr.h" 00043 #include "debug.h" 00044 00045 //Check crypto library configuration 00046 #if (CTR_SUPPORT == ENABLED) 00047 00048 00049 /** 00050 * @brief CTR encryption 00051 * @param[in] cipher Cipher algorithm 00052 * @param[in] context Cipher algorithm context 00053 * @param[in] m Size in bits of the specific part of the block to be incremented 00054 * @param[in,out] t Initial counter block 00055 * @param[in] p Plaintext to be encrypted 00056 * @param[out] c Ciphertext resulting from the encryption 00057 * @param[in] length Total number of data bytes to be encrypted 00058 * @return Error code 00059 **/ 00060 00061 error_t ctrEncrypt(const CipherAlgo *cipher, void *context, uint_t m, 00062 uint8_t *t, const uint8_t *p, uint8_t *c, size_t length) 00063 { 00064 size_t i; 00065 size_t n; 00066 uint8_t o[16]; 00067 00068 //The parameter must be a multiple of 8 00069 if(m % 8) 00070 return ERROR_INVALID_PARAMETER; 00071 00072 //Determine the size, in bytes, of the specific part of 00073 //the block to be incremented 00074 m = m / 8; 00075 00076 //Check the resulting value 00077 if(m > cipher->blockSize) 00078 return ERROR_INVALID_PARAMETER; 00079 00080 //Process plaintext 00081 while(length > 0) 00082 { 00083 //CTR mode operates in a block-by-block fashion 00084 n = MIN(length, cipher->blockSize); 00085 00086 //Compute O(j) = CIPH(T(j)) 00087 cipher->encryptBlock(context, t, o); 00088 00089 //Compute C(j) = P(j) XOR T(j) 00090 for(i = 0; i < n; i++) 00091 c[i] = p[i] ^ o[i]; 00092 00093 //Standard incrementing function 00094 for(i = 0; i < m; i++) 00095 { 00096 //Increment the current byte and propagate the carry if necessary 00097 if(++(t[cipher->blockSize - 1 - i]) != 0) 00098 break; 00099 } 00100 00101 //Next block 00102 p += n; 00103 c += n; 00104 length -= n; 00105 } 00106 00107 //Successful encryption 00108 return NO_ERROR; 00109 } 00110 00111 00112 /** 00113 * @brief CTR decryption 00114 * @param[in] cipher Cipher algorithm 00115 * @param[in] context Cipher algorithm context 00116 * @param[in] m Size in bits of the specific part of the block to be incremented 00117 * @param[in,out] t Initial counter block 00118 * @param[in] c Ciphertext to be decrypted 00119 * @param[out] p Plaintext resulting from the decryption 00120 * @param[in] length Total number of data bytes to be decrypted 00121 * @return Error code 00122 **/ 00123 00124 error_t ctrDecrypt(const CipherAlgo *cipher, void *context, uint_t m, 00125 uint8_t *t, const uint8_t *c, uint8_t *p, size_t length) 00126 { 00127 size_t i; 00128 size_t n; 00129 uint8_t o[16]; 00130 00131 //The parameter must be a multiple of 8 00132 if(m % 8) 00133 return ERROR_INVALID_PARAMETER; 00134 00135 //Determine the size, in bytes, of the specific part of 00136 //the block to be incremented 00137 m = m / 8; 00138 00139 //Check the resulting value 00140 if(m > cipher->blockSize) 00141 return ERROR_INVALID_PARAMETER; 00142 00143 //Process ciphertext 00144 while(length > 0) 00145 { 00146 //CTR mode operates in a block-by-block fashion 00147 n = MIN(length, cipher->blockSize); 00148 00149 //Compute O(j) = CIPH(T(j)) 00150 cipher->encryptBlock(context, t, o); 00151 00152 //Compute P(j) = C(j) XOR T(j) 00153 for(i = 0; i < n; i++) 00154 p[i] = c[i] ^ o[i]; 00155 00156 //Standard incrementing function 00157 for(i = 0; i < m; i++) 00158 { 00159 //Increment the current byte and propagate the carry if necessary 00160 if(++(t[cipher->blockSize - 1 - i]) != 0) 00161 break; 00162 } 00163 00164 //Next block 00165 c += n; 00166 p += n; 00167 length -= n; 00168 } 00169 00170 //Successful encryption 00171 return NO_ERROR; 00172 } 00173 00174 #endif 00175
Generated on Tue Jul 12 2022 17:10:12 by
1.7.2