1: %% 2: %% %CopyrightBegin% 3: %% 4: %% Copyright Ericsson AB 1999-2011. All Rights Reserved. 5: %% 6: %% The contents of this file are subject to the Erlang Public License, 7: %% Version 1.1, (the "License"); you may not use this file except in 8: %% compliance with the License. You should have received a copy of the 9: %% Erlang Public License along with this software. If not, it can be 10: %% retrieved online at http://www.erlang.org/. 11: %% 12: %% Software distributed under the License is distributed on an "AS IS" 13: %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 14: %% the License for the specific language governing rights and limitations 15: %% under the License. 16: %% 17: %% %CopyrightEnd% 18: %% 19: 20: -module(crypto_SUITE). 21: 22: -include_lib("test_server/include/test_server.hrl"). 23: 24: -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, 25: init_per_group/2,end_per_group/2, 26: t_md5/1,t_md5_update/1,error/1,unaligned_context/1,random_lists/1, 27: misc_errors/1]). 28: 29: suite() -> [{ct_hooks,[ts_install_cth]}]. 30: 31: all() -> 32: [t_md5, t_md5_update, error, unaligned_context, 33: random_lists, misc_errors]. 34: 35: groups() -> 36: []. 37: 38: init_per_suite(Config) -> 39: Config. 40: 41: end_per_suite(_Config) -> 42: ok. 43: 44: init_per_group(_GroupName, Config) -> 45: Config. 46: 47: end_per_group(_GroupName, Config) -> 48: Config. 49: 50: 51: 52: misc_errors(doc) -> 53: ["Test crc32, adler32 and md5 error cases not covered by other tests"]; 54: misc_errors(suite) -> 55: []; 56: misc_errors(Config) when is_list(Config) -> 57: ?line Dog = test_server:timetrap(test_server:minutes(2)), 58: ?line 1 = erlang:adler32([]), 59: ?line L = lists:duplicate(600,3), 60: ?line 1135871753 = erlang:adler32(L), 61: ?line L2 = lists:duplicate(22000,3), 62: ?line 1100939744 = erlang:adler32(L2), 63: ?line {'EXIT', {badarg,_}} = (catch erlang:adler32(L++[a])), 64: ?line {'EXIT', {badarg,_}} = (catch erlang:crc32(L++[a])), 65: ?line {'EXIT', {badarg,_}} = (catch erlang:crc32([1,2,3|<<25:7>>])), 66: ?line {'EXIT', {badarg,_}} = (catch erlang:crc32([1,2,3|4])), 67: ?line Big = 111111111111111111111111111111, 68: ?line {'EXIT', {badarg,_}} = (catch erlang:crc32(Big,<<"hej">>)), 69: ?line {'EXIT', {badarg,_}} = (catch erlang:crc32(25,[1,2,3|4])), 70: ?line {'EXIT', {badarg,_}} = (catch erlang:crc32_combine(Big,3,3)), 71: ?line {'EXIT', {badarg,_}} = (catch erlang:crc32_combine(3,Big,3)), 72: ?line {'EXIT', {badarg,_}} = (catch erlang:crc32_combine(3,3,Big)), 73: ?line {'EXIT', {badarg,_}} = (catch erlang:adler32(Big,<<"hej">>)), 74: ?line {'EXIT', {badarg,_}} = (catch erlang:adler32(25,[1,2,3|4])), 75: ?line {'EXIT', {badarg,_}} = (catch erlang:adler32_combine(Big,3,3)), 76: ?line {'EXIT', {badarg,_}} = (catch erlang:adler32_combine(3,Big,3)), 77: ?line {'EXIT', {badarg,_}} = (catch erlang:adler32_combine(3,3,Big)), 78: ?line {'EXIT', {badarg,_}} = (catch erlang:md5_update(<<"hej">>,<<"hej">>)), 79: ?line {'EXIT', {badarg,_}} = (catch erlang:md5_final(<<"hej">>)), 80: ?line test_server:timetrap_cancel(Dog), 81: ok. 82: 83: 84: %% 85: %% Most of the real code for these test cases are in 86: %% the modules crypto_reference and random_iolist. 87: %% 88: -define(REF,crypto_reference). 89: 90: nicesplit(N,L) -> 91: nicesplit(N,L,[]). 92: nicesplit(0,Tail,Acc) -> 93: {lists:reverse(Acc),Tail}; 94: nicesplit(_,[],Acc) -> 95: {lists:reverse(Acc),[]}; 96: nicesplit(N,[H|Tail],Acc) -> 97: nicesplit(N-1,Tail,[H|Acc]). 98: 99: run_in_para([],_) -> 100: true; 101: run_in_para(FunList,Schedulers) -> 102: {ThisTime,NextTime} = nicesplit(Schedulers,FunList), 103: case length(ThisTime) of 104: 1 -> 105: [{L,Fun}] = ThisTime, 106: try 107: Fun() 108: catch 109: _:Reason -> 110: exit({error_at_line,L,Reason}) 111: end; 112: _ -> 113: These = [ {L,erlang:spawn_monitor(F)} || {L,F} <- ThisTime ], 114: collect_workers(These) 115: end, 116: run_in_para(NextTime,Schedulers). 117: 118: collect_workers([]) -> 119: ok; 120: collect_workers([{L,{Pid,Ref}}|T]) -> 121: receive 122: {'DOWN',Ref,process,Pid,normal} -> 123: collect_workers(T); 124: {'DOWN',Ref,process,Pid,Other} -> 125: exit({error_at_line,L,Other}) 126: end. 127: 128: random_lists(doc) -> 129: ["Test crc32, adler32 and md5 on a number of pseudo-randomly generated " 130: "lists."]; 131: random_lists(suite) -> 132: []; 133: random_lists(Config) when is_list(Config) -> 134: ?line Dog = test_server:timetrap(test_server:minutes(5)), 135: ?line Num = erlang:system_info(schedulers_online), 136: ?line B = list_to_binary( 137: lists:duplicate( 138: (erlang:system_info(context_reductions)*10) - 50,$!)), 139: ?line CRC32_1 = fun(L) -> erlang:crc32(L) end, 140: ?line CRC32_2 = fun(L) -> ?REF:crc32(L) end, 141: ?line ADLER32_1 = fun(L) -> erlang:adler32(L) end, 142: ?line ADLER32_2 = fun(L) -> ?REF:adler32(L) end, 143: ?line MD5_1 = fun(L) -> erlang:md5(L) end, 144: ?line MD5_2 = fun(L) -> ?REF:md5_final( 145: ?REF:md5_update(?REF:md5_init(),L)) end, 146: ?line MD5_3 = fun(L) -> erlang:md5_final( 147: erlang:md5_update(erlang:md5_init(),L)) end, 148: ?line CRC32_1_L = fun(L) -> erlang:crc32([B|L]) end, 149: ?line CRC32_2_L = fun(L) -> ?REF:crc32([B|L]) end, 150: ?line ADLER32_1_L = fun(L) -> erlang:adler32([B|L]) end, 151: ?line ADLER32_2_L = fun(L) -> ?REF:adler32([B|L]) end, 152: ?line MD5_1_L = fun(L) -> erlang:md5([B|L]) end, 153: ?line MD5_2_L = fun(L) -> ?REF:md5_final( 154: ?REF:md5_update(?REF:md5_init(),[B|L])) end, 155: ?line MD5_3_L = fun(L) -> erlang:md5_final( 156: erlang:md5_update( 157: erlang:md5_init(),[B|L])) end, 158: ?line Wlist0 = 159: [{?LINE, fun() -> random_iolist:run(150, CRC32_1, CRC32_2) end}, 160: {?LINE, fun() -> random_iolist:run(150, ADLER32_1, ADLER32_2) end}, 161: {?LINE, fun() -> random_iolist:run(150,MD5_1,MD5_2) end}, 162: {?LINE, fun() -> random_iolist:run(150,MD5_1,MD5_3) end}, 163: {?LINE, fun() -> random_iolist:run(150, CRC32_1_L, CRC32_2_L) end}, 164: {?LINE, 165: fun() -> random_iolist:run(150, ADLER32_1_L, ADLER32_2_L) end}, 166: {?LINE, fun() -> random_iolist:run(150,MD5_1_L,MD5_2_L) end}, 167: {?LINE, fun() -> random_iolist:run(150,MD5_1_L,MD5_3_L) end}], 168: ?line run_in_para(Wlist0,Num), 169: ?line CRC32_1_2 = fun(L1,L2) -> erlang:crc32([L1,L2]) end, 170: ?line CRC32_2_2 = fun(L1,L2) -> erlang:crc32(erlang:crc32(L1),L2) end, 171: ?line CRC32_3_2 = fun(L1,L2) -> erlang:crc32_combine( 172: erlang:crc32(L1), 173: erlang:crc32(L2), 174: erlang:iolist_size(L2)) 175: end, 176: ?line ADLER32_1_2 = fun(L1,L2) -> erlang:adler32([L1,L2]) end, 177: ?line ADLER32_2_2 = fun(L1,L2) -> erlang:adler32( 178: erlang:adler32(L1),L2) end, 179: ?line ADLER32_3_2 = fun(L1,L2) -> erlang:adler32_combine( 180: erlang:adler32(L1), 181: erlang:adler32(L2), 182: erlang:iolist_size(L2)) 183: end, 184: ?line MD5_1_2 = fun(L1,L2) -> erlang:md5([L1,L2]) end, 185: ?line MD5_2_2 = fun(L1,L2) -> 186: erlang:md5_final( 187: erlang:md5_update( 188: erlang:md5_update( 189: erlang:md5_init(), 190: L1), 191: L2)) 192: end, 193: ?line CRC32_1_L_2 = fun(L1,L2) -> erlang:crc32([[B|L1],[B|L2]]) end, 194: ?line CRC32_2_L_2 = fun(L1,L2) -> erlang:crc32( 195: erlang:crc32([B|L1]),[B|L2]) end, 196: ?line CRC32_3_L_2 = fun(L1,L2) -> erlang:crc32_combine( 197: erlang:crc32([B|L1]), 198: erlang:crc32([B|L2]), 199: erlang:iolist_size([B|L2])) 200: end, 201: ?line ADLER32_1_L_2 = fun(L1,L2) -> erlang:adler32([[B|L1],[B|L2]]) end, 202: ?line ADLER32_2_L_2 = fun(L1,L2) -> erlang:adler32( 203: erlang:adler32([B|L1]), 204: [B|L2]) 205: end, 206: ?line ADLER32_3_L_2 = fun(L1,L2) -> erlang:adler32_combine( 207: erlang:adler32([B|L1]), 208: erlang:adler32([B|L2]), 209: erlang:iolist_size([B|L2])) 210: end, 211: ?line MD5_1_L_2 = fun(L1,L2) -> erlang:md5([[B|L1],[B|L2]]) end, 212: ?line MD5_2_L_2 = fun(L1,L2) -> 213: erlang:md5_final( 214: erlang:md5_update( 215: erlang:md5_update( 216: erlang:md5_init(), 217: [B|L1]), 218: [B|L2])) 219: end, 220: ?line Wlist1 = 221: [{?LINE, fun() -> random_iolist:run2(150,CRC32_1_2,CRC32_2_2) end}, 222: {?LINE, fun() -> random_iolist:run2(150,CRC32_1_2,CRC32_3_2) end}, 223: {?LINE, fun() -> random_iolist:run2(150,ADLER32_1_2,ADLER32_2_2) end}, 224: {?LINE, fun() -> random_iolist:run2(150,ADLER32_1_2,ADLER32_3_2) end}, 225: {?LINE, fun() -> random_iolist:run2(150,MD5_1_2,MD5_2_2) end}, 226: {?LINE, fun() -> random_iolist:run2(150,CRC32_1_L_2,CRC32_2_L_2) end}, 227: {?LINE, fun() -> random_iolist:run2(150,CRC32_1_L_2,CRC32_3_L_2) end}, 228: {?LINE, 229: fun() -> random_iolist:run2(150,ADLER32_1_L_2,ADLER32_2_L_2) end}, 230: {?LINE, 231: fun() -> random_iolist:run2(150,ADLER32_1_L_2,ADLER32_3_L_2) end}, 232: {?LINE, fun() -> random_iolist:run2(150,MD5_1_L_2,MD5_2_L_2) end}], 233: ?line run_in_para(Wlist1,Num), 234: ?line test_server:timetrap_cancel(Dog), 235: ok. 236: 237: %% 238: %% 239: t_md5(doc) -> 240: ["Generate MD5 message digests and check the result. Examples are " 241: "from RFC-1321."]; 242: t_md5(Config) when is_list(Config) -> 243: ?line t_md5_test("", "d41d8cd98f00b204e9800998ecf8427e"), 244: ?line t_md5_test("a", "0cc175b9c0f1b6a831c399e269772661"), 245: ?line t_md5_test("abc", "900150983cd24fb0d6963f7d28e17f72"), 246: ?line t_md5_test(["message ","digest"], "f96b697d7cb7938d525a2f31aaf161d0"), 247: ?line t_md5_test(["message ",unaligned_sub_bin(<<"digest">>)], 248: "f96b697d7cb7938d525a2f31aaf161d0"), 249: ?line t_md5_test("abcdefghijklmnopqrstuvwxyz", 250: "c3fcd3d76192e4007dfb496cca67e13b"), 251: ?line t_md5_test("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" 252: "0123456789", 253: "d174ab98d277d9f5a5611c2c9f419d9f"), 254: ?line t_md5_test("12345678901234567890123456789012345678901234567890" 255: "123456789012345678901234567890", 256: "57edf4a22be3c955ac49da2e2107b67a"), 257: ok. 258: 259: %% 260: %% 261: t_md5_update(doc) -> 262: ["Generate MD5 message using md5_init, md5_update, and md5_final, and" 263: "check the result. Examples are from RFC-1321."]; 264: t_md5_update(Config) when is_list(Config) -> 265: ?line t_md5_update_1(fun(Str) -> Str end), 266: ?line t_md5_update_1(fun(Str) -> list_to_binary(Str) end), 267: ?line t_md5_update_1(fun(Str) -> unaligned_sub_bin(list_to_binary(Str)) end), 268: ok. 269: 270: t_md5_update_1(Tr) when is_function(Tr, 1) -> 271: Ctx = erlang:md5_init(), 272: Ctx1 = erlang:md5_update(Ctx, Tr("ABCDEFGHIJKLMNOPQRSTUVWXYZ")), 273: Ctx2 = erlang:md5_update(Ctx1, Tr("abcdefghijklmnopqrstuvwxyz" 274: "0123456789")), 275: m(erlang:md5_final(Ctx2), 276: hexstr2bin("d174ab98d277d9f5a5611c2c9f419d9f")), 277: ok. 278: 279: %% 280: %% 281: error(Config) when is_list(Config) -> 282: ?line {'EXIT',{badarg,_}} = (catch erlang:md5(bit_sized_binary(<<"abc">>))), 283: ?line Ctx0 = erlang:md5_init(), 284: ?line {'EXIT',{badarg,_}} = 285: (catch erlang:md5_update(Ctx0, bit_sized_binary(<<"abcfjldjd">>))), 286: ?line {'EXIT',{badarg,_}} = 287: (catch erlang:md5_update(Ctx0, ["something",bit_sized_binary(<<"abcfjldjd">>)])), 288: ?line {'EXIT',{badarg,_}} = 289: (catch erlang:md5_update(bit_sized_binary(Ctx0), "something")), 290: ?line {'EXIT',{badarg,_}} = (catch erlang:md5_final(bit_sized_binary(Ctx0))), 291: ?line m(erlang:md5_final(Ctx0), hexstr2bin("d41d8cd98f00b204e9800998ecf8427e")), 292: ok. 293: 294: 295: %% 296: %% 297: unaligned_context(Config) when is_list(Config) -> 298: ?line Ctx0 = erlang:md5_init(), 299: ?line Ctx1 = erlang:md5_update(unaligned_sub_bin(Ctx0), "ABCDEFGHIJKLMNOPQRSTUVWXYZ"), 300: ?line Ctx = erlang:md5_update(unaligned_sub_bin(Ctx1), 301: "abcdefghijklmnopqrstuvwxyz0123456789"), 302: ?line m(erlang:md5_final(unaligned_sub_bin(Ctx)), 303: hexstr2bin("d174ab98d277d9f5a5611c2c9f419d9f")), 304: ok. 305: 306: %% 307: %% Help functions 308: %% 309: 310: t_md5_test(Str, ResultStr) -> 311: ResultBin = hexstr2bin(ResultStr), 312: m(erlang:md5(Str), ResultBin), 313: Bin = list_to_binary(Str), 314: m(erlang:md5(Bin), ResultBin), 315: UnalignedSubBin = unaligned_sub_bin(Bin), 316: m(erlang:md5(UnalignedSubBin), ResultBin). 317: 318: m(X, X) -> true. 319: 320: hexstr2bin(S) -> 321: list_to_binary(hexstr2list(S)). 322: 323: hexstr2list([X,Y|T]) -> 324: [mkint(X)*16 + mkint(Y) | hexstr2list(T)]; 325: hexstr2list([]) -> 326: []. 327: 328: mkint(C) when $0 =< C, C =< $9 -> 329: C - $0; 330: mkint(C) when $A =< C, C =< $F -> 331: C - $A + 10; 332: mkint(C) when $a =< C, C =< $f -> 333: C - $a + 10. 334: 335: unaligned_sub_bin(Bin0) -> 336: Bin1 = <<0:3,Bin0/binary,31:5>>, 337: Sz = size(Bin0), 338: <<0:3,Bin:Sz/binary,31:5>> = id(Bin1), 339: Bin. 340: 341: %% Add 1 bit to the size of the binary. 342: bit_sized_binary(Bin0) -> 343: Bin = <<Bin0/binary,1:1>>, 344: BitSize = bit_size(Bin), 345: BitSize = 8*size(Bin) + 1, 346: Bin. 347: 348: id(I) -> I. 349: 350: