xref: /netbsd-src/crypto/external/bsd/openssl/dist/test/recipes/70-test_sslcbcpadding.t (revision 7863ba460b0a05b553c754e5dbc29247dddec322)
1#! /usr/bin/env perl
2# Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
3#
4# Licensed under the OpenSSL license (the "License").  You may not use
5# this file except in compliance with the License.  You can obtain a copy
6# in the file LICENSE in the source distribution or at
7# https://www.openssl.org/source/license.html
8
9use strict;
10use OpenSSL::Test qw/:DEFAULT cmdstr srctop_file bldtop_dir/;
11use OpenSSL::Test::Utils;
12use TLSProxy::Proxy;
13
14my $test_name = "test_sslcbcpadding";
15setup($test_name);
16
17plan skip_all => "TLSProxy isn't usable on $^O"
18    if $^O =~ /^(VMS)$/;
19
20plan skip_all => "$test_name needs the dynamic engine feature enabled"
21    if disabled("engine") || disabled("dynamic-engine");
22
23plan skip_all => "$test_name needs the sock feature enabled"
24    if disabled("sock");
25
26plan skip_all => "$test_name needs TLSv1.2 enabled"
27    if disabled("tls1_2");
28
29$ENV{OPENSSL_ia32cap} = '~0x200000200000000';
30my $proxy = TLSProxy::Proxy->new(
31    \&add_maximal_padding_filter,
32    cmdstr(app(["openssl"]), display => 1),
33    srctop_file("apps", "server.pem"),
34    (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
35);
36
37# TODO: We could test all 256 values, but then the log file gets too large for
38# CI. See https://github.com/openssl/openssl/issues/1440.
39my @test_offsets = (0, 128, 254, 255);
40
41# Test that maximally-padded records are accepted.
42my $bad_padding_offset = -1;
43$proxy->start() or plan skip_all => "Unable to start up Proxy for tests";
44plan tests => 1 + scalar(@test_offsets);
45ok(TLSProxy::Message->success(), "Maximally-padded record test");
46
47# Test that invalid padding is rejected.
48foreach my $offset (@test_offsets) {
49    $proxy->clear();
50    $bad_padding_offset = $offset;
51    $proxy->start();
52    ok(TLSProxy::Message->fail(), "Invalid padding byte $bad_padding_offset");
53}
54
55sub add_maximal_padding_filter
56{
57    my $proxy = shift;
58
59    if ($proxy->flight == 0) {
60        # Disable Encrypt-then-MAC.
61        foreach my $message (@{$proxy->message_list}) {
62            if ($message->mt != TLSProxy::Message::MT_CLIENT_HELLO) {
63                next;
64            }
65
66            $message->delete_extension(TLSProxy::Message::EXT_ENCRYPT_THEN_MAC);
67            $message->process_extensions();
68            $message->repack();
69        }
70    }
71
72    if ($proxy->flight == 3) {
73        # Insert a maximally-padded record. Assume a block size of 16 (AES) and
74        # a MAC length of 20 (SHA-1).
75        my $block_size = 16;
76        my $mac_len = 20;
77
78        # Size the plaintext so that 256 is a valid padding.
79        my $plaintext_len = $block_size - ($mac_len % $block_size);
80        my $plaintext = "A" x $plaintext_len;
81
82        my $data = "B" x $block_size; # Explicit IV.
83        $data .= $plaintext;
84        $data .= TLSProxy::Proxy::fill_known_data($mac_len); # MAC.
85
86        # Add padding.
87        for (my $i = 0; $i < 256; $i++) {
88            if ($i == $bad_padding_offset) {
89                $data .= "\xfe";
90            } else {
91                $data .= "\xff";
92            }
93        }
94
95        my $record = TLSProxy::Record->new(
96            $proxy->flight,
97            TLSProxy::Record::RT_APPLICATION_DATA,
98            TLSProxy::Record::VERS_TLS_1_2,
99            length($data),
100            0,
101            length($data),
102            $plaintext_len,
103            $data,
104            $plaintext,
105        );
106
107        # Send the record immediately after the server Finished.
108        push @{$proxy->record_list}, $record;
109    }
110}
111