Sergey Pastor / 1

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers rc4.c Source File

rc4.c

Go to the documentation of this file.
00001 /**
00002  * @file rc4.c
00003  * @brief RC4 encryption algorithm
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  * @author Oryx Embedded SARL (www.oryx-embedded.com)
00026  * @version 1.7.6
00027  **/
00028 
00029 //Switch to the appropriate trace level
00030 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
00031 
00032 //Dependencies
00033 #include <string.h>
00034 #include "crypto.h"
00035 #include "rc4.h"
00036 
00037 //Check crypto library configuration
00038 #if (RC4_SUPPORT == ENABLED)
00039 
00040 //Common interface for encryption algorithms
00041 const CipherAlgo rc4CipherAlgo =
00042 {
00043    "RC4",
00044    sizeof(Rc4Context),
00045    CIPHER_ALGO_TYPE_STREAM,
00046    0,
00047    (CipherAlgoInit) rc4Init,
00048    (CipherAlgoEncryptStream) rc4Cipher,
00049    (CipherAlgoDecryptStream) rc4Cipher,
00050    NULL,
00051    NULL
00052 };
00053 
00054 
00055 /**
00056  * @brief Initialize an RC4 context using the supplied key
00057  * @param[in] context Pointer to the RC4 context to initialize
00058  * @param[in] key Pointer to the key
00059  * @param[in] length Length of the key
00060  * @return Error code
00061  **/
00062 
00063 error_t rc4Init(Rc4Context *context, const uint8_t *key, size_t length)
00064 {
00065    uint_t i;
00066    uint_t j;
00067    uint8_t temp;
00068 
00069    //Clear context
00070    context->i = 0;
00071    context->j = 0;
00072 
00073    //Initialize the S array with identity permutation
00074    for(i = 0; i < 256; i++)
00075       context->s[i] = i;
00076 
00077    //S is then processed for 256 iterations
00078    for(i = 0, j = 0; i < 256; i++)
00079    {
00080       //Randomize the permutations using the supplied key
00081       j = (j + context->s[i] + key[i % length]) % 256;
00082 
00083       //Swap the values of S[i] and S[j]
00084       temp = context->s[i];
00085       context->s[i] = context->s[j];
00086       context->s[j] = temp;
00087    }
00088 
00089    //RC4 context successfully initialized
00090    return NO_ERROR;
00091 }
00092 
00093 
00094 /**
00095  * @brief Encrypt/decrypt data with the RC4 algorithm
00096  * @param[in] context Pointer to the RC4 context
00097  * @param[in] input Pointer to the data to encrypt/decrypt
00098  * @param[in] output Pointer to the resulting data
00099  * @param[in] length Length of the input data
00100  **/
00101 
00102 void rc4Cipher(Rc4Context *context, const uint8_t *input, uint8_t *output, size_t length)
00103 {
00104    uint8_t temp;
00105 
00106    //Restore context
00107    uint_t i = context->i;
00108    uint_t j = context->j;
00109    uint8_t *s = context->s;
00110 
00111    //Encryption loop
00112    while(length > 0)
00113    {
00114       //Adjust indices
00115       i = (i + 1) % 256;
00116       j = (j + s[i]) % 256;
00117 
00118       //Swap the values of S[i] and S[j]
00119       temp = s[i];
00120       s[i] = s[j];
00121       s[j] = temp;
00122 
00123       //XOR the input data with the RC4 stream
00124       *output = *input ^ s[(s[i] + s[j]) % 256];
00125 
00126       //Increment data pointers
00127       input++;
00128       output++;
00129 
00130       //Remaining bytes to process
00131       length--;
00132    }
00133 
00134    //Save context
00135    context->i = i;
00136    context->j = j;
00137 }
00138 
00139 #endif
00140