FFmpeg
blowfish.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 <stdlib.h>
22 #include <string.h>
23 
24 #include "libavutil/mem.h"
25 #include "libavutil/blowfish.h"
26 
27 #define NUM_VARIABLE_KEY_TESTS 34
28 
29 /* plaintext bytes -- left halves */
30 static const uint32_t plaintext_l[NUM_VARIABLE_KEY_TESTS] = {
31  0x00000000, 0xFFFFFFFF, 0x10000000, 0x11111111, 0x11111111,
32  0x01234567, 0x00000000, 0x01234567, 0x01A1D6D0, 0x5CD54CA8,
33  0x0248D438, 0x51454B58, 0x42FD4430, 0x059B5E08, 0x0756D8E0,
34  0x762514B8, 0x3BDD1190, 0x26955F68, 0x164D5E40, 0x6B056E18,
35  0x004BD6EF, 0x480D3900, 0x437540C8, 0x072D43A0, 0x02FE5577,
36  0x1D9D5C50, 0x30553228, 0x01234567, 0x01234567, 0x01234567,
37  0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF
38 };
39 
40 /* plaintext bytes -- right halves */
41 static const uint32_t plaintext_r[NUM_VARIABLE_KEY_TESTS] = {
42  0x00000000, 0xFFFFFFFF, 0x00000001, 0x11111111, 0x11111111,
43  0x89ABCDEF, 0x00000000, 0x89ABCDEF, 0x39776742, 0x3DEF57DA,
44  0x06F67172, 0x2DDF440A, 0x59577FA2, 0x51CF143A, 0x774761D2,
45  0x29BF486A, 0x49372802, 0x35AF609A, 0x4F275232, 0x759F5CCA,
46  0x09176062, 0x6EE762F2, 0x698F3CFA, 0x77075292, 0x8117F12A,
47  0x18F728C2, 0x6D6F295A, 0x89ABCDEF, 0x89ABCDEF, 0x89ABCDEF,
48  0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF
49 };
50 
51 /* key bytes for variable key tests */
52 static const uint8_t variable_key[NUM_VARIABLE_KEY_TESTS][8] = {
53  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
54  { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
55  { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
56  { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 },
57  { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
58  { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 },
59  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
60  { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 },
61  { 0x7C, 0xA1, 0x10, 0x45, 0x4A, 0x1A, 0x6E, 0x57 },
62  { 0x01, 0x31, 0xD9, 0x61, 0x9D, 0xC1, 0x37, 0x6E },
63  { 0x07, 0xA1, 0x13, 0x3E, 0x4A, 0x0B, 0x26, 0x86 },
64  { 0x38, 0x49, 0x67, 0x4C, 0x26, 0x02, 0x31, 0x9E },
65  { 0x04, 0xB9, 0x15, 0xBA, 0x43, 0xFE, 0xB5, 0xB6 },
66  { 0x01, 0x13, 0xB9, 0x70, 0xFD, 0x34, 0xF2, 0xCE },
67  { 0x01, 0x70, 0xF1, 0x75, 0x46, 0x8F, 0xB5, 0xE6 },
68  { 0x43, 0x29, 0x7F, 0xAD, 0x38, 0xE3, 0x73, 0xFE },
69  { 0x07, 0xA7, 0x13, 0x70, 0x45, 0xDA, 0x2A, 0x16 },
70  { 0x04, 0x68, 0x91, 0x04, 0xC2, 0xFD, 0x3B, 0x2F },
71  { 0x37, 0xD0, 0x6B, 0xB5, 0x16, 0xCB, 0x75, 0x46 },
72  { 0x1F, 0x08, 0x26, 0x0D, 0x1A, 0xC2, 0x46, 0x5E },
73  { 0x58, 0x40, 0x23, 0x64, 0x1A, 0xBA, 0x61, 0x76 },
74  { 0x02, 0x58, 0x16, 0x16, 0x46, 0x29, 0xB0, 0x07 },
75  { 0x49, 0x79, 0x3E, 0xBC, 0x79, 0xB3, 0x25, 0x8F },
76  { 0x4F, 0xB0, 0x5E, 0x15, 0x15, 0xAB, 0x73, 0xA7 },
77  { 0x49, 0xE9, 0x5D, 0x6D, 0x4C, 0xA2, 0x29, 0xBF },
78  { 0x01, 0x83, 0x10, 0xDC, 0x40, 0x9B, 0x26, 0xD6 },
79  { 0x1C, 0x58, 0x7F, 0x1C, 0x13, 0x92, 0x4F, 0xEF },
80  { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
81  { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E },
82  { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE },
83  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
84  { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
85  { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
86  { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }
87 };
88 
89 /* ciphertext bytes -- left halves */
90 static const uint32_t ciphertext_l[NUM_VARIABLE_KEY_TESTS] = {
91  0x4EF99745, 0x51866FD5, 0x7D856F9A, 0x2466DD87, 0x61F9C380,
92  0x7D0CC630, 0x4EF99745, 0x0ACEAB0F, 0x59C68245, 0xB1B8CC0B,
93  0x1730E577, 0xA25E7856, 0x353882B1, 0x48F4D088, 0x432193B7,
94  0x13F04154, 0x2EEDDA93, 0xD887E039, 0x5F99D04F, 0x4A057A3B,
95  0x452031C1, 0x7555AE39, 0x53C55F9C, 0x7A8E7BFA, 0xCF9C5D7A,
96  0xD1ABB290, 0x55CB3774, 0xFA34EC48, 0xA7907951, 0xC39E072D,
97  0x014933E0, 0xF21E9A77, 0x24594688, 0x6B5C5A9C
98 };
99 
100 /* ciphertext bytes -- right halves */
101 static const uint32_t ciphertext_r[NUM_VARIABLE_KEY_TESTS] = {
102  0x6198DD78, 0xB85ECB8A, 0x613063F2, 0x8B963C9D, 0x2281B096,
103  0xAFDA1EC7, 0x6198DD78, 0xC6A0A28D, 0xEB05282B, 0x250F09A0,
104  0x8BEA1DA4, 0xCF2651EB, 0x09CE8F1A, 0x4C379918, 0x8951FC98,
105  0xD69D1AE5, 0xFFD39C79, 0x3C2DA6E3, 0x5B163969, 0x24D3977B,
106  0xE4FADA8E, 0xF59B87BD, 0xB49FC019, 0x937E89A3, 0x4986ADB5,
107  0x658BC778, 0xD13EF201, 0x47B268B2, 0x08EA3CAE, 0x9FAC631D,
108  0xCDAFF6E4, 0xB71C49BC, 0x5754369A, 0x5D9E0A5A
109 };
110 
111 /* plaintext bytes */
112 static const uint8_t plaintext[8] = "BLOWFISH";
113 
114 static const uint8_t plaintext2[16] = "BLOWFISHBLOWFISH";
115 
116 /* ciphertext bytes */
117 static const uint8_t ciphertext[8] = {
118  0x32, 0x4E, 0xD0, 0xFE, 0xF4, 0x13, 0xA2, 0x03
119 };
120 
121 static const uint8_t ciphertext2[16] = {
122  0x53, 0x00, 0x40, 0x06, 0x63, 0xf2, 0x1d, 0x99,
123  0x3b, 0x9b, 0x27, 0x64, 0x46, 0xfd, 0x20, 0xc1,
124 };
125 
126 #define IV "blowfish"
127 
128 static void test_blowfish(AVBlowfish *ctx, uint8_t *dst, const uint8_t *src,
129  const uint8_t *ref, int len, uint8_t *iv, int dir,
130  const char *test)
131 {
132  av_blowfish_crypt(ctx, dst, src, len, iv, dir);
133  if (memcmp(dst, ref, 8*len)) {
134  int i;
135  printf("%s failed\ngot ", test);
136  for (i = 0; i < 8*len; i++)
137  printf("%02x ", dst[i]);
138  printf("\nexpected ");
139  for (i = 0; i < 8*len; i++)
140  printf("%02x ", ref[i]);
141  printf("\n");
142  exit(1);
143  }
144 }
145 
146 int main(void)
147 {
148  uint32_t tmptext_l[NUM_VARIABLE_KEY_TESTS];
149  uint32_t tmptext_r[NUM_VARIABLE_KEY_TESTS];
150  uint8_t tmp[16], iv[8];
151  int i;
153  if (!ctx)
154  return 1;
155 
156  av_blowfish_init(ctx, "abcdefghijklmnopqrstuvwxyz", 26);
157 
158  test_blowfish(ctx, tmp, plaintext, ciphertext, 1, NULL, 0, "encryption");
159  test_blowfish(ctx, tmp, ciphertext, plaintext, 1, NULL, 1, "decryption");
160  test_blowfish(ctx, tmp, tmp, ciphertext, 1, NULL, 0, "Inplace encryption");
161  test_blowfish(ctx, tmp, tmp, plaintext, 1, NULL, 1, "Inplace decryption");
162  memcpy(iv, IV, 8);
163  test_blowfish(ctx, tmp, plaintext2, ciphertext2, 2, iv, 0, "CBC encryption");
164  memcpy(iv, IV, 8);
165  test_blowfish(ctx, tmp, ciphertext2, plaintext2, 2, iv, 1, "CBC decryption");
166  memcpy(iv, IV, 8);
167  test_blowfish(ctx, tmp, tmp, ciphertext2, 2, iv, 0, "Inplace CBC encryption");
168  memcpy(iv, IV, 8);
169  test_blowfish(ctx, tmp, tmp, plaintext2, 2, iv, 1, "Inplace CBC decryption");
170 
171  memcpy(tmptext_l, plaintext_l, sizeof(*plaintext_l) * NUM_VARIABLE_KEY_TESTS);
172  memcpy(tmptext_r, plaintext_r, sizeof(*plaintext_r) * NUM_VARIABLE_KEY_TESTS);
173 
174  for (i = 0; i < NUM_VARIABLE_KEY_TESTS; i++) {
176 
177  av_blowfish_crypt_ecb(ctx, &tmptext_l[i], &tmptext_r[i], 0);
178  if (tmptext_l[i] != ciphertext_l[i] || tmptext_r[i] != ciphertext_r[i]) {
179  printf("Test encryption failed.\n");
180  return 2;
181  }
182 
183  av_blowfish_crypt_ecb(ctx, &tmptext_l[i], &tmptext_r[i], 1);
184  if (tmptext_l[i] != plaintext_l[i] || tmptext_r[i] != plaintext_r[i]) {
185  printf("Test decryption failed.\n");
186  return 3;
187  }
188  }
189  printf("Test encryption/decryption success.\n");
190  av_free(ctx);
191 
192  return 0;
193 }
194 
plaintext_r
static const uint32_t plaintext_r[NUM_VARIABLE_KEY_TESTS]
Definition: blowfish.c:41
ciphertext_l
static const uint32_t ciphertext_l[NUM_VARIABLE_KEY_TESTS]
Definition: blowfish.c:90
variable_key
static const uint8_t variable_key[NUM_VARIABLE_KEY_TESTS][8]
Definition: blowfish.c:52
IV
#define IV
Definition: blowfish.c:126
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:26
plaintext2
static const uint8_t plaintext2[16]
Definition: blowfish.c:114
av_blowfish_alloc
AVBlowfish * av_blowfish_alloc(void)
Allocate an AVBlowfish context.
Definition: blowfish.c:304
NUM_VARIABLE_KEY_TESTS
#define NUM_VARIABLE_KEY_TESTS
Definition: blowfish.c:27
ctx
AVFormatContext * ctx
Definition: movenc.c:48
NULL
#define NULL
Definition: coverity.c:32
src
#define src
Definition: vp8dsp.c:255
ciphertext2
static const uint8_t ciphertext2[16]
Definition: blowfish.c:121
blowfish.h
av_blowfish_crypt
void av_blowfish_crypt(AVBlowfish *ctx, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt)
Encrypt or decrypt a buffer using a previously initialized context.
Definition: blowfish.c:375
plaintext
static const uint8_t plaintext[8]
Definition: blowfish.c:112
test_blowfish
static void test_blowfish(AVBlowfish *ctx, uint8_t *dst, const uint8_t *src, const uint8_t *ref, int len, uint8_t *iv, int dir, const char *test)
Definition: blowfish.c:128
plaintext_l
static const uint32_t plaintext_l[NUM_VARIABLE_KEY_TESTS]
Definition: blowfish.c:30
printf
printf("static const uint8_t my_array[100] = {\n")
ciphertext
static const uint8_t ciphertext[8]
Definition: blowfish.c:117
AVBlowfish
Definition: blowfish.h:35
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
len
int len
Definition: vorbis_enc_data.h:426
test
static void test(const char *pattern, const char *host)
Definition: noproxy.c:23
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:107
av_blowfish_crypt_ecb
void av_blowfish_crypt_ecb(AVBlowfish *ctx, uint32_t *xl, uint32_t *xr, int decrypt)
Encrypt or decrypt a buffer using a previously initialized context.
Definition: blowfish.c:344
mem.h
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
av_blowfish_init
av_cold void av_blowfish_init(AVBlowfish *ctx, const uint8_t *key, int key_len)
Initialize an AVBlowfish context.
Definition: blowfish.c:309
ciphertext_r
static const uint32_t ciphertext_r[NUM_VARIABLE_KEY_TESTS]
Definition: blowfish.c:101
main
int main(void)
Definition: blowfish.c:146