Webserver+3d print

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers cipher_mode_cfb.c Source File

cipher_mode_cfb.c

Go to the documentation of this file.
00001 /**
00002  * @file cipher_mode_cfb.c
00003  * @brief Cipher Feedback (CFB) 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 Feedback (CFB) mode is a confidentiality mode that features the
00028  * feedback of successive ciphertext segments into the input blocks of the
00029  * forward cipher to generate output blocks that are exclusive-ORed with the
00030  * plaintext to produce the ciphertext, and vice versa. The CFB mode requires
00031  * an IV as the initial input block. The IV need not be secret, but it must be
00032  * unpredictable. Refer to SP 800-38A for more details
00033  *
00034  * @author Oryx Embedded SARL (www.oryx-embedded.com)
00035  * @version 1.7.6
00036  **/
00037 
00038 //Switch to the appropriate trace level
00039 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
00040 
00041 //Dependencies
00042 #include <string.h>
00043 #include "crypto.h"
00044 #include "cipher_mode_cfb.h"
00045 #include "debug.h"
00046 
00047 //Check crypto library configuration
00048 #if (CFB_SUPPORT == ENABLED)
00049 
00050 
00051 /**
00052  * @brief CFB encryption
00053  * @param[in] cipher Cipher algorithm
00054  * @param[in] context Cipher algorithm context
00055  * @param[in] s Size of the plaintext and ciphertext segments
00056  * @param[in,out] iv Initialization vector
00057  * @param[in] p Plaintext to be encrypted
00058  * @param[out] c Ciphertext resulting from the encryption
00059  * @param[in] length Total number of data bytes to be encrypted
00060  * @return Error code
00061  **/
00062 
00063 error_t cfbEncrypt(const CipherAlgo *cipher, void *context, uint_t s,
00064    uint8_t *iv, const uint8_t *p, uint8_t *c, size_t length)
00065 {
00066    size_t i;
00067    size_t n;
00068    uint8_t o[16];
00069 
00070    //The parameter must be a multiple of 8
00071    if(s % 8)
00072       return ERROR_INVALID_PARAMETER;
00073 
00074    //Determine the size, in bytes, of the plaintext and ciphertext segments
00075    s = s / 8;
00076 
00077    //Check the resulting value
00078    if(s < 1 || s > cipher->blockSize)
00079       return ERROR_INVALID_PARAMETER;
00080 
00081    //Process each plaintext segment
00082    while(length > 0)
00083    {
00084       //Compute the number of bytes to process at a time
00085       n = MIN(length, s);
00086 
00087       //Compute O(j) = CIPH(I(j))
00088       cipher->encryptBlock(context, iv, o);
00089 
00090       //Compute C(j) = P(j) XOR MSB(O(j))
00091       for(i = 0; i < n; i++)
00092          c[i] = p[i] ^ o[i];
00093 
00094       //Compute I(j+1) = LSB(I(j)) | C(j)
00095       memmove(iv, iv + s, cipher->blockSize - s);
00096       memcpy(iv + cipher->blockSize - s, c, s);
00097 
00098       //Next block
00099       p += n;
00100       c += n;
00101       length -= n;
00102    }
00103 
00104    //Successful encryption
00105    return NO_ERROR;
00106 }
00107 
00108 
00109 /**
00110  * @brief CFB decryption
00111  * @param[in] cipher Cipher algorithm
00112  * @param[in] context Cipher algorithm context
00113  * @param[in] s Size of the plaintext and ciphertext segments
00114  * @param[in,out] iv Initialization vector
00115  * @param[in] c Ciphertext to be decrypted
00116  * @param[out] p Plaintext resulting from the decryption
00117  * @param[in] length Total number of data bytes to be decrypted
00118  * @return Error code
00119  **/
00120 
00121 error_t cfbDecrypt(const CipherAlgo *cipher, void *context, uint_t s,
00122    uint8_t *iv, const uint8_t *c, uint8_t *p, size_t length)
00123 {
00124    size_t i;
00125    size_t n;
00126    uint8_t o[16];
00127 
00128    //The parameter must be a multiple of 8
00129    if(s % 8)
00130       return ERROR_INVALID_PARAMETER;
00131 
00132    //Determine the size, in bytes, of the plaintext and ciphertext segments
00133    s = s / 8;
00134 
00135    //Check the resulting value
00136    if(s < 1 || s > cipher->blockSize)
00137       return ERROR_INVALID_PARAMETER;
00138 
00139    //Process each ciphertext segment
00140    while(length > 0)
00141    {
00142       //Compute the number of bytes to process at a time
00143       n = MIN(length, s);
00144 
00145       //Compute O(j) = CIPH(I(j))
00146       cipher->encryptBlock(context, iv, o);
00147 
00148       //Compute I(j+1) = LSB(I(j)) | C(j)
00149       memmove(iv, iv + s, cipher->blockSize - s);
00150       memcpy(iv + cipher->blockSize - s, c, s);
00151 
00152       //Compute P(j) = C(j) XOR MSB(O(j))
00153       for(i = 0; i < n; i++)
00154          p[i] = c[i] ^ o[i];
00155 
00156       //Next block
00157       c += n;
00158       p += n;
00159       length -= n;
00160    }
00161 
00162    //Successful encryption
00163    return NO_ERROR;
00164 }
00165 
00166 #endif
00167