Yubico Forum
https://forum.yubico.com/

Yubikey Simulator! HELP - need low level CRC-routine[SOLVED]
https://forum.yubico.com/viewtopic.php?f=16&t=69
Page 1 of 2

Author:  hasterguf [ Thu May 29, 2008 7:54 pm ]
Post subject:  Yubikey Simulator! HELP - need low level CRC-routine[SOLVED]

Hi,

I almost finished my php-yubikey simulator. It makes it possible to simulate a yubikey without actually having to reprogram your key. It's minded for development and testing purposes.

You can test it here: http://zyz.dk/yk/generator_0.2/yubi_generator.php

And the source-code is here: http://zyz.dk/yk/generator_0.2/yubi_generator.php.html

The only thing I need to finish it is the CRC-calculation, otherwise it works perfectly. I would appreciate if the yubikey-team could provide me with their low level CRC-calculation routine that their yubikey uses. Code in C would be fine :)

Best regards,
Alex

Author:  hasterguf [ Thu May 29, 2008 8:26 pm ]
Post subject:  Re: Yubikey Simulator! HELP - need low level CRC-routine...

.

Author:  Jakob [ Thu May 29, 2008 9:20 pm ]
Post subject:  Re: Yubikey Simulator! HELP - need low level CRC-routine...

It's an ISO13239 checksum - a simple implementation can be done as:

unsigned short crc;

void init_crc(void)
{
crc = 0xffff;
}

void update_crc(unsigned char val)
{
int i, j;

crc ^= val;
for (i = 0; i < 8; i++) {
j = crc & 1;
crc >>= 1;
if (j) crc ^= 0x8408;
}
}

void update_crc_buf(unsigned char *buf, int bcnt)
{
while (bcnt--) update_crc(*buf++);
}

The 13239 checksum is typically used in a way so the 2nd complement of the checksum is stored in the end of the buffer. Then, verification is done over the buffer and the crc shall then be 0xf0b8 if it all matches.

A simple test vector 55 aa 00 ff gives crc 0xcbb5. 2nd complement is 0x344a

Store crc in little-endian format, i.e. LSB first: 55 aa 00 ff 4a 34

Verify CRC by calculating over all six bytes = 0xf0b8

Hope this helps,

Regards,

Jakob E
Hardware and firmware guy @ Yubico

Author:  hasterguf [ Thu May 29, 2008 10:06 pm ]
Post subject:  Re: Yubikey Simulator! HELP - need low level CRC-routine...

Hi JakobE,

Yes that's the CRC routine I am trying to use, but it fails :(
Are you sure that's the one you use inside the yubikey to ENCODE (not decode) the CRC?

Best regards,
Alex

Author:  Jakob [ Thu May 29, 2008 10:29 pm ]
Post subject:  Re: Yubikey Simulator! HELP - need low level CRC-routine...

Yes - that's the one used. I'm not quite with you where it fails. Please indicate where in the steps below.

a) Strip the OTP part, i.e. the last 16 bytes received
a) Decode modhex - binary
b) Decrypt the OTP with the AES key
c) Verify the OTP CRC over all 16 bytes - the result shall be 0xf0b8

The Yubikey calculates the OTP CRC over the first bytes and stores the ~crc in 2nd complement, LSB first.

Please let me know if this resolved anything.

/ J

Author:  hasterguf [ Fri May 30, 2008 2:17 pm ]
Post subject:  Re: Yubikey Simulator! HELP - need low level CRC-routine...

Hi JakobE,

Thanks for your answer.

Here is a very small example with the CRC-routine that works for decoding.

The first echo-line from the code prints 0xF0B8 when I feed it with decoded data from my real hardware yubikey - thats great :) It means that the routine is ok for decoding crc.

In the next echo-line i feed the CRC-routine with exactly the same data except setting the two CRC-bytes to 0x0000 (because thats the one I want to calculate just like the youbikey would do internally). I did this according to your technical document on your homepage. Now i get back 0x92e5 and I was expecting 0xfc41 (like the crc from my real hardware yubikey).

So all of this is about emulating the hardware of the youbikey... I am building a homepage that is able to simulate a hardware yubikey. I am doing the opposite of everyone else that makes serverside authentication. I don't think the CRC encoding routine is the same as the decoding routine.

Code:
<?php
   $crc=crc(pack('H*',"e2e417f4ad3b2d00af47071217bd41fc"));
   echo dechex($crc)."<br>";

   $crc=crc(pack('H*',"e2e417f4ad3b2d00af47071217bd0000"));
   echo dechex($crc)."<br>";

   
   function crc($buffer)
   {
      $m_crc=0xffff;
      for($bpos=0; $bpos<16; $bpos++)
      {
         $m_crc ^= ord($buffer[$bpos]) & 0xff;
         for ($i=0; $i<8; $i++)
         {
            $j=$m_crc & 1;
            $m_crc >>= 1;
            if ($j) $m_crc ^= 0x8408;
         }
      }
      return $m_crc;
   }
?>

Author:  hasterguf [ Fri May 30, 2008 8:50 pm ]
Post subject:  Re: Yubikey Simulator! HELP - need low level CRC-routine...

Hi JakobE :)

I figured it out after hacking, trying and looping the crc parameters :)

It seems that the crc starting-point should be set to 0x5af0 instead of 0xffff and then I should only work on the 14 bytes instead of 16 :) But thanks for using your precious time to help me :) Have a nice weekend.

I already made a new forum-entry with my new fully working emulator :) Maybe you want to link to it in the development section of your site?

Best regards,
Alex

Author:  fortean [ Wed Aug 26, 2009 8:14 pm ]
Post subject:  Re: Yubikey Simulator! HELP - need low level CRC-routine...

JakobE wrote:
A simple test vector 55 aa 00 ff gives crc 0xcbb5. 2nd complement is 0x344a


I respectfully disagree (after spending some time scrutinizing my algorithms which consequently reported back 0x344b as the 2's complement of 0xcbb5). Shouldn't it be 0x344_B_...?

Code:
   
C    B    B    5
1100 1011 1011 0101
0011 0100 0100 1010  flipped bits
0011 0100 0100 1011  added one
3    4    4    B     

Author:  fortean [ Wed Aug 26, 2009 9:33 pm ]
Post subject:  Re: Yubikey Simulator! HELP - need low level CRC-routine...

I am still wrestling with this. I wrote some javacode (gruesome language, but I had to as I am programming a Yubikey emulation for the Android G1). Now, to test it it used the array as you suggested it to be:

Code:
int [] input = {
              0x55, 0xaa, 0x00, 0xff, 0x4a, 0x34
};


(Yes, I know, that are int's. I have to use int's, as sick Java does not dig unsigned bytes.. :shock: )

Next I wrote a little class that contains the method getcrc - it calculates the CRC over it's input array of 'bytes' (integers..). Parameters are the array and the number of 'bytes' it should use to calculate the checksum. I also wrote a method 'TwoComplement' that does what you think it does, namely: invert the bits and add one.

Then I did:

Code:
java.lang.Integer.toHexString( modhex.TwoComplement(modhex.getcrc( input, 4 )); 


.. which gave me 0x344b (not 0x344a) ...

and then I did:
Code:
java.lang.Integer.toHexString( modhex.getcrc(input,6));


.. which gave me 0xf0b8 (the correct checksum).

Now, I am puzzled.

If, instead of using the 2's complement I simply flip bits, it all works as you predicted. Can you help out: do we need to use 2nd complement (and hence your example was flawed) or not? Or..??

Author:  Jakob [ Fri Aug 28, 2009 9:26 pm ]
Post subject:  Re: Yubikey Simulator! HELP - need low level CRC-routine[SOLVED]

Sorry - I'm the offender here. The example above states 2nd complement which of course is wrong. 1st complement (= bit flip) is thw way to go.

To quickly summarize the steps:

a) Calculate the ISO13239 checksum over the bytes, in this case 55 aa 00 ff which gives 0xcbb5

b) Make 1st complement (flip bits) which gives 0x344a

c) Append the CRC with LSB first, i.e. 4a 34

c) Verify the checksum over the checksummed byte string 55 aa 00 ff 4a 34 gives 0xf0b8 which is the correct residue

Again - terribly sorry for the error and the confusion it has created.

Regards,

JakobE
Hardware- and firmware guy @ Yubico

Page 1 of 2 All times are UTC + 1 hour
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/