1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
5%%
6%% Licensed under the Apache License, Version 2.0 (the "License");
7%% you may not use this file except in compliance with the License.
8%% You may obtain a copy of the License at
9%%
10%%     http://www.apache.org/licenses/LICENSE-2.0
11%%
12%% Unless required by applicable law or agreed to in writing, software
13%% distributed under the License is distributed on an "AS IS" BASIS,
14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15%% See the License for the specific language governing permissions and
16%% limitations under the License.
17%%
18%% %CopyrightEnd%
19%%
20
21-module(ssl_cipher_SUITE).
22
23-behaviour(ct_suite).
24
25-include_lib("common_test/include/ct.hrl").
26-include("tls_record.hrl").
27-include("ssl_cipher.hrl").
28
29%% Callback functions
30-export([all/0,
31         groups/0,
32         init_per_suite/1,
33         end_per_suite/1,
34         init_per_group/2,
35         end_per_group/2,
36         init_per_testcase/2,
37         end_per_testcase/2]).
38
39%% Testcases
40-export([aes_decipher_good/0,
41         aes_decipher_good/1,
42         aes_decipher_fail/0,
43         aes_decipher_fail/1,
44         padding_test/1
45        ]).
46
47
48%%--------------------------------------------------------------------
49%% Common Test interface functions -----------------------------------
50%%--------------------------------------------------------------------
51all() ->
52    [aes_decipher_good, aes_decipher_fail, padding_test].
53
54groups() ->
55    [].
56
57init_per_suite(Config) ->
58    try crypto:start() of
59	ok ->
60	    Config
61    catch _:_  ->
62	    {skip, "Crypto did not start"}
63    end.
64
65end_per_suite(_Config) ->
66    ssl:stop(),
67    application:stop(crypto).
68
69init_per_group(_GroupName, Config) ->
70    Config.
71
72end_per_group(_GroupName, Config) ->
73    Config.
74
75init_per_testcase(_TestCase, Config) ->
76    ct:timetrap({seconds, 5}),
77    Config.
78
79end_per_testcase(_TestCase, Config) ->
80    Config.
81
82%%--------------------------------------------------------------------
83%% Test Cases --------------------------------------------------------
84%%--------------------------------------------------------------------
85aes_decipher_good() ->
86    [{doc,"Decipher a known cryptotext using a correct key"}].
87
88aes_decipher_good(Config) when is_list(Config) ->
89    HashSz = 32,
90    CipherState = correct_cipher_state(),
91    decipher_check_good(HashSz, CipherState, {3,0}),
92    decipher_check_good(HashSz, CipherState, {3,1}),
93    decipher_check_good(HashSz, CipherState, {3,2}),
94    decipher_check_good(HashSz, CipherState, {3,3}).
95
96%%--------------------------------------------------------------------
97aes_decipher_fail() ->
98    [{doc,"Decipher a known cryptotext using a incorrect key"}].
99
100aes_decipher_fail(Config) when is_list(Config) ->
101    HashSz = 32,
102    CipherState = incorrect_cipher_state(),
103    decipher_check_fail(HashSz, CipherState, {3,0}),
104    decipher_check_fail(HashSz, CipherState, {3,1}),
105    decipher_check_fail(HashSz, CipherState, {3,2}),
106    decipher_check_fail(HashSz, CipherState, {3,3}).
107
108%%--------------------------------------------------------------------
109padding_test(Config) when is_list(Config)  ->
110    HashSz = 16,
111    CipherState = correct_cipher_state(),
112    pad_test(HashSz, CipherState, {3,0}),
113    pad_test(HashSz, CipherState, {3,1}),
114    pad_test(HashSz, CipherState, {3,2}),
115    pad_test(HashSz, CipherState, {3,3}).
116
117%%--------------------------------------------------------------------
118% Internal functions  --------------------------------------------------------
119%%--------------------------------------------------------------------
120decipher_check_good(HashSz, CipherState, Version) ->
121    {Content, _NextIV, Mac} = content_nextiv_mac(Version),
122    {Content, Mac, _} =
123	ssl_cipher:decipher(?AES_CBC, HashSz, CipherState, aes_fragment(Version), Version, true).
124
125decipher_check_fail(HashSz, CipherState, Version) ->
126    {Content, NextIV, Mac} = content_nextiv_mac(Version),
127    true = {Content, Mac, #cipher_state{iv = NextIV}} =/=
128	ssl_cipher:decipher(?AES_CBC, HashSz, CipherState, aes_fragment(Version), Version, true).
129
130pad_test(HashSz, CipherState, {3,0} = Version) ->
131    %% 3.0 does not have padding test
132    {Content, NextIV, Mac} = badpad_content_nextiv_mac(Version),
133    {Content, Mac, #cipher_state{iv = NextIV}} =
134	ssl_cipher:decipher(?AES_CBC, HashSz, CipherState, badpad_aes_fragment({3,0}), {3,0}, true),
135    {Content, Mac, #cipher_state{iv = NextIV}} =
136	ssl_cipher:decipher(?AES_CBC, HashSz, CipherState, badpad_aes_fragment({3,0}), {3,0}, false);
137pad_test(HashSz, CipherState, {3,1} = Version) ->
138    %% 3.1 should have padding test, but may be disabled
139    {Content, NextIV, Mac} = badpad_content_nextiv_mac(Version),
140    BadCont = badpad_content(Content),
141    {Content, Mac, #cipher_state{iv = NextIV}} =
142	ssl_cipher:decipher(?AES_CBC, HashSz, CipherState, badpad_aes_fragment({3,1}) , {3,1}, false),
143    {BadCont, Mac, #cipher_state{iv = NextIV}} =
144	ssl_cipher:decipher(?AES_CBC, HashSz, CipherState, badpad_aes_fragment({3,1}), {3,1}, true);
145pad_test(HashSz, CipherState, Version) ->
146    %% 3.2 and 3.3 must have padding test
147    {Content, NextIV, Mac} = badpad_content_nextiv_mac(Version),
148    BadCont = badpad_content(Content),
149    {BadCont, Mac, #cipher_state{iv = NextIV}} = ssl_cipher:decipher(?AES_CBC, HashSz, CipherState,
150									      badpad_aes_fragment(Version), Version, false),
151    {BadCont, Mac, #cipher_state{iv = NextIV}} = ssl_cipher:decipher(?AES_CBC, HashSz, CipherState,
152								     badpad_aes_fragment(Version), Version, true).
153
154aes_fragment({3,N}) when N == 0; N == 1->
155    <<197,9,6,109,242,87,80,154,85,250,110,81,119,95,65,185,53,206,216,153,246,169,
156      119,177,178,238,248,174,253,220,242,81,33,0,177,251,91,44,247,53,183,198,165,
157      63,20,194,159,107>>;
158
159aes_fragment(_) ->
160    <<220,193,179,139,171,33,143,245,202,47,123,251,13,232,114,8,
161      190,162,74,31,186,227,119,155,94,74,119,79,169,193,240,160,
162      198,181,81,19,98,162,213,228,74,224,253,168,156,59,195,122,
163      108,101,107,242,20,15,169,150,163,107,101,94,93,104,241,165>>.
164
165badpad_aes_fragment({3,N})  when N == 0; N == 1 ->
166    <<186,139,125,10,118,21,26,248,120,108,193,104,87,118,145,79,225,55,228,10,105,
167      30,190,37,1,88,139,243,210,99,65,41>>;
168badpad_aes_fragment(_) ->
169    <<137,31,14,77,228,80,76,103,183,125,55,250,68,190,123,131,117,23,229,180,207,
170      94,121,137,117,157,109,99,113,61,190,138,131,229,201,120,142,179,172,48,77,
171      234,19,240,33,38,91,93>>.
172
173content_nextiv_mac({3,N})  when N == 0; N == 1 ->
174    {<<"HELLO\n">>,
175     <<72,196,247,97,62,213,222,109,210,204,217,186,172,184, 197,148>>,
176     <<71,136,212,107,223,200,70,232,127,116,148,205,232,35,158,113,237,174,15,217,192,168,35,8,6,107,107,233,25,174,90,111>>};
177content_nextiv_mac(_) ->
178    {<<"HELLO\n">>,
179     <<183,139,16,132,10,209,67,86,168,100,61,217,145,57,36,56>>,
180     <<71,136,212,107,223,200,70,232,127,116,148,205,232,35,158,113,237,174,15,217,192,168,35,8,6,107,107,233,25,174,90,111>>}.
181
182badpad_content_nextiv_mac({3,N})  when N == 0; N == 1 ->
183    {<<"HELLO\n">>,
184     <<225,55,228,10,105,30,190,37,1,88,139,243,210,99,65,41>>,
185      <<183,139,16,132,10,209,67,86,168,100,61,217,145,57,36,56>>
186    };
187badpad_content_nextiv_mac(_) ->
188    {<<"HELLO\n">>,
189     <<133,211,45,189,179,229,56,86,11,178,239,159,14,160,253,140>>,
190      <<183,139,16,132,10,209,67,86,168,100,61,217,145,57,36,56>>
191    }.
192
193badpad_content(Content) ->
194    %% BadContent will fail mac test
195    <<16#F0, Content/binary>>.
196
197correct_cipher_state() ->
198    #cipher_state{iv = <<59,201,85,117,188,206,224,136,5,109,46,70,104,79,4,9>>,
199		  key = <<72,196,247,97,62,213,222,109,210,204,217,186,172,184,197,148>>}.
200
201incorrect_cipher_state() ->
202    #cipher_state{iv = <<59,201,85,117,188,206,224,136,5,109,46,70,104,79,4,9>>,
203		  key = <<72,196,247,97,62,213,222,109,210,204,217,186,172,184,197,254>>}.
204
205