|
|
1.1 ! root 1: /* ! 2: * The ARC4 stream cipher. ! 3: * ! 4: * Copyright (c) 2009 Joshua Oreman <[email protected]>. ! 5: * ! 6: * This program is free software; you can redistribute it and/or ! 7: * modify it under the terms of the GNU General Public License as ! 8: * published by the Free Software Foundation; either version 2 of the ! 9: * License, or any later version. ! 10: * ! 11: * This program is distributed in the hope that it will be useful, but ! 12: * WITHOUT ANY WARRANTY; without even the implied warranty of ! 13: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! 14: * General Public License for more details. ! 15: * ! 16: * You should have received a copy of the GNU General Public License ! 17: * along with this program; if not, write to the Free Software ! 18: * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ! 19: */ ! 20: ! 21: FILE_LICENCE ( GPL2_OR_LATER ); ! 22: ! 23: #include <ipxe/crypto.h> ! 24: #include <ipxe/arc4.h> ! 25: ! 26: #define SWAP( ary, i, j ) \ ! 27: ({ u8 temp = ary[i]; ary[i] = ary[j]; ary[j] = temp; }) ! 28: ! 29: /** ! 30: * Set ARC4 key ! 31: * ! 32: * @v ctxv ARC4 encryption context ! 33: * @v keyv Key to set ! 34: * @v keylen Length of key ! 35: * ! 36: * If an initialisation vector is to be used, it should be prepended ! 37: * to the key; ARC4 does not implement the @c setiv function because ! 38: * there is no standard length for an initialisation vector in the ! 39: * cipher. ! 40: */ ! 41: static int arc4_setkey ( void *ctxv, const void *keyv, size_t keylen ) ! 42: { ! 43: struct arc4_ctx *ctx = ctxv; ! 44: const u8 *key = keyv; ! 45: u8 *S = ctx->state; ! 46: int i, j; ! 47: ! 48: for ( i = 0; i < 256; i++ ) { ! 49: S[i] = i; ! 50: } ! 51: ! 52: for ( i = j = 0; i < 256; i++ ) { ! 53: j = ( j + S[i] + key[i % keylen] ) & 0xff; ! 54: SWAP ( S, i, j ); ! 55: } ! 56: ! 57: ctx->i = ctx->j = 0; ! 58: return 0; ! 59: } ! 60: ! 61: /** ! 62: * Perform ARC4 encryption or decryption ! 63: * ! 64: * @v ctxv ARC4 encryption context ! 65: * @v srcv Data to encrypt or decrypt ! 66: * @v dstv Location to store encrypted or decrypted data ! 67: * @v len Length of data to operate on ! 68: * ! 69: * ARC4 is a stream cipher that works by generating a stream of PRNG ! 70: * data based on the key, and XOR'ing it with the data to be ! 71: * encrypted. Since XOR is symmetric, encryption and decryption in ! 72: * ARC4 are the same operation. ! 73: * ! 74: * If you pass a @c NULL source or destination pointer, @a len ! 75: * keystream bytes will be consumed without encrypting any data. ! 76: */ ! 77: static void arc4_xor ( void *ctxv, const void *srcv, void *dstv, ! 78: size_t len ) ! 79: { ! 80: struct arc4_ctx *ctx = ctxv; ! 81: const u8 *src = srcv; ! 82: u8 *dst = dstv; ! 83: u8 *S = ctx->state; ! 84: int i = ctx->i, j = ctx->j; ! 85: ! 86: while ( len-- ) { ! 87: i = ( i + 1 ) & 0xff; ! 88: j = ( j + S[i] ) & 0xff; ! 89: SWAP ( S, i, j ); ! 90: if ( srcv && dstv ) ! 91: *dst++ = *src++ ^ S[(S[i] + S[j]) & 0xff]; ! 92: } ! 93: ! 94: ctx->i = i; ! 95: ctx->j = j; ! 96: } ! 97: ! 98: static void arc4_setiv ( void *ctx __unused, const void *iv __unused ) ! 99: { ! 100: /* ARC4 does not use a fixed-length IV */ ! 101: } ! 102: ! 103: ! 104: /** ! 105: * Perform ARC4 encryption or decryption, skipping initial keystream bytes ! 106: * ! 107: * @v key ARC4 encryption key ! 108: * @v keylen Key length ! 109: * @v skip Number of bytes of keystream to skip ! 110: * @v src Message to encrypt or decrypt ! 111: * @v msglen Length of message ! 112: * @ret dst Encrypted or decrypted message ! 113: */ ! 114: void arc4_skip ( const void *key, size_t keylen, size_t skip, ! 115: const void *src, void *dst, size_t msglen ) ! 116: { ! 117: struct arc4_ctx ctx; ! 118: arc4_setkey ( &ctx, key, keylen ); ! 119: arc4_xor ( &ctx, NULL, NULL, skip ); ! 120: arc4_xor ( &ctx, src, dst, msglen ); ! 121: } ! 122: ! 123: struct cipher_algorithm arc4_algorithm = { ! 124: .name = "ARC4", ! 125: .ctxsize = ARC4_CTX_SIZE, ! 126: .blocksize = 1, ! 127: .setkey = arc4_setkey, ! 128: .setiv = arc4_setiv, ! 129: .encrypt = arc4_xor, ! 130: .decrypt = arc4_xor, ! 131: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.