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 */
30static 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 */
41static 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 */
52static 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 */
90static 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 */
101static 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 */
112static const uint8_t plaintext[8] = "BLOWFISH";
113
114static const uint8_t plaintext2[16] = "BLOWFISHBLOWFISH";
115
116/* ciphertext bytes */
117static const uint8_t ciphertext[8] = {
118    0x32, 0x4E, 0xD0, 0xFE, 0xF4, 0x13, 0xA2, 0x03
119};
120
121static 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
128static 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
146int 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
195