Webserver+3d print

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers cipher_mode_ofb.c Source File

cipher_mode_ofb.c

Go to the documentation of this file.
00001 /**
00002  * @file cipher_mode_ofb.c
00003  * @brief Output Feedback (OFB) 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 Output Feedback (OFB) mode is a confidentiality mode that features the
00028  * iteration of the forward cipher on an IV to generate a sequence of output
00029  * blocks that are exclusive-ORed with the plaintext to produce the ciphertext,
00030  * and vice versa. The OFB mode requires that the IV is a nonce, i.e., the IV
00031  * must be unique for each execution of the mode under the given key.
00032  * 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_ofb.h"
00045 #include "debug.h"
00046 
00047 //Check crypto library configuration
00048 #if (OFB_SUPPORT == ENABLED)
00049 
00050 
00051 /**
00052  * @brief OFB 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 ofbEncrypt(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    uint8_t o[16];
00068 
00069    //The parameter must be a multiple of 8
00070    if(s % 8)
00071       return ERROR_INVALID_PARAMETER;
00072 
00073    //Determine the size, in bytes, of the plaintext and ciphertext segments
00074    s = s / 8;
00075 
00076    //Check the resulting value
00077    if(s < 1 || s > cipher->blockSize)
00078       return ERROR_INVALID_PARAMETER;
00079 
00080    //Process each plaintext segment
00081    while(length >= s)
00082    {
00083       //Compute O(j) = CIPH(I(j))
00084       cipher->encryptBlock(context, iv, o);
00085 
00086       //Compute C(j) = P(j) XOR MSB(O(j))
00087       for(i = 0; i < s; i++)
00088          c[i] = p[i] ^ o[i];
00089 
00090       //Compute I(j+1) = LSB(I(j)) | O(j)
00091       memmove(iv, iv + s, cipher->blockSize - s);
00092       memcpy(iv + cipher->blockSize - s, o, s);
00093 
00094       //Next block
00095       p += s;
00096       c += s;
00097       length -= s;
00098    }
00099 
00100    //The plaintext must be a multiple of the segment size
00101    if(length != 0)
00102       return ERROR_INVALID_LENGTH;
00103 
00104    //Successful encryption
00105    return NO_ERROR;
00106 }
00107 
00108 
00109 /**
00110  * @brief OFB 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 ofbDecrypt(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    uint8_t o[16];
00126 
00127    //The parameter must be a multiple of 8
00128    if(s % 8)
00129       return ERROR_INVALID_PARAMETER;
00130 
00131    //Determine the size, in bytes, of the plaintext and ciphertext segments
00132    s = s / 8;
00133 
00134    //Check the resulting value
00135    if(s < 1 || s > cipher->blockSize)
00136       return ERROR_INVALID_PARAMETER;
00137 
00138    //Process each ciphertext segment
00139    while(length >= s)
00140    {
00141       //Compute O(j) = CIPH(I(j))
00142       cipher->encryptBlock(context, iv, o);
00143 
00144       //Compute P(j) = C(j) XOR MSB(O(j))
00145       for(i = 0; i < s; i++)
00146          p[i] = c[i] ^ o[i];
00147 
00148       //Compute I(j+1) = LSB(I(j)) | O(j)
00149       memmove(iv, iv + s, cipher->blockSize - s);
00150       memcpy(iv + cipher->blockSize - s, o, s);
00151 
00152       //Next block
00153       c += s;
00154       p += s;
00155       length -= s;
00156    }
00157 
00158    //The plaintext must be a multiple of the segment size
00159    if(length != 0)
00160       return ERROR_INVALID_LENGTH;
00161 
00162    //Successful encryption
00163    return NO_ERROR;
00164 }
00165 
00166 #endif
00167