Sergey Pastor / 1

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers cipher_mode_ctr.c Source File

cipher_mode_ctr.c

Go to the documentation of this file.
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