FFmpeg
rc4.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include <stdint.h>
20 #include <stdio.h>
21 #include <string.h>
22 
24 #include "libavutil/macros.h"
25 #include "libavutil/mem.h"
26 #include "libavutil/rc4.h"
27 
28 /* RFC 6229 test vectors */
29 static const struct {
30  int key_bits;
31  const uint8_t key[16];
32  const uint8_t keystream[8]; /* first 8 bytes of output */
33 } test_vectors[] = {
34  /* 40-bit key: 0x0102030405 */
35  { 40,
36  { 0x01, 0x02, 0x03, 0x04, 0x05 },
37  { 0xb2, 0x39, 0x63, 0x05, 0xf0, 0x3d, 0xc0, 0x27 } },
38  /* 56-bit key: 0x01020304050607 */
39  { 56,
40  { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 },
41  { 0x29, 0x3f, 0x02, 0xd4, 0x7f, 0x37, 0xc9, 0xb6 } },
42  /* 64-bit key: 0x0102030405060708 */
43  { 64,
44  { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 },
45  { 0x97, 0xab, 0x8a, 0x1b, 0xf0, 0xaf, 0xb9, 0x61 } },
46  /* 128-bit key: 0x0102030405060708090a0b0c0d0e0f10 */
47  { 128,
48  { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
49  0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 },
50  { 0x9a, 0xc7, 0xcc, 0x9a, 0x60, 0x9d, 0x1e, 0xf7 } },
51 };
52 
53 int main(void)
54 {
55  AVRC4 *ctx;
56  uint8_t buf[8], encrypted[8], decrypted[8];
57 
58  ctx = av_rc4_alloc();
59  if (!ctx)
60  return 1;
61 
62  /* test keystream output (src=NULL) against known vectors */
63  for (int i = 0; i < FF_ARRAY_ELEMS(test_vectors); i++) {
65  av_rc4_crypt(ctx, buf, NULL, sizeof(buf), NULL, 0);
66  if (memcmp(buf, test_vectors[i].keystream, sizeof(buf))) {
67  printf("Keystream test %d (%d-bit key) failed.\n",
69  av_free(ctx);
70  return 1;
71  }
72  }
73 
74  /* test encrypt then decrypt round-trip */
75  {
76  const uint8_t key[] = { 0x01, 0x02, 0x03, 0x04, 0x05 };
77  static attribute_nonstring const uint8_t plaintext[8] = "TestData";
78 
79  av_rc4_init(ctx, key, 40, 0);
81 
82  /* RC4 is symmetric: re-init and encrypt again to decrypt */
83  av_rc4_init(ctx, key, 40, 0);
84  av_rc4_crypt(ctx, decrypted, encrypted, sizeof(encrypted), NULL, 0);
85 
86  if (memcmp(decrypted, plaintext, sizeof(plaintext))) {
87  printf("Round-trip test failed.\n");
88  av_free(ctx);
89  return 1;
90  }
91  }
92 
93  /* test inplace encrypt/decrypt */
94  {
95  const uint8_t key[] = { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 };
96  static attribute_nonstring const uint8_t plaintext[8] = "InPlace!";
97 
98  memcpy(buf, plaintext, sizeof(plaintext));
99  av_rc4_init(ctx, key, 64, 0);
100  av_rc4_crypt(ctx, buf, buf, sizeof(buf), NULL, 0);
101 
102  av_rc4_init(ctx, key, 64, 0);
103  av_rc4_crypt(ctx, buf, buf, sizeof(buf), NULL, 0);
104 
105  if (memcmp(buf, plaintext, sizeof(plaintext))) {
106  printf("Inplace round-trip test failed.\n");
107  av_free(ctx);
108  return 1;
109  }
110  }
111 
112  /* test invalid key_bits (not multiple of 8) */
113  if (av_rc4_init(ctx, (const uint8_t[]){ 0x01 }, 7, 0) >= 0) {
114  printf("Invalid key_bits should return error.\n");
115  av_free(ctx);
116  return 1;
117  }
118 
119  printf("Test encryption/decryption success.\n");
120  av_free(ctx);
121 
122  return 0;
123 }
printf
__device__ int printf(const char *,...)
main
int main(void)
Definition: rc4.c:53
AVRC4
Definition: rc4.h:32
attribute_nonstring
#define attribute_nonstring
Definition: attributes_internal.h:42
macros.h
key
const uint8_t key[16]
Definition: rc4.c:31
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
attributes_internal.h
encrypted
static const uint8_t encrypted[]
Definition: aes_ctr.c:34
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
plaintext
static const attribute_nonstring uint8_t plaintext[8]
Definition: blowfish.c:113
NULL
#define NULL
Definition: coverity.c:32
key_bits
int key_bits
Definition: rc4.c:30
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
av_rc4_alloc
AVRC4 * av_rc4_alloc(void)
Allocate an AVRC4 context.
Definition: rc4.c:29
av_rc4_crypt
void av_rc4_crypt(AVRC4 *r, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt)
Encrypts / decrypts using the RC4 algorithm.
Definition: rc4.c:55
av_rc4_init
int av_rc4_init(AVRC4 *r, const uint8_t *key, int key_bits, int decrypt)
Initializes an AVRC4 context.
Definition: rc4.c:34
test_vectors
static const struct @545 test_vectors[]
keystream
const uint8_t keystream[8]
Definition: rc4.c:32
mem.h
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
rc4.h