Annotation of qemu/roms/ipxe/src/crypto/arc4.c, revision 1.1.1.1

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: };

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.