]> git.sesse.net Git - ffmpeg/blob - libavutil/tests/blowfish.c
Merge commit 'a70eac7a9b193e8434b5bed90bd72aa4cb688363'
[ffmpeg] / libavutil / tests / blowfish.c
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;
152     AVBlowfish *ctx = av_blowfish_alloc();
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++) {
175         av_blowfish_init(ctx, variable_key[i], 8);
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