Webserver+3d print

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers cipher_mode_cbc.c Source File

cipher_mode_cbc.c

Go to the documentation of this file.
00001 /**
00002  * @file cipher_mode_cbc.c
00003  * @brief Cipher Block Chaining (CBC) 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 Cipher Block Chaining (CBC) mode is a confidentiality mode whose
00028  * encryption process features the combining of the plaintext blocks with
00029  * the previous ciphertext blocks. The CBC mode requires an IV to combine
00030  * with the first plaintext block. 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_cbc.h"
00043 #include "debug.h"
00044 
00045 //Check crypto library configuration
00046 #if (CBC_SUPPORT == ENABLED)
00047 
00048 
00049 /**
00050  * @brief CBC encryption
00051  * @param[in] cipher Cipher algorithm
00052  * @param[in] context Cipher algorithm context
00053  * @param[in,out] iv Initialization vector
00054  * @param[in] p Plaintext to be encrypted
00055  * @param[out] c Ciphertext resulting from the encryption
00056  * @param[in] length Total number of data bytes to be encrypted
00057  * @return Error code
00058  **/
00059 
00060 error_t cbcEncrypt(const CipherAlgo *cipher, void *context,
00061    uint8_t *iv, const uint8_t *p, uint8_t *c, size_t length)
00062 {
00063    size_t i;
00064 
00065    //CBC mode operates in a block-by-block fashion
00066    while(length >= cipher->blockSize)
00067    {
00068       //XOR input block with IV contents
00069       for(i = 0; i < cipher->blockSize; i++)
00070          c[i] = p[i] ^ iv[i];
00071 
00072       //Encrypt the current block based upon the output
00073       //of the previous encryption
00074       cipher->encryptBlock(context, c, c);
00075 
00076       //Update IV with output block contents
00077       memcpy(iv, c, cipher->blockSize);
00078 
00079       //Next block
00080       p += cipher->blockSize;
00081       c += cipher->blockSize;
00082       length -= cipher->blockSize;
00083    }
00084 
00085    //The plaintext must be a multiple of the block size
00086    if(length != 0)
00087       return ERROR_INVALID_LENGTH;
00088 
00089    //Successful encryption
00090    return NO_ERROR;
00091 }
00092 
00093 
00094 /**
00095  * @brief CBC decryption
00096  * @param[in] cipher Cipher algorithm
00097  * @param[in] context Cipher algorithm context
00098  * @param[in,out] iv Initialization vector
00099  * @param[in] c Ciphertext to be decrypted
00100  * @param[out] p Plaintext resulting from the decryption
00101  * @param[in] length Total number of data bytes to be decrypted
00102  * @return Error code
00103  **/
00104 
00105 error_t cbcDecrypt(const CipherAlgo *cipher, void *context,
00106    uint8_t *iv, const uint8_t *c, uint8_t *p, size_t length)
00107 {
00108    size_t i;
00109    uint8_t t[16];
00110 
00111    //CBC mode operates in a block-by-block fashion
00112    while(length >= cipher->blockSize)
00113    {
00114       //Save input block
00115       memcpy(t, c, cipher->blockSize);
00116 
00117       //Decrypt the current block
00118       cipher->decryptBlock(context, c, p);
00119 
00120       //XOR output block with IV contents
00121       for(i = 0; i < cipher->blockSize; i++)
00122          p[i] ^= iv[i];
00123 
00124       //Update IV with input block contents
00125       memcpy(iv, t, cipher->blockSize);
00126 
00127       //Next block
00128       c += cipher->blockSize;
00129       p += cipher->blockSize;
00130       length -= cipher->blockSize;
00131    }
00132 
00133    //The ciphertext must be a multiple of the block size
00134    if(length != 0)
00135       return ERROR_INVALID_LENGTH;
00136 
00137    //Successful encryption
00138    return NO_ERROR;
00139 }
00140 
00141 #endif
00142