1
Description: Patch fixes CVE-2011-0766 (cryptographic weakness) vulnerability
2
in Erlang SSH application. It is taken from upstream git repository
3
https://github.com/erlang/otp/commit/f228601de45c5
5
Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=628456
6
Last-Updated: Tue, 03 Jan 2012 14:05:07 +0400
8
--- erlang-14.a-dfsg.orig/lib/crypto/c_src/crypto.c
9
+++ erlang-14.a-dfsg/lib/crypto/c_src/crypto.c
11
static ERL_NIF_TERM des_ede3_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
12
static ERL_NIF_TERM aes_cfb_128_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
13
static ERL_NIF_TERM rand_bytes_1(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
14
+static ERL_NIF_TERM strong_rand_bytes_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
15
static ERL_NIF_TERM rand_bytes_3(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
16
+static ERL_NIF_TERM strong_rand_mpint_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
17
static ERL_NIF_TERM rand_uniform_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
18
static ERL_NIF_TERM mod_exp_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
19
static ERL_NIF_TERM dss_verify(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
21
{"des_ede3_cbc_crypt", 6, des_ede3_cbc_crypt},
22
{"aes_cfb_128_crypt", 4, aes_cfb_128_crypt},
23
{"rand_bytes", 1, rand_bytes_1},
24
+ {"strong_rand_bytes_nif", 1, strong_rand_bytes_nif},
25
{"rand_bytes", 3, rand_bytes_3},
26
+ {"strong_rand_mpint_nif", 3, strong_rand_mpint_nif},
27
{"rand_uniform_nif", 2, rand_uniform_nif},
28
{"mod_exp_nif", 3, mod_exp_nif},
29
{"dss_verify", 4, dss_verify},
31
ERL_VALGRIND_MAKE_MEM_DEFINED(data, bytes);
34
+static ERL_NIF_TERM strong_rand_bytes_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
37
+ unsigned char* data;
39
+ if (!enif_get_uint(env, argv[0], &bytes)) {
40
+ return enif_make_badarg(env);
42
+ data = enif_make_new_binary(env, bytes, &ret);
43
+ if ( RAND_bytes(data, bytes) != 1) {
46
+ ERL_VALGRIND_MAKE_MEM_DEFINED(data, bytes);
50
static ERL_NIF_TERM rand_bytes_3(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
51
{/* (Bytes, TopMask, BottomMask) */
57
+static ERL_NIF_TERM strong_rand_mpint_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
58
+{/* (Bytes, TopMask, BottomMask) */
62
+ unsigned char* data;
65
+ if (!enif_get_uint(env, argv[0], &bits)
66
+ || !enif_get_int(env, argv[1], &top)
67
+ || !enif_get_int(env, argv[2], &bottom)) {
68
+ return enif_make_badarg(env);
70
+ if (! (top == -1 || top == 0 || top == 1) ) {
71
+ return enif_make_badarg(env);
73
+ if (! (bottom == 0 || bottom == 1) ) {
74
+ return enif_make_badarg(env);
79
+ return enif_make_badarg(env);
82
+ /* Get a (bits) bit random number */
83
+ if (!BN_rand(bn_rand, bits, top, bottom)) {
87
+ /* Copy the bignum into an erlang mpint binary. */
88
+ dlen = BN_num_bytes(bn_rand);
89
+ data = enif_make_new_binary(env, dlen+4, &ret);
90
+ put_int32(data, dlen);
91
+ BN_bn2bin(bn_rand, data+4);
92
+ ERL_VALGRIND_MAKE_MEM_DEFINED(data+4, dlen);
99
static int get_bn_from_mpint(ErlNifEnv* env, ERL_NIF_TERM term, BIGNUM** bnp)
101
--- erlang-14.a-dfsg.orig/lib/crypto/doc/src/crypto.xml
102
+++ erlang-14.a-dfsg/lib/crypto/doc/src/crypto.xml
107
+ <name>strong_rand_bytes(N) -> binary()</name>
108
+ <fsummary>Generate a binary of random bytes</fsummary>
110
+ <v>N = integer()</v>
113
+ <p>Generates N bytes randomly uniform 0..255, and returns the
114
+ result in a binary. Uses a cryptographically secure prng seeded and
115
+ periodically mixed with operating system provided entropy. By default
116
+ this is the <c>RAND_bytes</c> method from OpenSSL.</p>
117
+ <p>May throw exception <c>low_entropy</c> in case the random generator
118
+ failed due to lack of secure "randomness".</p>
122
<name>rand_uniform(Lo, Hi) -> N</name>
123
<fsummary>Generate a random number</fsummary>
129
+ <name>strong_rand_mpint(N, Top, Bottom) -> Mpint</name>
130
+ <fsummary>Generate an N bit random number</fsummary>
132
+ <v>N = non_neg_integer()</v>
133
+ <v>Top = -1 | 0 | 1</v>
134
+ <v>Bottom = 0 | 1</v>
135
+ <v>Mpint = binary()</v>
138
+ <p>Generate an N bit random number using OpenSSL's
139
+ cryptographically strong pseudo random number generator
140
+ <c>BN_rand</c>.</p>
141
+ <p>The parameter <c>Top</c> places constraints on the most
142
+ significant bits of the generated number. If <c>Top</c> is 1, then the
143
+ two most significant bits will be set to 1, if <c>Top</c> is 0, the
144
+ most significant bit will be 1, and if <c>Top</c> is -1 then no
145
+ constraints are applied and thus the generated number may be less than
147
+ <p>If <c>Bottom</c> is 1, then the generated number is
148
+ constrained to be odd.</p>
149
+ <p>May throw exception <c>low_entropy</c> in case the random generator
150
+ failed due to lack of secure "randomness".</p>
154
<name>mod_exp(N, P, M) -> Result</name>
155
<fsummary>Perform N ^ P mod M</fsummary>
157
--- erlang-14.a-dfsg.orig/lib/crypto/src/crypto.erl
158
+++ erlang-14.a-dfsg/lib/crypto/src/crypto.erl
160
-export([rsa_private_encrypt/3, rsa_public_decrypt/3]).
161
-export([dh_generate_key/1, dh_generate_key/2, dh_compute_key/3]).
162
-export([rand_bytes/1, rand_bytes/3, rand_uniform/2]).
163
+-export([strong_rand_bytes/1, strong_rand_mpint/3]).
164
-export([mod_exp/3, mpint/1, erlint/1]).
165
%% -export([idea_cbc_encrypt/3, idea_cbc_decrypt/3]).
166
-export([aes_cbc_128_encrypt/3, aes_cbc_128_decrypt/3]).
168
des_ede3_cbc_encrypt, des_ede3_cbc_decrypt,
169
aes_cfb_128_encrypt, aes_cfb_128_decrypt,
176
@@ -340,12 +343,32 @@
177
%% RAND - pseudo random numbers using RN_ functions in crypto lib
179
-spec rand_bytes(non_neg_integer()) -> binary().
180
+-spec strong_rand_bytes(non_neg_integer()) -> binary().
181
-spec rand_uniform(crypto_integer(), crypto_integer()) ->
183
+-spec strong_rand_mpint(Bits::non_neg_integer(),
185
+ Bottom::0..1) -> binary().
187
rand_bytes(_Bytes) -> ?nif_stub.
189
+strong_rand_bytes(Bytes) ->
190
+ case strong_rand_bytes_nif(Bytes) of
191
+ false -> erlang:error(low_entropy);
194
+strong_rand_bytes_nif(_Bytes) -> ?nif_stub.
196
rand_bytes(_Bytes, _Topmask, _Bottommask) -> ?nif_stub.
198
+strong_rand_mpint(Bits, Top, Bottom) ->
199
+ case strong_rand_mpint_nif(Bits,Top,Bottom) of
200
+ false -> erlang:error(low_entropy);
203
+strong_rand_mpint_nif(_Bits, _Top, _Bottom) -> ?nif_stub.
206
rand_uniform(From,To) when is_binary(From), is_binary(To) ->
207
case rand_uniform_nif(From,To) of
208
<<Len:32/integer, MSB, Rest/binary>> when MSB > 127 ->
209
--- erlang-14.a-dfsg.orig/lib/ssh/src/ssh.appup.src
210
+++ erlang-14.a-dfsg/lib/ssh/src/ssh.appup.src
215
+ {"2.0.3", [{load_module, ssh_bits, soft_purge, soft_purge, []},
216
+ {load_module, ssh_connection_handler, soft_purge, soft_purge, []},
217
+ {load_module, ssh_file, soft_purge, soft_purge, []},
218
+ {load_module, ssh, soft_purge, soft_purge, []},
219
+ {load_module, ssh_rsa, soft_purge, soft_purge, []},
220
+ {load_module, ssh_acceptor, soft_purge, soft_purge, []},
221
+ {load_module, ssh_transport, soft_purge, soft_purge, []},
222
+ {load_module, ssh_connection_manager, soft_purge, soft_purge, []}]},
223
+ {"2.0.2", [{load_module, ssh_bits, soft_purge, soft_purge, []},
224
+ {load_module, ssh_connection_handler, soft_purge, soft_purge, []},
225
+ {load_module, ssh_file, soft_purge, soft_purge, []},
226
+ {load_module, ssh, soft_purge, soft_purge, []},
227
+ {load_module, ssh_rsa, soft_purge, soft_purge, []},
228
+ {load_module, ssh_acceptor, soft_purge, soft_purge, []},
229
+ {load_module, ssh_transport, soft_purge, soft_purge, []},
230
+ {load_module, ssh_connection_manager, soft_purge, soft_purge, []}]}
233
+ {"2.0.3", [{load_module, ssh_bits, soft_purge, soft_purge, []},
234
+ {load_module, ssh_connection_handler, soft_purge, soft_purge, []},
235
+ {load_module, ssh_file, soft_purge, soft_purge, []},
236
+ {load_module, ssh, soft_purge, soft_purge, []},
237
+ {load_module, ssh_rsa, soft_purge, soft_purge, []},
238
+ {load_module, ssh_acceptor, soft_purge, soft_purge, []},
239
+ {load_module, ssh_transport, soft_purge, soft_purge, []},
240
+ {load_module, ssh_connection_manager, soft_purge, soft_purge, []}]},
241
+ {"2.0.2", [{load_module, ssh_bits, soft_purge, soft_purge, []},
242
+ {load_module, ssh_connection_handler, soft_purge, soft_purge, []},
243
+ {load_module, ssh_file, soft_purge, soft_purge, []},
244
+ {load_module, ssh, soft_purge, soft_purge, []},
245
+ {load_module, ssh_rsa, soft_purge, soft_purge, []},
246
+ {load_module, ssh_acceptor, soft_purge, soft_purge, []},
247
+ {load_module, ssh_transport, soft_purge, soft_purge, []},
248
+ {load_module, ssh_connection_manager, soft_purge, soft_purge, []}]}
252
--- erlang-14.a-dfsg.orig/lib/ssh/src/ssh_bits.erl
253
+++ erlang-14.a-dfsg/lib/ssh/src/ssh_bits.erl
257
-export([irandom/1, irandom/3]).
258
--export([random/1, random/3]).
259
+-export([random/1]).
260
-export([xor_bits/2, fill_bits/2]).
261
-export([i2bin/2, bin2i/1]).
267
-%% irandom_odd(Bits) ->
268
-%% irandom(Bits, 1, 1).
271
%% irandom(N, Top, Bottom)
273
@@ -414,57 +411,16 @@
274
%% Bot = 0 - do not set the least signifcant bit
275
%% Bot = 1 - set the least signifcant bit (i.e always odd)
277
-irandom(0, _Top, _Bottom) ->
279
-irandom(Bits, Top, Bottom) ->
280
- Bytes = (Bits+7) div 8,
281
- Skip = (8-(Bits rem 8)) rem 8,
282
- TMask = case Top of
287
- BMask = case Bottom of
291
- <<X:Bits/big-unsigned-integer, _:Skip>> = random(Bytes, TMask, BMask),
293
+irandom(Bits, Top, Bottom) when is_integer(Top),
294
+ 0 =< Top, Top =< 2 ->
295
+ crypto:erlint(crypto:strong_rand_mpint(Bits, Top - 1, Bottom)).
299
%% Generate N random bytes
304
-random(N, TMask, BMask) ->
305
- list_to_binary(rnd(N, TMask, BMask)).
308
-%% random(Bytes, TopMask, BotMask)
310
-%% Bytes is the number of bytes to generate
311
-%% TopMask is bitwised or'ed to the first byte
312
-%% BotMask is bitwised or'ed to the last byte
314
-rnd(0, _TMask, _BMask) ->
316
-rnd(1, TMask, BMask) ->
317
- [(rand8() bor TMask) bor BMask];
318
-rnd(N, TMask, BMask) ->
319
- [(rand8() bor TMask) | rnd_n(N-1, BMask)].
322
- [rand8() bor BMask];
324
- [rand8() | rnd_n(I-1, BMask)].
327
- (rand32() bsr 8) band 16#ff.
330
- random:uniform(16#100000000) -1.
331
+ crypto:strong_rand_bytes(N).
334
%% Base 64 encode/decode
335
--- erlang-14.a-dfsg.orig/lib/ssh/src/ssh_connection_handler.erl
336
+++ erlang-14.a-dfsg/lib/ssh/src/ssh_connection_handler.erl
339
%%--------------------------------------------------------------------
340
init([Role, Manager, Socket, SshOpts]) ->
341
- {A,B,C} = erlang:now(),
342
- random:seed(A, B, C),
343
{NumVsn, StrVsn} = ssh_transport:versions(Role, SshOpts),
344
ssh_bits:install_messages(ssh_transport:transport_messages(NumVsn)),
345
{Protocol, Callback, CloseTag} =