Xuyi Wang / wolfcrypt

Dependents:   OS

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers arc4.c Source File

arc4.c

00001 /* arc4.c
00002  *
00003  * Copyright (C) 2006-2017 wolfSSL Inc.
00004  *
00005  * This file is part of wolfSSL.
00006  *
00007  * wolfSSL is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * wolfSSL is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
00020  */
00021 
00022 
00023 #ifdef HAVE_CONFIG_H
00024     #include <config.h>
00025 #endif
00026 
00027 #include <wolfcrypt/settings.h>
00028 
00029 #ifndef NO_RC4
00030 
00031 #include <wolfcrypt/error-crypt.h>
00032 #include <wolfcrypt/arc4.h>
00033 
00034 
00035 int wc_Arc4SetKey(Arc4* arc4, const byte* key, word32 length)
00036 {
00037     int ret = 0;
00038     word32 i;
00039     word32 keyIndex = 0, stateIndex = 0;
00040 
00041     if (arc4 == NULL || key == NULL) {
00042         return BAD_FUNC_ARG;
00043     }
00044 
00045 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ARC4) && \
00046         defined(HAVE_CAVIUM) && !defined(HAVE_CAVIUM_V)
00047     if (arc4->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ARC4) {
00048         return NitroxArc4SetKey(arc4, key, length);
00049     }
00050 #endif
00051 
00052     arc4->x = 1;
00053     arc4->y = 0;
00054 
00055     for (i = 0; i < ARC4_STATE_SIZE; i++)
00056         arc4->state[i] = (byte)i;
00057 
00058     for (i = 0; i < ARC4_STATE_SIZE; i++) {
00059         word32 a = arc4->state[i];
00060         stateIndex += key[keyIndex] + a;
00061         stateIndex &= 0xFF;
00062         arc4->state[i] = arc4->state[stateIndex];
00063         arc4->state[stateIndex] = (byte)a;
00064 
00065         if (++keyIndex >= length)
00066             keyIndex = 0;
00067     }
00068 
00069     return ret;
00070 }
00071 
00072 
00073 static WC_INLINE byte MakeByte(word32* x, word32* y, byte* s)
00074 {
00075     word32 a = s[*x], b;
00076     *y = (*y+a) & 0xff;
00077 
00078     b = s[*y];
00079     s[*x] = (byte)b;
00080     s[*y] = (byte)a;
00081     *x = (*x+1) & 0xff;
00082 
00083     return s[(a+b) & 0xff];
00084 }
00085 
00086 
00087 int wc_Arc4Process(Arc4* arc4, byte* out, const byte* in, word32 length)
00088 {
00089     int ret = 0;
00090     word32 x;
00091     word32 y;
00092 
00093     if (arc4 == NULL || out == NULL || in == NULL) {
00094         return BAD_FUNC_ARG;
00095     }
00096 
00097 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ARC4) && \
00098         defined(HAVE_CAVIUM) && !defined(HAVE_CAVIUM_V)
00099     if (arc4->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ARC4) {
00100         return NitroxArc4Process(arc4, out, in, length);
00101     }
00102 #endif
00103 
00104     x = arc4->x;
00105     y = arc4->y;
00106 
00107     while(length--)
00108         *out++ = *in++ ^ MakeByte(&x, &y, arc4->state);
00109 
00110     arc4->x = (byte)x;
00111     arc4->y = (byte)y;
00112 
00113     return ret;
00114 }
00115 
00116 /* Initialize Arc4 for use with async device */
00117 int wc_Arc4Init(Arc4* arc4, void* heap, int devId)
00118 {
00119     int ret = 0;
00120 
00121     if (arc4 == NULL)
00122         return BAD_FUNC_ARG;
00123 
00124     arc4->heap = heap;
00125 
00126 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ARC4)
00127     ret = wolfAsync_DevCtxInit(&arc4->asyncDev, WOLFSSL_ASYNC_MARKER_ARC4,
00128         arc4->heap, devId);
00129 #else
00130     (void)devId;
00131 #endif /* WOLFSSL_ASYNC_CRYPT */
00132 
00133     return ret;
00134 }
00135 
00136 
00137 /* Free Arc4 from use with async device */
00138 void wc_Arc4Free(Arc4* arc4)
00139 {
00140     if (arc4 == NULL)
00141         return;
00142 
00143 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ARC4)
00144     wolfAsync_DevCtxFree(&arc4->asyncDev, WOLFSSL_ASYNC_MARKER_ARC4);
00145 #endif /* WOLFSSL_ASYNC_CRYPT */
00146 }
00147 
00148 #endif /* NO_RC4 */
00149 
00150