Annotation of qemu/roms/ipxe/src/crypto/arc4.c, revision 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.