* commit '29abb04e73b0580ebe38703cadb988d26df6a76a': libspeexdec: If the channel count is not valid, decode as stereo. libspeexdec: improve setting of Speex mode and sample rate libspeex: Add a private option for enabling VAD xtea: Test inplace decryption xtea: Fix CBC decryption when src==dst xtea: Factorize testing into a separate function configure: Refactor HAVE_ options available on the command line avconv/avprobe: Add missing 'void' to exit_program() definition Allow use of strncpy() blowfish: Add more tests blowfish: Fix CBC decryption with dst==src blowfish: Factorize testing into a separate function Conflicts: configure libavcodec/libspeexdec.c libavutil/xtea.c Merged-by: Michael Niedermayer <michaelni@gmx.at>tags/n1.1
| @@ -1243,6 +1243,12 @@ ARCH_EXT_LIST=" | |||||
| mipsdspr2 | mipsdspr2 | ||||
| " | " | ||||
| HAVE_LIST_CMDLINE=' | |||||
| inline_asm | |||||
| symver | |||||
| yasm | |||||
| ' | |||||
| HAVE_LIST_PUB=' | HAVE_LIST_PUB=' | ||||
| bigendian | bigendian | ||||
| fast_unaligned | fast_unaligned | ||||
| @@ -1253,6 +1259,7 @@ HAVE_LIST=" | |||||
| $ARCH_EXT_LIST | $ARCH_EXT_LIST | ||||
| $(add_suffix _external $ARCH_EXT_LIST) | $(add_suffix _external $ARCH_EXT_LIST) | ||||
| $(add_suffix _inline $ARCH_EXT_LIST) | $(add_suffix _inline $ARCH_EXT_LIST) | ||||
| $HAVE_LIST_CMDLINE | |||||
| $HAVE_LIST_PUB | $HAVE_LIST_PUB | ||||
| $THREADS_LIST | $THREADS_LIST | ||||
| aligned_malloc | aligned_malloc | ||||
| @@ -1305,7 +1312,6 @@ HAVE_LIST=" | |||||
| gnu_as | gnu_as | ||||
| ibm_asm | ibm_asm | ||||
| inet_aton | inet_aton | ||||
| inline_asm | |||||
| io_h | io_h | ||||
| isatty | isatty | ||||
| isinf | isinf | ||||
| @@ -1369,7 +1375,6 @@ HAVE_LIST=" | |||||
| struct_sockaddr_sa_len | struct_sockaddr_sa_len | ||||
| struct_sockaddr_storage | struct_sockaddr_storage | ||||
| struct_v4l2_frmivalenum_discrete | struct_v4l2_frmivalenum_discrete | ||||
| symver | |||||
| symver_asm_label | symver_asm_label | ||||
| symver_gnu_asm | symver_gnu_asm | ||||
| sysconf | sysconf | ||||
| @@ -1395,7 +1400,6 @@ HAVE_LIST=" | |||||
| xform_asm | xform_asm | ||||
| xgetbv | xgetbv | ||||
| xmm_clobbers | xmm_clobbers | ||||
| yasm | |||||
| " | " | ||||
| # options emitted with CONFIG_ prefix but not available on command line | # options emitted with CONFIG_ prefix but not available on command line | ||||
| @@ -1427,18 +1431,16 @@ CONFIG_EXTRA=" | |||||
| CMDLINE_SELECT=" | CMDLINE_SELECT=" | ||||
| $ARCH_EXT_LIST | $ARCH_EXT_LIST | ||||
| $CONFIG_LIST | $CONFIG_LIST | ||||
| $HAVE_LIST_CMDLINE | |||||
| $THREADS_LIST | $THREADS_LIST | ||||
| asm | asm | ||||
| coverage | coverage | ||||
| cross_compile | cross_compile | ||||
| debug | debug | ||||
| extra_warnings | extra_warnings | ||||
| inline_asm | |||||
| logging | logging | ||||
| optimizations | optimizations | ||||
| stripping | stripping | ||||
| symver | |||||
| yasm | |||||
| " | " | ||||
| PATHS_LIST=' | PATHS_LIST=' | ||||
| @@ -39,35 +39,42 @@ static av_cold int libspeex_decode_init(AVCodecContext *avctx) | |||||
| { | { | ||||
| LibSpeexContext *s = avctx->priv_data; | LibSpeexContext *s = avctx->priv_data; | ||||
| const SpeexMode *mode; | const SpeexMode *mode; | ||||
| // defaults in the case of a missing header | |||||
| if (avctx->sample_rate <= 8000) | |||||
| mode = &speex_nb_mode; | |||||
| else if (avctx->sample_rate <= 16000) | |||||
| mode = &speex_wb_mode; | |||||
| else | |||||
| mode = &speex_uwb_mode; | |||||
| int spx_mode; | |||||
| if (avctx->extradata_size >= 80) | if (avctx->extradata_size >= 80) | ||||
| s->header = speex_packet_to_header(avctx->extradata, avctx->extradata_size); | s->header = speex_packet_to_header(avctx->extradata, avctx->extradata_size); | ||||
| avctx->sample_fmt = AV_SAMPLE_FMT_S16; | avctx->sample_fmt = AV_SAMPLE_FMT_S16; | ||||
| if (s->header) { | if (s->header) { | ||||
| avctx->sample_rate = s->header->rate; | |||||
| avctx->channels = s->header->nb_channels; | avctx->channels = s->header->nb_channels; | ||||
| s->frame_size = s->header->frame_size; | s->frame_size = s->header->frame_size; | ||||
| mode = speex_lib_get_mode(s->header->mode); | |||||
| if (!mode) { | |||||
| av_log(avctx, AV_LOG_ERROR, "Unknown Speex mode %d\n", s->header->mode); | |||||
| return AVERROR_INVALIDDATA; | |||||
| spx_mode = s->header->mode; | |||||
| } else { | |||||
| switch (avctx->sample_rate) { | |||||
| case 8000: spx_mode = 0; break; | |||||
| case 16000: spx_mode = 1; break; | |||||
| case 32000: spx_mode = 2; break; | |||||
| default: | |||||
| /* libspeex can handle any mode if initialized as ultra-wideband */ | |||||
| av_log(avctx, AV_LOG_WARNING, "Invalid sample rate: %d\n" | |||||
| "Decoding as 32kHz ultra-wideband\n", | |||||
| avctx->sample_rate); | |||||
| spx_mode = 2; | |||||
| } | } | ||||
| } else | |||||
| av_log(avctx, AV_LOG_INFO, "Missing Speex header, assuming defaults.\n"); | |||||
| } | |||||
| mode = speex_lib_get_mode(spx_mode); | |||||
| if (!mode) { | |||||
| av_log(avctx, AV_LOG_ERROR, "Unknown Speex mode %d", spx_mode); | |||||
| return AVERROR_INVALIDDATA; | |||||
| } | |||||
| avctx->sample_rate = 8000 << spx_mode; | |||||
| if (avctx->channels > 2) { | |||||
| av_log(avctx, AV_LOG_ERROR, "Only stereo and mono are supported.\n"); | |||||
| return AVERROR(EINVAL); | |||||
| if (avctx->channels < 1 || avctx->channels > 2) { | |||||
| /* libspeex can handle mono or stereo if initialized as stereo */ | |||||
| av_log(avctx, AV_LOG_ERROR, "Invalid channel count: %d.\n" | |||||
| "Decoding as stereo.\n", avctx->channels); | |||||
| avctx->channels = 2; | |||||
| } | } | ||||
| speex_bits_init(&s->bits); | speex_bits_init(&s->bits); | ||||
| @@ -380,15 +380,15 @@ void av_blowfish_crypt(AVBlowfish *ctx, uint8_t *dst, const uint8_t *src, | |||||
| av_blowfish_crypt_ecb(ctx, &v0, &v1, decrypt); | av_blowfish_crypt_ecb(ctx, &v0, &v1, decrypt); | ||||
| AV_WB32(dst, v0); | |||||
| AV_WB32(dst + 4, v1); | |||||
| if (iv) { | if (iv) { | ||||
| for (i = 0; i < 8; i++) | |||||
| dst[i] = dst[i] ^ iv[i]; | |||||
| v0 ^= AV_RB32(iv); | |||||
| v1 ^= AV_RB32(iv + 4); | |||||
| memcpy(iv, src, 8); | memcpy(iv, src, 8); | ||||
| } | } | ||||
| AV_WB32(dst, v0); | |||||
| AV_WB32(dst + 4, v1); | |||||
| src += 8; | src += 8; | ||||
| dst += 8; | dst += 8; | ||||
| } | } | ||||
| @@ -509,32 +509,61 @@ static const uint32_t ciphertext_r[NUM_VARIABLE_KEY_TESTS] = { | |||||
| /* plaintext bytes */ | /* plaintext bytes */ | ||||
| static const uint8_t plaintext[8] = "BLOWFISH"; | static const uint8_t plaintext[8] = "BLOWFISH"; | ||||
| static const uint8_t plaintext2[16] = "BLOWFISHBLOWFISH"; | |||||
| /* ciphertext bytes */ | /* ciphertext bytes */ | ||||
| static const uint8_t ciphertext[8] = { | static const uint8_t ciphertext[8] = { | ||||
| 0x32, 0x4E, 0xD0, 0xFE, 0xF4, 0x13, 0xA2, 0x03 | 0x32, 0x4E, 0xD0, 0xFE, 0xF4, 0x13, 0xA2, 0x03 | ||||
| }; | }; | ||||
| static const uint8_t ciphertext2[16] = { | |||||
| 0x53, 0x00, 0x40, 0x06, 0x63, 0xf2, 0x1d, 0x99, | |||||
| 0x3b, 0x9b, 0x27, 0x64, 0x46, 0xfd, 0x20, 0xc1, | |||||
| }; | |||||
| #define IV "blowfish" | |||||
| #undef exit | |||||
| 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) | |||||
| { | |||||
| av_blowfish_crypt(ctx, dst, src, len, iv, dir); | |||||
| if (memcmp(dst, ref, 8*len)) { | |||||
| int i; | |||||
| printf("%s failed\ngot ", test); | |||||
| for (i = 0; i < 8*len; i++) | |||||
| printf("%02x ", dst[i]); | |||||
| printf("\nexpected "); | |||||
| for (i = 0; i < 8*len; i++) | |||||
| printf("%02x ", ref[i]); | |||||
| printf("\n"); | |||||
| exit(1); | |||||
| } | |||||
| } | |||||
| int main(void) | int main(void) | ||||
| { | { | ||||
| AVBlowfish ctx; | AVBlowfish ctx; | ||||
| uint32_t tmptext_l[NUM_VARIABLE_KEY_TESTS]; | uint32_t tmptext_l[NUM_VARIABLE_KEY_TESTS]; | ||||
| uint32_t tmptext_r[NUM_VARIABLE_KEY_TESTS]; | uint32_t tmptext_r[NUM_VARIABLE_KEY_TESTS]; | ||||
| uint8_t tmp[8]; | |||||
| uint8_t tmp[16], iv[8]; | |||||
| int i; | int i; | ||||
| av_blowfish_init(&ctx, "abcdefghijklmnopqrstuvwxyz", 26); | av_blowfish_init(&ctx, "abcdefghijklmnopqrstuvwxyz", 26); | ||||
| av_blowfish_crypt(&ctx, tmp, plaintext, 1, NULL, 0); | |||||
| if (memcmp(tmp, ciphertext, 8)) { | |||||
| printf("Test encryption failed.\n"); | |||||
| return 1; | |||||
| } | |||||
| av_blowfish_crypt(&ctx, tmp, ciphertext, 1, NULL, 1); | |||||
| if (memcmp(tmp, plaintext, 8)) { | |||||
| printf("Test decryption failed.\n"); | |||||
| return 1; | |||||
| } | |||||
| test_blowfish(&ctx, tmp, plaintext, ciphertext, 1, NULL, 0, "encryption"); | |||||
| test_blowfish(&ctx, tmp, ciphertext, plaintext, 1, NULL, 1, "decryption"); | |||||
| test_blowfish(&ctx, tmp, tmp, ciphertext, 1, NULL, 0, "Inplace encryption"); | |||||
| test_blowfish(&ctx, tmp, tmp, plaintext, 1, NULL, 1, "Inplace decryption"); | |||||
| memcpy(iv, IV, 8); | |||||
| test_blowfish(&ctx, tmp, plaintext2, ciphertext2, 2, iv, 0, "CBC encryption"); | |||||
| memcpy(iv, IV, 8); | |||||
| test_blowfish(&ctx, tmp, ciphertext2, plaintext2, 2, iv, 1, "CBC decryption"); | |||||
| memcpy(iv, IV, 8); | |||||
| test_blowfish(&ctx, tmp, tmp, ciphertext2, 2, iv, 0, "Inplace CBC encryption"); | |||||
| memcpy(iv, IV, 8); | |||||
| test_blowfish(&ctx, tmp, tmp, plaintext2, 2, iv, 1, "Inplace CBC decryption"); | |||||
| memcpy(tmptext_l, plaintext_l, sizeof(*plaintext_l) * NUM_VARIABLE_KEY_TESTS); | memcpy(tmptext_l, plaintext_l, sizeof(*plaintext_l) * NUM_VARIABLE_KEY_TESTS); | ||||
| memcpy(tmptext_r, plaintext_r, sizeof(*plaintext_r) * NUM_VARIABLE_KEY_TESTS); | memcpy(tmptext_r, plaintext_r, sizeof(*plaintext_r) * NUM_VARIABLE_KEY_TESTS); | ||||
| @@ -71,8 +71,6 @@ | |||||
| #define sprintf sprintf_is_forbidden_due_to_security_issues_use_snprintf | #define sprintf sprintf_is_forbidden_due_to_security_issues_use_snprintf | ||||
| #undef strcat | #undef strcat | ||||
| #define strcat strcat_is_forbidden_due_to_security_issues_use_av_strlcat | #define strcat strcat_is_forbidden_due_to_security_issues_use_av_strlcat | ||||
| #undef strncpy | |||||
| #define strncpy strncpy_is_forbidden_due_to_security_issues_use_av_strlcpy | |||||
| #undef exit | #undef exit | ||||
| #define exit exit_is_forbidden | #define exit exit_is_forbidden | ||||
| #undef printf | #undef printf | ||||
| @@ -96,8 +96,8 @@ static void xtea_crypt_ecb(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, | |||||
| DSTEP(0x9E3779B9U, k3, k0); | DSTEP(0x9E3779B9U, k3, k0); | ||||
| #endif | #endif | ||||
| if (iv) { | if (iv) { | ||||
| v0 ^= AV_RB32(iv ); | |||||
| v1 ^= AV_RB32(iv+4); | |||||
| v0 ^= AV_RB32(iv); | |||||
| v1 ^= AV_RB32(iv + 4); | |||||
| memcpy(iv, src, 8); | memcpy(iv, src, 8); | ||||
| } | } | ||||
| } else { | } else { | ||||
| @@ -220,27 +220,39 @@ static const uint8_t xtea_test_ct[XTEA_NUM_TESTS][8] = { | |||||
| { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 } | { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 } | ||||
| }; | }; | ||||
| #undef exit | |||||
| static void test_xtea(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, | |||||
| const uint8_t *ref, int len, uint8_t *iv, int dir, | |||||
| const char *test) | |||||
| { | |||||
| av_xtea_crypt(ctx, dst, src, len, iv, dir); | |||||
| if (memcmp(dst, ref, 8*len)) { | |||||
| int i; | |||||
| printf("%s failed\ngot ", test); | |||||
| for (i = 0; i < 8*len; i++) | |||||
| printf("%02x ", dst[i]); | |||||
| printf("\nexpected "); | |||||
| for (i = 0; i < 8*len; i++) | |||||
| printf("%02x ", ref[i]); | |||||
| printf("\n"); | |||||
| exit(1); | |||||
| } | |||||
| } | |||||
| int main(void) | int main(void) | ||||
| { | { | ||||
| AVXTEA ctx; | AVXTEA ctx; | ||||
| uint8_t buf[8], iv[8]; | uint8_t buf[8], iv[8]; | ||||
| int i; | int i; | ||||
| const uint8_t src[32] = "HelloWorldHelloWorldHelloWorld"; | const uint8_t src[32] = "HelloWorldHelloWorldHelloWorld"; | ||||
| uint8_t ct[32]; | |||||
| uint8_t pl[32]; | |||||
| #define CHECK(dst, src, ref, len, iv, dir, error) \ | |||||
| av_xtea_crypt(&ctx, dst, src, len, iv, dir);\ | |||||
| if (memcmp(dst, ref, 8*len)) {\ | |||||
| printf(error);\ | |||||
| return 1;\ | |||||
| } | |||||
| uint8_t ct[32]; | |||||
| uint8_t pl[32]; | |||||
| for (i = 0; i < XTEA_NUM_TESTS; i++) { | for (i = 0; i < XTEA_NUM_TESTS; i++) { | ||||
| av_xtea_init(&ctx, xtea_test_key[i]); | av_xtea_init(&ctx, xtea_test_key[i]); | ||||
| CHECK(buf, xtea_test_pt[i], xtea_test_ct[i], 1, NULL, 0, "Test encryption failed.\n"); | |||||
| CHECK(buf, xtea_test_ct[i], xtea_test_pt[i], 1, NULL, 1, "Test decryption failed.\n"); | |||||
| test_xtea(&ctx, buf, xtea_test_pt[i], xtea_test_ct[i], 1, NULL, 0, "encryption"); | |||||
| test_xtea(&ctx, buf, xtea_test_ct[i], xtea_test_pt[i], 1, NULL, 1, "decryption"); | |||||
| /* encrypt */ | /* encrypt */ | ||||
| memcpy(iv, "HALLO123", 8); | memcpy(iv, "HALLO123", 8); | ||||
| @@ -248,10 +260,10 @@ int main(void) | |||||
| /* decrypt into pl */ | /* decrypt into pl */ | ||||
| memcpy(iv, "HALLO123", 8); | memcpy(iv, "HALLO123", 8); | ||||
| CHECK(pl, ct, src, 4, iv, 1, "Test IV decryption failed.\n"); | |||||
| test_xtea(&ctx, pl, ct, src, 4, iv, 1, "CBC decryption"); | |||||
| memcpy(iv, "HALLO123", 8); | memcpy(iv, "HALLO123", 8); | ||||
| CHECK(ct, ct, src, 4, iv, 1, "Test IV inplace decryption failed.\n"); | |||||
| test_xtea(&ctx, ct, ct, src, 4, iv, 1, "CBC inplace decryption"); | |||||
| } | } | ||||
| printf("Test encryption/decryption success.\n"); | printf("Test encryption/decryption success.\n"); | ||||