annotate rc4.c @ 728:1fa3820b1a84 libavutil

ARM asm for AV_RN*() ARMv6 and later support unaligned loads and stores for single word/halfword but not double/multiple. GCC is ignorant of this and will always use bytewise accesses for unaligned data. Casting to an int32_t pointer is dangerous since a load/store double or multiple instruction might be used (this happens with some code in FFmpeg). Implementing the AV_[RW]* macros with inline asm using only supported instructions gives fast and safe unaligned accesses. ARM RVCT does the right thing with generic code. This gives an overall speedup of up to 10%.
author mru
date Sat, 18 Apr 2009 00:00:28 +0000
parents b084f8cd043f
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
384
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
1 /*
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
2 * RC4 encryption/decryption/pseudo-random number generator
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
3 * Copyright (c) 2007 Reimar Doeffinger
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
4 *
386
e6ec944b7ff0 Consistently place comments in file header.
diego
parents: 384
diff changeset
5 * loosely based on LibTomCrypt by Tom St Denis
e6ec944b7ff0 Consistently place comments in file header.
diego
parents: 384
diff changeset
6 *
384
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
7 * This file is part of FFmpeg.
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
8 *
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
9 * FFmpeg is free software; you can redistribute it and/or
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
10 * modify it under the terms of the GNU Lesser General Public
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
11 * License as published by the Free Software Foundation; either
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
12 * version 2.1 of the License, or (at your option) any later version.
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
13 *
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
14 * FFmpeg is distributed in the hope that it will be useful,
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
17 * Lesser General Public License for more details.
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
18 *
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
19 * You should have received a copy of the GNU Lesser General Public
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
20 * License along with FFmpeg; if not, write to the Free Software
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
22 */
647
67fb0b442dd2 Add and use a public API for RC4 and DES, analogous to the AES API.
reimar
parents: 386
diff changeset
23 #include "avutil.h"
384
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
24 #include "common.h"
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
25 #include "rc4.h"
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
26
647
67fb0b442dd2 Add and use a public API for RC4 and DES, analogous to the AES API.
reimar
parents: 386
diff changeset
27 typedef struct AVRC4 AVRC4;
67fb0b442dd2 Add and use a public API for RC4 and DES, analogous to the AES API.
reimar
parents: 386
diff changeset
28
67fb0b442dd2 Add and use a public API for RC4 and DES, analogous to the AES API.
reimar
parents: 386
diff changeset
29 int av_rc4_init(AVRC4 *r, const uint8_t *key, int key_bits, int decrypt) {
384
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
30 int i, j;
647
67fb0b442dd2 Add and use a public API for RC4 and DES, analogous to the AES API.
reimar
parents: 386
diff changeset
31 uint8_t y;
67fb0b442dd2 Add and use a public API for RC4 and DES, analogous to the AES API.
reimar
parents: 386
diff changeset
32 uint8_t *state = r->state;
67fb0b442dd2 Add and use a public API for RC4 and DES, analogous to the AES API.
reimar
parents: 386
diff changeset
33 int keylen = key_bits >> 3;
67fb0b442dd2 Add and use a public API for RC4 and DES, analogous to the AES API.
reimar
parents: 386
diff changeset
34 if (key_bits & 7)
67fb0b442dd2 Add and use a public API for RC4 and DES, analogous to the AES API.
reimar
parents: 386
diff changeset
35 return -1;
384
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
36 for (i = 0; i < 256; i++)
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
37 state[i] = i;
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
38 y = 0;
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
39 // j is i % keylen
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
40 for (j = 0, i = 0; i < 256; i++, j++) {
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
41 if (j == keylen) j = 0;
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
42 y += state[i] + key[j];
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
43 FFSWAP(uint8_t, state[i], state[y]);
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
44 }
647
67fb0b442dd2 Add and use a public API for RC4 and DES, analogous to the AES API.
reimar
parents: 386
diff changeset
45 r->x = 1;
67fb0b442dd2 Add and use a public API for RC4 and DES, analogous to the AES API.
reimar
parents: 386
diff changeset
46 r->y = state[1];
67fb0b442dd2 Add and use a public API for RC4 and DES, analogous to the AES API.
reimar
parents: 386
diff changeset
47 return 0;
67fb0b442dd2 Add and use a public API for RC4 and DES, analogous to the AES API.
reimar
parents: 386
diff changeset
48 }
67fb0b442dd2 Add and use a public API for RC4 and DES, analogous to the AES API.
reimar
parents: 386
diff changeset
49
67fb0b442dd2 Add and use a public API for RC4 and DES, analogous to the AES API.
reimar
parents: 386
diff changeset
50 void av_rc4_crypt(AVRC4 *r, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt) {
67fb0b442dd2 Add and use a public API for RC4 and DES, analogous to the AES API.
reimar
parents: 386
diff changeset
51 uint8_t x = r->x, y = r->y;
67fb0b442dd2 Add and use a public API for RC4 and DES, analogous to the AES API.
reimar
parents: 386
diff changeset
52 uint8_t *state = r->state;
67fb0b442dd2 Add and use a public API for RC4 and DES, analogous to the AES API.
reimar
parents: 386
diff changeset
53 while (count-- > 0) {
384
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
54 uint8_t sum = state[x] + state[y];
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
55 FFSWAP(uint8_t, state[x], state[y]);
647
67fb0b442dd2 Add and use a public API for RC4 and DES, analogous to the AES API.
reimar
parents: 386
diff changeset
56 *dst++ = src ? *src++ ^ state[sum] : state[sum];
384
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
57 x++;
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
58 y += state[x];
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
59 }
647
67fb0b442dd2 Add and use a public API for RC4 and DES, analogous to the AES API.
reimar
parents: 386
diff changeset
60 r->x = x; r->y = y;
384
8d29c19c22c4 Add RC4 encryption/decryption function
reimar
parents:
diff changeset
61 }