[erlang-questions] Problem with legacy code when upgrading to R16B03

Felix Gallo felixgallo@REDACTED
Thu Feb 19 21:33:05 CET 2015

A constructive note: it's hard for readers (e.g. me) to reason about what's
happening without a full, minimal failing test case, including the data
you're passing in.  Just the act of creating a minimal failing test case is
also a great debugging step that often illuminates/solves the problem
(along the lines of 'rubber duck debugging' (
http://en.wikipedia.org/wiki/Rubber_duck_debugging)).  For example, maybe
you're passing in the wrong kind of data; that is very common and is
frequently exposed when you type it in a second time and look at it.

For the purposes of this discussion I created a test() function:

test() ->
  X = <<1:128>>,
  Y = <<1:53>>,
  Z = <<1:1>>,

and then I run it like so:

Eshell V6.1  (abort with ^G)
1> c(a),l(a),a:test().
Line 100
Line 97
** exception error: bad argument
     in function  a:pad_binary_128/1 (a.erl, line 12)
     in call from a:test/0 (a.erl, line 22)

and see your error when I am trying to use a 53 bit bitstring.

In this particular scenario that matches the clause:

pad_binary_128(Data) when bit_size(Data) < 128 ->
    io:format("Line ~p~n", [97]),

this appears to me be an excessively clever attempt to right-pad the binary
with zeroes.  In particular, the original author thought
<<Data/binary,0:1>> would construct a binary with one zero to the right,
and then recursion would continue until the string was 128 bits long.

As a debug step, let's break out the construction attempt from the function

New = <<Data/binary,0:1>>;

now we get the error at the constructor.  How exciting!

So we turn to the documentation (
http://www.erlang.org/doc/programming_examples/bit_syntax.html) and see
that you will get badarg errors when you attempt to construct a binary that
has an unaligned byte boundary -- e.g., anything not divisible by 8.  In
this case, Data/binary could be attempting to convert an unaligned
bitstring into a binary, which can't be done.

In order to fix the problem in a short term way, you could change that to
<<Data/bitstring, 0:1>> and it would run fine.  But it also recurses for
every single bit of padding, which is a little, ah, corkbrained.

Better would be to refactor this code a little so it's a bit more
sensible.  I am by no means an erlang grandmaster but here's how I
personally would do it.  The specs pass dialyzer and there's a brief test
suite that hits some of the high notes.



On Thu, Feb 19, 2015 at 11:02 AM, Ryan Brown <ryankbrown@REDACTED> wrote:

> Thank you Felix. I did get that to work standalone. It appears that there
> is something in the pad_binary method that I have not been able to
> track-down.
> In a crude attempt to trace the issue down, I added a bunch of io:formats
> and ran in the shell.
> pad_binary_128(Data) when bit_size(Data) > 128 ->
>   io:format("Line ~p~n", [89]),
>   {Kept, _Lost} = split_binary(Data, size(Data) - 1),
>   io:format("Line ~p~n", [94]),
>   pad_binary_128(Kept);
> pad_binary_128(Data) when bit_size(Data) < 128 ->
>   io:format("Line ~p~n", [97]),
>   pad_binary_128(<<Data/binary,0:1>>);
> pad_binary_128(Data) ->
>   io:format("Line ~p~n", [100]),
>   Data.
> This is the output I get:
> Line 97
> ** exception error: bad argument
>      in function  omac1:pad_binary_128/1 (src/omac1.erl, line 97)
>      in call from omac1:cmac_aes_cbc_128/6 (src/omac1.erl, line 78)
> So, it almost seems like there may be a difference in the way that
> bit_size/1 is handled in R1603. However, I do not see anything that
> stands-out to me in the docs.
> http://erldocs.com/R15B01/erts/erlang.html?i=0&search=erlang:bit#bit_size/1
> http://erldocs.com/R16B03/erts/erlang.html?i=0&search=erlang:bit#bit_size/1
> Thanks in advance.
> Best,
> Ryan
> On Tue, Feb 17, 2015 at 5:21 PM, Felix Gallo <felixgallo@REDACTED> wrote:
>> I made your same changes to the module, and also added the following
>> function to the module:
>> test() ->
>>   Key = <<1:128>>,
>>   Data = <<1:128>>,
>>   generate_tag_aes_cbc_128(Key, Data).
>> and when run in a shell:
>> Eshell V6.1  (abort with ^G)
>> 1> c(omac1),l(omac1),omac1:test().
>> <<173,219,62,66,7,255,149,96,196,74,41,116,238,229,211,35>>
>> this appears to work (at least, it doesn't crash with badarg.  I don't
>> know whether the data is correct).  Are you sure your aes key is 128, 192,
>> or 256 bits long?  It's possible the crypto module is throwing badarg when
>> it detects an improper length key.
>> On Tue, Feb 17, 2015 at 3:27 PM, Ryan Brown <ryankbrown@REDACTED> wrote:
>>> Thank you Felix. It looks like the aes_cbc_128_encrypt method is gone so
>>> I changed all to use crypto:block_encrypt(aes_cbc128, Key, IV,
>>> ToBeEncrypted)
>>> But alas, I'm still seeing the same error.
>>> On Tue, Feb 17, 2015 at 3:10 PM, Felix Gallo <felixgallo@REDACTED>
>>> wrote:
>>>> I'm not super familiar with the crypto library, but it looks like its
>>>> function signatures changed significantly between 15B01 and 16B03.  In
>>>> particular, it appears that some of the functions you are calling are no
>>>> longer in the library, and have been replaced with equivalents.
>>>> I suggest opening
>>>> http://erldocs.com/R15B01/crypto/crypto.html
>>>> and
>>>> http://erldocs.com/R16B03/crypto/crypto.html
>>>> and seeing if you can figure out where the changes occurred.  I suspect
>>>> those are the cause of your badargs.
>>>> F.
>>>> On Tue, Feb 17, 2015 at 1:55 PM, Ryan Brown <ryankbrown@REDACTED>
>>>> wrote:
>>>>> Hello all,
>>>>> I am in the process of upgrading a legacy application from R15B01 to
>>>>> R16B03 in order to get SHA 384 support. However, I am getting an error
>>>>> creating my CMAC from the library located here:
>>>>> https://github.com/PearsonEducation/subpub/blob/master/src/omac1.erl
>>>>> For the life of me I cannot find the root cause. I am just receiving a
>>>>> badarg error pointing to line 74.
>>>>> Any guidance would be greatly appreciated.
>>>>> Thank you.
>>>>> _______________________________________________
>>>>> erlang-questions mailing list
>>>>> erlang-questions@REDACTED
>>>>> http://erlang.org/mailman/listinfo/erlang-questions
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20150219/eacf326a/attachment.htm>

More information about the erlang-questions mailing list