Tuesday, September 23, 2008

Laundry Part 3

Let's recall from last time: we're studying an Atmel AT88SC0404C ("CryptoMemory") in smart card form factor. We can communicate with it via a serial bus compatible with a regular PC serial port. We identified it using the Answer-to-Reset string, which ISO 7816 specifies all such cards must send when brought out of reset. Now we want to poke around the card a bit, hopefully doing something like reading the card's balance.
From this point on, the AT88SC0404C datasheet is an essential part of our work. At the very least, it's important to quickly scan it to get an idea of how the device works. There's a couple of tables you'll find yourself referring to fairly often:
  • Figure 4-10 (AT88SC0104C, 0204C, 0404C Configuration Memory) on page 14;
  • Table 8-2 (CryptoMemory Asynchronous Command Set) on page 41;
  • Table 8-3. Asychronous Mode Return Status Definitions.

The chip has some fuses that provide chip-level protection. Let's try to read the fuse status byte:
ATR 3b b2 11 00 10 80 00 04
--> 00 b6 01 00 01
<-- (b6) 20 [90 00]

That (b6) is the INS byte (command) sent back to us, the 20 is the fuse byte, and the trailing [90 00] is the status code. According to the datasheet (page 24), this means that all fuses have been blown.

The AT88SC0404C has a great deal of configuration memory (256 B); let's try to dump it using the "Read Config Zone" command. Keep in mind that bytes that we don't have rights to read will appear as 20 (the fuse byte):
ATR 3b b2 11 00 10 80 00 04
--> 00 b6 00 00 f0
<-- (b6) 3b b2 ... 20 20 [69 00]


Here's the data, formatted for comparing with the configuration zone map on page 14 (and with potentially identifying data removed):
000000 3b b2 11 00 10 80 00 04
000008 40 40 ff ff ff ff ff ff
000010 69 x2 08 x2 28 x0 40 x0
000018 bf 00 00 00 x0 x5 xd xb
000020 df 08 df 08 df 58 df 58
000028 ff ff ff ff ff ff ff ff
000030 ff ff ff ff ff ff ff ff
000038 ff ff ff ff ff ff ff ff
000040 ff ff ff ff ff ff ff ff
000048 ff ff ff ff ff ff ff ff
000050 ff 5d ae 47 5a 06 51 db
000058 20 20 20 20 20 20 20 20
000060 ff ff ff ff ff ff ff ff
000068 20 20 20 20 20 20 20 20
000070 ff ff ff ff ff ff ff ff
000078 20 20 20 20 20 20 20 20
000080 ff ff ff ff ff ff ff ff
000088 20 20 20 20 20 20 20 20
000090 20 20 20 20 20 20 20 20
000098 20 20 20 20 20 20 20 20
0000a0 20 20 20 20 20 20 20 20
0000a8 20 20 20 20 20 20 20 20
0000b0 ff 20 20 20 ff 20 20 20
0000b8 ff 20 20 20 ff 20 20 20
0000c0 ff 20 20 20 ff 20 20 20
0000c8 ff 20 20 20 ff 20 20 20
0000d0 ff 20 20 20 ff 20 20 20
0000d8 ff 20 20 20 ff 20 20 20
0000e0 ff 20 20 20 ff 20 20 20
0000e8 88 20 20 20 ff 20 20 20
0000f0 end


Let's take a look at some of the interesting fields and their values:
  • Offset 18h - DCR = BFh
  • Offset 19h - Identification Number Nc = "00 00 00 x0 x5 xd xb"
  • Offset 20h - AR0 = DFh
  • Offset 21h - PR0 = 08h
  • Offset 22h - AR1 = DFh
  • Offset 23h - PR2 = 08h
  • Offset 24h - AR2 = DFh
  • Offset 25h - PR2 = 58h
  • Offset 26h - AR3 = DFh
  • Offset 27h - PR3 = 58h
  • Offset 50h - Reserved for Authentication and Encryption = "ff 5d ae 47 5a 06 51 db"
  • Offset E8h - PAC = 88h
The DCR value is the Device Configuration Register and the meaning of its bits are explained in detail in section 5.3.8. The conclusion is that the Write 7 password (master password) has been disabled, "Unlimited Checksum Reads" is asserted, "Unlimited Authentication Trials" are not allowed and we are only allowed 4 incorrect password attempts before the device locks itself out in hardware, permanently. (Be careful not to "brick" your card!)

Next, we have an Identification Number that varies according to the number on the back of the card. It's not quite the same number, but the value of Nc does increase by 1 per every increment of the number of the back (i.e., it's just an offset).

The Access Registers are a bit more interesting. The AR values have PM(1:0)="11", meaning "no password", but since AM(1:0)="01", this means the cryptographic authentication protocol is in effect. "Encryption Required" is set to 1, which appears to mean deasserted. The rest of the bits aren't too interesting.

The Password Registers tell us that the device's user memory is split into two areas, accessed by different passwords/keys. The first half uses AK(1:0)="00" and POK(1:0)="00" and the second half uses AK(1:0)="01" and POK(1:0)="01".

The next part appears to be "Cryptograms" (section 5.3.12). This is most likely part of the cryptographic authentication protocol. The first page of the datasheet states that the chips use a "64-bit Mutual Authentication Protocol" under license from ELVA. If you look them up, they appear to be a French company that has filed patents on the topic to the US Patent Office: Method of enabling a server to authorize access to a service from portable... The patent makes reference to various cryptograms that get shuffled around to validate the identity of the device and/or host. Of course, the patent omits the details truly valuable to an implementation or for cryptoanalysis. (Okay, fine, I didn't read it all. If anyone finds and juicy details, please post!)

The very last field we can look at is the Password Attempts Counter for the Write 7 password. Because I attempted to validate the Write 7 password a couple times, this counter has decreased to 88h. This means I only have one attempt before the card locks itself out completely. Ouch! Don't do this at home!

Well, that's about it for now. I ordered a kit from Atmel that includes all the libraries, in binary format, needed to use the cryptographic authentication protocol. When I have something new to report, rest assured you'll be the first to know. Until then, 73.

-Cat


Saturday, July 12, 2008

Laundry, Semi-part 2b

To all my faithful readers:

It has been far too long since I've posted here. Unfortunately, my blog tends to take a rather low priority for me, and Real Life has been knocking on my door pretty insistently the past few months. Nonetheless, I will make an effort to post a bit more often and keep you posted on my techy adventures.

See you in a bit and don't give up on me!

-Cat

Thursday, January 24, 2008

Laundry Part 2

Here's the deal. We've got what looks like an ISO 7861 smartcard. It's used for "laundry," something most of us geeks reject as part of the alternate universe we like to call the "Real World." I digress. We're trying to communicate with this smartcard, hoping to unlock its secrets...

Let's start with a review of the electrical signals defined by the ISO standard.


VCC and Ground are pretty straightforward. Clock must be provided to the smartcard, TTL-level and on the order of 3 MHz. Input/Output is a bidirectional data pin; the protocol determines whether the host or the smartcard is driving this line at a given instant. The Reset signal is active-low.

We'll be connecting the I/O pin to a MAX-232 level shifter to convert the TTL level to the PC's RS-232 levels (and vice-versa). From the PC side, you have separate signals for transmit and receive; I connected the I/O pin directly to the PC's receive; the PC's transmit is spliced in with a 1 kOhm resistor. The resistor should limit the current in case something goes wrong, and in normal operation, the current is low enough that the voltage drop across the resistor isn't high enough to disturb data sent from the PC.

Now let's talk a bit about the protocol on this I/O pin. Right after reset, the card sends a block of data called the Answer to Reset (ATR); this is documented in section 2.3.4 of the standard. The baud is specified as being the input clock frequency divided by exactly 372. The other parameters are: 8 bits, even parity and one stop bit.

Assuming we want to work at a baud of 9600 (fairly typical baud for PC serial ports), this means we need an input frequency of 3.5712 MHz. While there's crystals out there that provide this frequency, I don't have one and I don't have a signal generator either. So I had to improvise.

I had laying around an Altera UP2 development board with a 25.175 MHz crystal. This is an educational board with a CPLD and an FPGA (programmable logic chips); I also happened to have a working copy of Quartus usable to create designs for the chips. I basically used a binary counter as a frequency divider from the main 25.175 MHz clock. In the end, it looked something like this:

Don't be deceived by the large board; it's just an oversized clock generator.

At first, I tried using a divisor of 7, which adds up to a baud of (25.175 MHz / 7 / 372 = ) 9668. This is really close to 9600, and most serial port receivers tolerate a certain margin of error, but 9668 turned out to be too far off; data become garbled after the first few bytes. If I settled for an I/O baud of 1200 bps, the required clock for the smartcard would be only 0.4464 MHz. With a divisor of 56, I would get a baud of 1208 bps, which was close enough for the serial port. I was able to get an ATR:

atr: read 8 bytes: atr: read 8 bytes: 3b b2 11 00 10 80 00 04

A quick Google search for this hex string quickly uncovered the identity of this smart card:

3B B2 11 00 10 80 00 04
Atmel memory card AT88SC0404C
http://www.atmel.com/dyn/resources/prod_documents/doc5210.pdf

Aha! Luckily, the datasheet is fairly explicit regarding the command set of the chip. But you'll have to wait until next time to see what happened when I started poking commands at it.

Tuesday, January 22, 2008

Laundry

Nowadays, it seems like real money (in the sense of cash) barely even exists anymore. We have debit cards, credit cards, paypal accounts, wire transfers... And in a sense, this is much more convenient than hiding 35 grams of gold under your pillow. On the other hand, as good as one may be at staring contests, it's a lot easier to convince a smart card that you put money on it than to convince 35 grams of gold that it's really 45 grams.

The laundry machines at my apartment building use SmartCity smart cards. There is a refill machine that takes debit (aka Interac) as well as credit cards. Here's what the cards look like (and the transcribed text for the benefit of search engines and visually impaired readers):


"SmartCity

Smart cards by Coinamatic

Canada's Most Trusted Name in Apartment Services™"


"Please treat this card like cash. The value on this card will not be replaced if the card is lost, stolen, destroyed, or altered. Use of this card constitutes acceptance of the terms and condition stated in the SmartCity® Resident Card Information section on http://www.coinamatic.com/
Questions? 1-800-561-1972 ou customerservices@coinamatic.com"

On the back, in the bottom-left corner, is what looks like a 7-digit numeric serial number.

The electrical contacts you can see on the front side (first photo) are the typical ISO 7861 physical interface. Most (if not all) of these cards also obey the electrical interface and protocol defined by the same standard. Luckily for us, this means all we need to communicate with them is a clock generator, an RS-232 level shifter (MAX232) and a regular PC serial port.

Stay tuned for more details on what happened when I hooked the card up to my PC! For now, I've got some homework to do.

-Cat

Sunday, January 20, 2008

Back in Black

Yesterday, I came back from Montreal after having attended my 3rd CUSEC. I have attended the conference every year since my first year in Software Engineering and I have to say that I was very happy this year to see a continued commitment to high quality talks and a friendly and fun atmosphere all around.

I thoroughly enjoyed most of the keynotes, but Jeff Atwood's talk was particularly motivating to me. I remembered I had started this blog a long time ago, and abandoned it (alas, for this is the destiny of so many of my projects); Jeff reminded me that I did indeed have something to say to the world.

I'm a Software Engineer by University program; a versatile programmer by experience and a hacker at heart. It's hard to keep me from reverse engineering just about any piece of technology that happens to drop on my lap. I happily drop from the virtual world of ones and zeroes and get my hands dirty with my soldering iron.

As for most geeks, my home page speaks of me better than I can: http://vv.carleton.ca/~cat/

See you around the blogosphere!

Wednesday, December 29, 2004

Multimedia PHP Album Tutorial

...by me!

Take a look, feedback is highly appreciated:
PHP Album Tutorial

Sunday, November 14, 2004

Castles Made of Sand

Holy #$@* Jimi Hendrix was a genius!

Friday, November 12, 2004

Know Your Enemy

Come on
Yes I know my enemies
They're the teachers who taught me to fight me
Compromise
conformity
assimilation
submission
ignorance
hypocrisy
brutality
the elite
All of which are American dreams(8x)

- Rage Against The Machine - Know Your Enemy

Tuesday, October 26, 2004

Hookers and services

<Technobabble>
No, this post is not related to prostitution. It is, in fact, related to Windows hooks - just as bad. Well, no, not nearly.. Anyway!

First, I'd like to mention that rattle's article on Systemwide Windows Hooks without external DLL is what first sparked my interest in this. Thanks!

I've mainly been experimenting with WH_KEYBOARD and WH_KEYBOARD_LL. As mentionned by MSDN, the NT-specific WH_KEYBOARD_LL delivers notifications in the process that set the hook. This is especially interesing because it means no external DLL need be created. On the the other hand, it makes you wonder about the numerous context switches that will happen upon keyboard input.

The second point I want to explore is exactly that - the delivery of notifications. As far as I can see, hooks use some kind of Windows messages. If, after hooking, the thread is Sleeping or SleepExing (to put the thread in an alertable wait state), hooks are not called. If, however, it is in a GetMessage or PeekMessage-based message pump, it processes messages successfully. What's more, MsgWaitForMultipleObjects returns WAIT_OBJECT_0+nCount (indicative of a message queued in the thread's message queue) when a hook is about to be called.

The strange behavior in this entire system is that, given an application which does not have any windows or other message sources than the hooks, GetMessage never returns! In fact, PeekMessage returns FALSE and never returns a valid message in *lpMsg. The hook procedure gets called, it appears, from inside them (in GetMessage and MsgWaitForMultipleObjects). I always suspected there was much more to GetMessage than meets the eye!

So, take all this, and throw most of it away. This only happens for WH_KEYBOARD_LL and WH_MOUSE_LL (and possibly WH_JOURNALRECORD and WH_JOURNALPLAYBACK). All other hooks seem to still require an external DLL. But wait... My original goal was to hook when the process was registered as a service. Things start to get even weirder in this case.

The service (it may be worth mentionning that it is set as an "interactive service" - interaction with the desktop is permitted) seems to be able to use WH_KEYBOARD, but still to a very restricted extent. (Normal processes simply didn't have their hook procedure called at all.) I observed that the hook procedure is called when the events are being delivered to a console window. As soon as events are received by other windows, the hook stops functionning, and switching back to a console window does not "re-enable" it. (Note that the message processing is still necessary for services.)

Soon to come... Hooking in other desktops and window stations. Probably yet another ugly beast, but I love it. I love it all.
</Technobabble>

Sunday, October 24, 2004

*chemistry nerd here*

Outrageously cool:
http://antoine.frostburg.edu/chem/senese/101/electrons/faq/orange-streetlights.shtml
.. especially "a nightmarish, monochromatic black-and-yellow effect". I'd like to see this.

Sunday, October 17, 2004

Windows, oh, Windows

<Technobabble>
For the past few hours, I have been struggling with WinPcap to send RAW packets over a WAN interface. It just doesn't want to.

PacketSendPacket returns FALSE. Peeking into Packet32.c, it first checks if the adapter on which the packet is to be sent is an NDIS adapter. Since WAN adapters don't qualify as such, a write isn't even attempted. If, however, I force a WriteFile of the packet, it fails with ERROR_INVALID_HANDLE (error 6). Go figure.

I was determined not to stop there. The NPF driver's IRP_MJ_WRITE handler is NPF_Write, in Write.c. I don't know enough about kernel programming or debugging to go further than staring at the handler blankly. I suspect NdisSend (line 129) might cause the ERROR_INVALID_HANDLE, because the handle refers to an NDISWAN adapter, rather than an NDIS adapter? (I'm not very familiar with the Windows network driver architecture, either.)

Any help would be highly appreciated!
</Technobabble>

Wednesday, October 13, 2004

Hacking Winamp... well not really

<Technobabble>
I've posted a small description of my creation on the Winamp forums, and I will duplicate it here, for I see no reason to reformulate what I've already written.


I was trying to get a program to retrieve the current track name from Winamp. To my disappointment, the IPC messages are divided in general-use and in-process messages. My first through was that I would have to go through the hassle of writing a general plugin, just for getting the track name!

However, there's another solution. Fortunately, Windows (NT+ definitely, not sure about 9x) allows you to read other processes' memory without having to inject a DLL in them. Later realizing that Winamp (probably) returns a static buffer from IPC_GETPLAYLISTTITLE relieved me, because that meant the lifetime of the buffer was rather long.

(For conciseness in my blog, you will need to click on the following link to see the actual code.)


...this general technique can be applied for most, if not all, "in-process" IPCs. For the messages that require you to pass a pointer to some data (ex. IPC_SETSKIN), one can use VirtualAllocEx to allocate memory in Winamp's process, and then WriteProcessMemory to transfer the data. The message can then be sent, and the memory can finally be freed with VirtualFreeEx. The downside is that VirtualAlloc/FreeEx are only supported in Windows NT and later.
</Technobabble>

Tuesday, October 12, 2004

Fatigue, addiction, school and poetry

Going to bed late is really bad for you, from a day-to-day productiveness point of view. Not only do you look like crap, you don't feel like doing anything, either.

But it keeps happening to so many of us, regularly. It's chronic lack of sleep, and it seems to be slightly addictive. Night after night, I don't feel like going to sleep because...?

In a way, this sleeplessness makes me somewhat drowsy, if not partly unconscious. Similarly to the way I imagine (since I've never experienced them) being under the influence of alcohol or drugs, specifically psychedelics, it renders you more "loose" from a social point of view and sheds light on certain things that might not have occured to you before. Some ideas are much more focused, and it seems like answers to various problems are within reach. But is the mind just playing tricks on itself? Are these ideas truly there, and can they really be of any use to us?

Could this (potentially illusional) state of enlightenment be the reason drugs are so widespread? Could it be a prime cause of some of their addictive properties? Let us extend this theory and say that lack of sleep is addictive. Oh, boy!

Well, I was going to talk about school and how I feel with respect to it, its place in my life, and so on, about an hour ago when I started writing this entry. But now I don't really feel like it. :P

To finish off, I'd like to include an extract of The Rhyme of the Ancient Mariner by Samuel Taylor Coleridge, written around the 1800's. A quick Google search for "The Rhyme of the Ancient Mariner" yields many pertinent results, should you choose to research it further.

Day after day, day after day,
We stuck, nor breath nor motion;
As idle as a painted ship
Upon a painted ocean.


Ciao!

Monday, October 11, 2004

TransmitFile

<Technobabble>
The TransmitFile API is friggin' cool!

Well.. it's pretty cool, but not developed enough, in my opinion. It's a great idea because efficiency goes up significantly - it saves at least two buffer copies, one ReadFile and one send. Also, it uses the standard asynchronous I/O mechanism (the OVERLAPPED structure) and, knowing that SOCKETs are in fact HANDLEs under cloak, you can use the standard wait functions on the handle returned by socket.

One of its problems, however, is that there's no way (that I know of) to query the progress of a TransmitFile (in fact, is there a way to generally query the progress of an asynchronous I/O operation?). The OVERLAPPED structure does not change until the end of the operation, which is why GetOverlappedResult is useless.
Attempting to retrieve the file pointer during the operation constantly returns a position of 4096 bytes into the file (why 4096, I don't know).
Is there some ioctl or socket option to query the number of bytes sent on a given socket?
Either way, there must be some file pointer somewhere in AFD.SYS (this is the driver that carries out the actual operation)!

I've conceived a hack for this, however. Instead of sending the entire file in one call, I use many calls that send "quantas". In the application, I dynamically adjust the quanta size to obtain roughly 500 ms per quanta (this allows for a reasonable refresh rate of the interface). Also, I found it prudent to provide "sanity checks" for the quanta size. My lower limit is 4096 bytes, while the upper limit is 262144 (256K) bytes.
</Technobabble>

Good morning!

This weekend of being alone at home has made me realize one very important thing. If my parents aren't around, there's no end to how late I will go to bed. Bad, especially since I plan on living by myself in university. *sigh*.

How's my blog?

I think I'm finally done fiddling with my blog template.. Hope you like the look!

My First Post... Ever!

Uhm, wow... I have a blog. Hum.
This blog has one purpose: to share and get feedback on, my ideas. Basically, this involves two main areas: programming, and personal matters.
Sharing and feedback play an equal role, in my opinion, so please do comment (anonymously, if you so wish) - I very much appreciate it.