Download as pdf or txt
Download as pdf or txt
You are on page 1of 67

Phaedrus Systems Ltd

Encryption and Ciphers using 7816 for Smart Cards

by

Eur Ing Chris Hills BSc(Hons), C. Eng., MIEE, FRGS

September 2001

chris@phaedsys.org
www.phaedsys.org

Copyright Phaedrus Systems


Copyright Phaedrus Systems
Contents
Contents _________________________________________________________________ 3
History / Record of Changes ______________________________________________ 5
Release notes:-___________________________________________________________ 5
SCOPE ______________________________________________________________ 7
Dynamic Authentication______________________________________________ 9
Commands Using MAC/DES _________________________________________ 9
DES ________________________________________________________________ 11
Key Derivation______________________________________________________ 13
Unique Keys ________________________________________________________ 13
MAC DES Keys _____________________________________________________ 15
MAC Session Keys __________________________________________________ 15
MAC Computation __________________________________________________ 17
THEORY ________________________________________________________________17
Padding and Blocking___________________________________________________________17
MAC Session Key_______________________________________________________________17
Cryptogram Computation _______________________________________________________17
Process: ________________________________________________________________18
Data Flow for MAC Generation_______________________________________ 20
Generating An AC or an ARPC _______________________________________ 21
APPLICATION CRYPTOGRAM - ARQC / TC or AAC________________________________21
AUTHORISATION RESPONSE CRYPTOGRAM – ARPC ______________________________25
RSA ________________________________________________________________ 29
RSA Keys ___________________________________________________________ 30
Remaining digits of the issuers public key to be hashed ________________________ 30
File Security ________________________________________________________ 31
Cipher Sources _____________________________________________________ 33
DES Sources ____________________________________________________________33
C Source______________________________________________________________________33
8051 Assembler _______________________________________________________________43
SHA-1 ___________________________________________________________________57
GSM A3A8 algorithm. ( COMP128) ______________________________________60
References _________________________________________________________ 66

www.phaedsys.org  Phaedrus Systems Page 3 of 67


www.phaedsys.org  Phaedrus Systems Page 4 of 67
History / Record of Changes

CHANGE No. DATE ISSUE AUTHOR DETAILS OF CHANGE

- 13/08/97 A CAH First release for Initial review


(released as internal document)

- 4/Aug/01 1.0 CAH Additional material added. Principally the


ciphers.

Release notes:-

This document was originally produced as an internal document for a smart card project in
the UK in 1997-8. All the company/project specific parts have been removed and only
generic 7816, EMV, UKIS and cipher information remains. UKIS is a subset of 7816 used in UK
for APACS financial smart cards.

The cipher sources have been collected from several places all of them reputable but for
obvious reasons some of them are not attributed. None of them come with no guarantees of
any kind. You have to validate them for your own use.

www.phaedsys.org  Phaedrus Systems Page 5 of 67


www.phaedsys.org  Phaedrus Systems Page 6 of 67
SCOPE
The UKIS smart card working to 7816 requires security. Sending Message Authentication
Certificates (MAC) with certain messages ensures this. However the data in the message
itself is not encrypted. The card contains secret keys for this purpose. These keys are unique
and generated at personalisation time. These keys are used to generate session keys.

Apart from MAC’s they system requires transaction certificates that are also generated using
DEA in a similar manner to the MAC.

The card also contains other (RSA) keys that can be recovered from the card, using Read
Record that the terminal uses for static authentication. This does not require any involvement
by the card other than supplying the files.

There is also a method of read write access to the application and files. This is part of the file
system and outside the scope of this document.

www.phaedsys.org  Phaedrus Systems Page 7 of 67


www.phaedsys.org  Phaedrus Systems Page 8 of 67
Dynamic Authentication
Dynamic authentication is “online” authentication where the card talks (through the terminal)
to the issuer or host. When the card and the terminal verify each other without recourse to
the issuer it is static authentication. Dynamic authentication is undertaken using ISO DEA-1.

Commands Using MAC/DES


The following commands use validate MAC’s or generate application cryptograms. The
DEA-1 algorithm is used.

All Issuer Scripts Commands:


Application Block
Application Unblock
Card Block
Put Data

External Authenticate

Generate AC (Generate Application Cryptogram)

With the exception of the Generate AC all the commands receive a MAC or encrypted data.
They have to authenticate the command. With Gen AC the card receives a request for a an
encrypted certificate. The certificate it returns depends on the card risk management data.

Issuer script commands use secure messaging because they flow from the issuer not the
terminal. The terminal does not interpret the messages.

Issuer Script Commands (Secure Messaging)

Taking the Issuer script commands as a group they work as follows: The Issuer constructs the
message, which is sent to the terminal. The terminal sends the command to the card without
interpretation. The card validates the command and executes it. Issuer script commands may
contain data. For this implementation of UKIS only Put Data contains data, a one byte Lower
Consecutive Offline Limit (LCOL). In all cases the MAC is the last element of the message. The
Issuer Script Commands apply only to applications loaded during personalisation.

All the UKIS issuer Scripts only return SW1/SW2 ie NO RETURN DATA

The MAC is generated using all the command. UKIS (E 2.2 MAC Length) mandates the MAC is
8 bytes. In ALL cases the MAC is the last element of the command sent.

NB The MAC may, under EMV rules be 4 to 8 bytes and Visa recommends 4 bytes.

The second nibble of the CLA is 4h indicating secure messaging. The lead nibble of CLA
indicates the following: 8h = A standard ISO7816 format command that has proprietary
command and response. Fro Put Data 0h = ISO7816 command.

All data required to perform the Issuer Script Command shall be available to both Issuer and
the card operating system.

Whilst UKIS D2.1.2 Command Message section of Application Block states that “the header
consists of CLA, INS, P1 and P.” in UKIS E2.4 MAC Computation Step 2 it states “The
following data is concatenated in the order specified to create a block of data: CLA, INS, P1,

www.phaedsys.org  Phaedrus Systems Page 9 of 67


P2, Lc, ATC,LAC, DATA(if present)” VISA 1.3 6.3.2.4 also confirms this. LAC= Last
Application Cryptogram.

CLA, INS, P1, P2, Lc Data +MAC

App Block 0x84 0x1E 0x00 0x00 0x08 MAC


App Unblock 0x84 0x18 0x00 0x00 0x08 MAC
Card Block 0x84 0x16 0x00 0x00 0x08 MAC
Put Data 0x04 0xDA 0x9F 0x58 0x09 LCOL MAC

External Authenticate

CLA, INS, P1, P2, Lc, Data


0x00 0x82 0x00 0x00 0x0A ARPC + ARPC RC

Returns SW1/SW2

Generate AC
Generate Application Cryptogram is the only command that causes a cryptogram to be
generated and returned.

Command :
CLA, INS, P1, P2, Lc, Data
0x80 0xAE 0x00 0x00 0x1D CDOL1
0x40 0x1F CDOL2
0x80

Returns: SW1/SW2 + CID+ ATC+ AC+ le+ DKI+ CVN+ CVR


Length 1 1 1 2 8 1 1 1 4

CID = Cryptogram Information Data


ATC = Application Transaction Counter
AC = Application Cryptogram (DES certificate)
le = length of following data
DKI = Derivation Key Index
CVN = Cryptogram Version Number
CVR = Card Verification Results

DKI = Derivation Key Index

www.phaedsys.org  Phaedrus Systems Page 10 of 67


DES

This 64-bit block cipher is the approved algorithm for secure messaging and
is standardised in ISO 8731-1, ISO 8372, and ISO/IEC 10116. More precisely,
both the single DES encipherment and the triple DES encipherment versions
described below are approved to be used in the encipherment and MAC
mechanisms described in Annex E.

Triple DES encipherment involves enciphering an 8-byte plaintext block in an


8-byte ciphertext block with a double-length (16-byte) secret key K = (KL ||
KR) as follows:

Y = DES(KL)[DES-1(KR)[DES(KL)[X]]].

Decipherment takes place as follows:

X = DES-1(KL)[DES(KR)[DES-1(KL)[Y]]].

.
The encipherment mechanisms for secure messaging for confidentiality uses a
64-bit block cipher ALG either in Electronic Codebook (ECB) Mode or in
Cipher Block Chaining (CBC) mode.

Encipherment of a message MSG of arbitrary length with Encipherment


Session Key KS takes place in the following steps.

Padding and Blocking

If the message MSG has a length that is not a multiple of 8 bytes, add a ‘80’
byte to the right of MSG, and then add the smallest number of ‘00’ bytes to the
right such that the length of resulting message MSG := (MSG || ‘80’ || ‘00’ ||
‘00’ || . . . || ‘00’) is a multiple of 8 bytes.

If the message MSG has a length that is a multiple of 8 bytes, the following two
cases can occur depending on pre-defined rules (see Part IV of this
specification).

- No padding takes place: MSG := MSG.

- MSG is padded to the right with the 8-byte block

(‘80’ || ‘00’ || ‘00’ ||‘00’ || ‘00’ || ‘00’ || ‘00’ || ‘00’)

to obtain MSG.

MSG is then divided into 8-byte blocks X1, X2, . . . , Xk.

www.phaedsys.org  Phaedrus Systems Page 11 of 67


Cryptogram Computation

ECB Mode

Encipher the blocks X1, X2, . . . , Xk into the 8-byte blocks Y1, Y2, . . . , Yk with
the block cipher algorithm in ECB mode using the Encipherment Session Key
KS. Hence compute for i = 1, 2, . . . , k:
Yi := ALG(KS)[Xi].

CBC Mode

Encipher the blocks X1, X2, . . . , Xk into the 8-byte blocks Y1, Y2, . . . , Yk with
the block cipher algorithm in CBC mode using the Encipherment Session Key
KS. Hence compute for i = 1, 2, . . . , k:
Yi := ALG(KS)[Xi ⊕ Yi-1],

with initial value Y0 := (‘00’ || ‘00’ || ‘00’ || ‘00’ || ‘00’ || ‘00’ || ‘00’ ||
‘00’).

Notation:
Y := (Y1 || Y2 || . . . || Yk) = ENC(KS)[MSG].

Decipherment is as follows.

Cryptogram Decipherment

ECB Mode

Compute for i = 1, 2, . . . , k:
Xi := ALG-1(KS)[Yi ].

CBC Mode

Compute for i = 1, 2, . . . , k:
Xi := ALG-1(KS)[Yi ] ⊕ Yi-1,

with initial value Y0 := (‘00’ || ‘00’ || ‘00’ || ‘00’ || ‘00’ || ‘00’ || ‘00’ || ‘00’).

To obtain the original message MSG, concatenate the blocks X1, X2, . . . , Xk
and if padding has been used (see above) remove the trailing (‘80’ || ‘00’ ||
‘00’ || . . . || ‘00’) byte-string from the last block Xk.

Notation:
M = DEC(KS)[Y].

www.phaedsys.org  Phaedrus Systems Page 12 of 67


Key Derivation

Unique Keys

The Unique DEA Keys are used to perform online card authentication, online
issuer authentication and TC generation. The Unique DEA keys are stored in
the card during personalisation and are derived using the Application PAN1
and Application PAN Sequence Number.

Note: This derivation does not take place on the card.

To derive the Unique Key A, the Application PAN and Application PAN
Sequence Number are concatenated together into a 16-hexadecimal field. If
the Sequence Number is not present then it is zero filled. If the length of the
Application PAN followed by the Sequence Number is not equal to 16 digits
then the following rules apply:

− if the PAN plus the Sequence Number are less than 16 digits the
data is right justified in a 16-hexadecimal field and padded on the
left with ‘0’s

− if the PAN plus the Sequence Number are greater than 16 digits
only the rightmost 16 digits are used

Triple DEA encipherment (i.e. encipher, decipher, encipher), is then


performed using the Issuer generated double-length Derivation Key resulting
in the Unique Key A.

To derive the Unique Key B, the Application PAN and Application PAN
Sequence Number are concatenated together into a 16-hexadecimal field
using the formatting rules above and then inverted. Inversion takes place at
bit level where each bit with the value ‘1’ is set to ‘0’ and each bit with the
value ‘0’ is set to ‘1’.

Triple DEA encipherment is then performed using the Issuer generated


double-length Derivation Key resulting in the Unique Key B.

1
Primary Account Number

www.phaedsys.org  Phaedrus Systems Page 13 of 67


www.phaedsys.org  Phaedrus Systems Page 14 of 67
MAC DES Keys

The MAC DES Keys are calculated using the MAC Master Derivation Key and same method as
the Unique Keys. These are also generated and stored at personalisation time.

Note: This derivation does not take place on the card.

MAC Session Keys

The calculation of the MAC requires the use of MAC Session Keys, which are
derived using the card’s MAC DES Keys.

Session keys KS for secure messaging for integrity and confidentiality are
derived from unique Master Keys KM using diversification data R provided by
the receiving entity, hence
KS := F(KM)[R].

To prevent replay attacks, the diversification data R should either be


unpredictable, or at least different for each session key derivation.

The only requirement for the diversification function F is that the number of
possible outputs of the function is sufficiently large and uniformly distributed
to prevent an exhaustive key search on the session key.

1 MAC Session Key A

This key is generated using the following process:

− The Application Transaction Counter (ATC) returned by the card to


the terminal in response to the ‘Generate AC’ command, is right
justified in an 8-byte field and the remaining 6 bytes are set to 0x00.

− The terminal performs an exclusive-OR operation on the padded


ATC and the MAC Key A stored on the card

The result of the exclusive-OR is session key A for the ‘Maccing’ process.

2 MAC Session Key B

This key is generated using the following process:

− The ATC returned by the card to the terminal in response to the


‘Generate AC’ command is inverted. The card performs the

www.phaedsys.org  Phaedrus Systems Page 15 of 67


inversion at bit level, (i.e. each bit with the value ‘1’ is set to ‘0’ and
each bit with the value ‘0’ is set to ‘1’)

− The inverted ATC is then right justified in an 8-byte field and the
remaining 6 bytes are set to 0x00.

− An exclusive-OR operation is performed on the inverted and


padded ATC with the MAC Key B stored on the card

The result of the exclusive-OR is session key B for the ‘Maccing’ process.

Session Key
Create Session Created
Key
Creat Session
Key

Create Key A
Create Key B
Session Key
Session Key B Created
A Created

Create MAC Create MAC


Get keu B MAC Key B
Session Key A Session Key B
Get key A
MAC Key A
2 3

Session Key A Session Key B


Get ATC Get ATC

MAC Session MAC Session


Key A Key b
Application
Transaction
Counter

www.phaedsys.org  Phaedrus Systems Page 16 of 67


MAC Computation

THEORY
The computation of an s-byte MAC (4 ≤ s ≤ 8) is according to ISO/IEC 9797 using a 64-bit
block cipher ALG in CBC mode. More precisely, the computation of a MAC S over a
message MSG consisting of an arbitrary number of bytes with a MAC Session Key KS takes
place in the following steps.

Padding and Blocking

Pad the message M according to ISO 7816-4 (which is equivalent to method 2 of ISO/IEC
9797), hence add a mandatory ‘80’ byte to the right of MSG, and then add the smallest
number of ‘00’ bytes to the right such that the length of resulting message MSG := (MSG
|| ‘80’ || ‘00’ || ‘00’ || . . . || ‘00’) is a multiple of 8 bytes.

MSG is then divided into 8-byte blocks X1, X2, . . . , Xk.

MAC Session Key

The MAC Session Key KS either consists of only a leftmost key block KS = KSL or the
concatenation of a leftmost and a rightmost key block KS = (KSL || KSR).

Cryptogram Computation

Process the 8-byte blocks X1, X2, . . . , Xk with the block cipher in CBC mode using the
leftmost MAC Session Key block KSL:

Hi := ALG(KSL)[Xi ⊕ Hi-1], for i = 1, 2, . . . , k.

with initial value H0 := (‘00’ || ‘00’ || ‘00’ || ‘00’ || ‘00’ || ‘00’ || ‘00’ || ‘00’).

• Compute the 8 byte block Hk+1 in one of the following two ways. According to the
main process of ISO/IEC 9797:

Hk+1 := Hk.

• According to Optional Process 1 of ISO/IEC 9797:

Hk+1 := ALG(KSL)[ALG-1(KSR)[Hk]].

The MAC S is then equal to the s most significant bytes of Hk+1.

www.phaedsys.org  Phaedrus Systems Page 17 of 67


Process:

The MAC is generated using triple DEA encipherment with the MAC session
keys previously calculated as follows:

− An initial 8-byte vector is set to 0x00

− The following data is concatenated in the order specified to create a


block of data:

DATA NOTES
CLA Bytes of the script command sent to the card from the
INS terminal
P1
P2
Lc
ATC The last ATC sent to the terminal in the ‘Generate AC’
command
ARQC The last application cryptogram sent to the terminal in
the ‘Generate AC’ command
DATA Any ‘plain text’ data in the data field of the command
i.e. the Put Data’ command it would be the new value
for LCOL

− This block of data is formatted into 8-byte data blocks labelled D1,
D2, D3…D6…, (the last block may be between 1 and 8 bytes
depending on the length of the original data block)

− If the last block of data

‰ is 8 bytes in length then an additional 8-byte block is


concatenated to the right of the last data block and contains the
hexadecimal values

80 00 00 00 00 00 00 00

‰ is less than 8 bytes then 0x80 is concatenated to the end of the


block. If the new length of the block is still less than 8 bytes then
the byte is concatenated with 0x00 until it is 8 bytes in length

Note: The number of data blocks will depend on the original data block.

The MAC is then generated by:

1 the first data block becomes the first input block I1


2 the card will perform an exclusive-OR operation on the initial vector and
the input block I1 to give I2
3 I2 is encrypted using the DES encrypt algorithm and the MAC session
key A to give the output block O1

4 the card will then perform an exclusive-OR on O1 and D2 to give I3

www.phaedsys.org  Phaedrus Systems Page 18 of 67


5 I3 is encrypted using the DES encrypt algorithm and the MAC session
key A to give the output block O2

Steps 4 and 5 are then repeated for the number of data blocks that exist until
an exclusive-OR has been performed on the last data block, D(n), and the
result has been encrypted to give the output O(n).

6 O(n) is then decrypted using the DES decrypt algorithm and the MAC
session key B to give the output O(n + 1)
7 O(n + 1) is then encrypted using the DES encrypt algorithm and the
MAC session key A to give the output O(n + 2)

The result O(n + 2) is the 8-byte MAC.

The MAC is then compared to the MAC in the Command Data. This procedure
is shown diagrammatically below:
Initial I2 I3 I4 I5
Vector

Xor DEA(e) DEA(e) DEA(e) DEA(e)


DEA(d)
I1 = D1
O1 O2 O3 O4
O5

Xor Xor Xor


DEA(e)
D2 D3 D4
O6

Calculated
I = Input D = Data Block 8 – byte MAC
DEA (e) = Encrypt using MAC O = Output
Session Key A
DEA (d) = Decrypt using MAC = Exclusive Or
Xor
Session Key B

FIGURE 1 – MAC Calculation

www.phaedsys.org  Phaedrus Systems Page 19 of 67


Data Flow for MAC Generation

www.phaedsys.org  Phaedrus Systems Page 20 of 67


Generating An AC or an ARPC

APPLICATION CRYPTOGRAM - ARQC / TC or AAC

DATA OBJECTS USED IN THE CALCULATION

A data object which is input into the algorithm is either:

Referenced in the card’s CDOL, and transmitted from the terminal to the card
in the ‘Generate AC’ command

or

Accessed internally by the card

The data elements that need to be accessed internally by the card for input
into the algorithm are:

Application Interchange Profile (AIP)


Application Transaction Counter (ATC)
Card Verification Results (CVR)

GENERATING THE ALGORITHM

Depending upon the result of the internal card risk management tests
performed by the card, a TC, an AAC or an ARQC will be returned in the
response message.

The calculation, which uses triple DEA encipherment, proceeds as below:

The card concatenates the data received in the ‘Generate AC’ command. This
data is referenced by the CDOL and is placed in the order specified by the
CDOL into a data block.

The card concatenates the AIP, ATC and CVR onto the end of the data block.

The card will then format the data block into smaller 8-byte blocks labelled
D1, D2, D3, D4 and D5.

As the data block D5 is less than 8-bytes in length the remaining right bits are
set to 0x00.

Using the unique DES keys A and B on the card the following steps are
performed:

www.phaedsys.org  Phaedrus Systems Page 21 of 67


The input I1 is equal to Data Block 1 D1

‰ I1 is encrypted with DES Key A to give an output O1


‰ The card performs an exclusive-OR operation on O1 and D2 to
give I2
‰ I2 is encrypted with DES Key A to give output O2
‰ An exclusive-OR operation is performed on O2 and D3 to give I3
‰ I3 is encrypted with DES Key A to give output O3
‰ An exclusive-OR operation is performed on O3 and D4 to give I4
‰ I4 is encrypted with DES Key A to give output O4
‰ An exclusive-OR operation is performed on O4 and D5 to give I5
‰ I5 is encrypted with DES Key A to give output O5
‰ O5 is then decrypted with DES Key B to give O6
‰ O6 is then encrypted with DES Key A to give O7

The output 8-byte field is the resulting cryptogram returned by the card in
response to the ‘Generate AC’ command

This procedure is shown diagrammatically below:

I1 = D1 I2 I3 I4 I5

DEA(e) DEA(e) DEA(e) DEA(e) DEA(e)


DEA(d)

O1 O2 O3 O4 O5
O6

Xor Xor Xor Xor


DEA(e)
D2 D3 D4 D5
O7

Calculated
I = Input D = Data Block 8 – byte Cryptogram
DEA (e) = Encrypt using DES O = Output
with Key A
DEA (d) = Decrypt using DES Xor = Exclusive Or
with Key B

FIGURE 2 – ARQC/TC or AAC Calculation

www.phaedsys.org  Phaedrus Systems Page 22 of 67


www.phaedsys.org  Phaedrus Systems Page 23 of 67
www.phaedsys.org  Phaedrus Systems Page 24 of 67
AUTHORISATION RESPONSE CRYPTOGRAM – ARPC

DATA OBJECTS USED IN THE CALCULATION

The data objects used in the calculation are:

− ARQC calculated earlier by the card


− Authorisation Response Code sent to the card by the terminal in the
‘External Authenticate’ command

GENERATING THE ALGORITHM

The ARPC is generated using the steps below:

ƒThe card left-justifies the Authorisation Response Code into an 8-byte


field and fills the remaining 6 bytes with 0x00

ƒThe card performs an exclusive-OR operation on the ARQC and the


Authorisation Response Code

ƒThe exclusive-OR produces an 8-byte data block, D1

ƒD1 is encrypted using the DES algorithm and the DES Key A on the card
to give an output O1

ƒO1 is decrypted using the DES algorithm and DES Key B to give an
output O2

ƒO2 is encrypted using the DES algorithm and the DES Key A on the card
to give an output O3. O3 is the 8-byte ARPC which is used to verify the
ARPC sent to the card in the ‘External Authenticate’ command by the
terminal

www.phaedsys.org  Phaedrus Systems Page 25 of 67


This procedure is shown diagrammatically below:

I1 = D1

DEA(e)

O1

DEA(d)

O2

DEA(e)

O3

Calculated
ARPC

I = Input DEA (e) = Encrypt using DES


algorithm with Key A
D = Data Block

O = Output DEA (d) = Decrypt using DES algorithm


with Key B

FIGURE 3 – ARPC Calculation

www.phaedsys.org  Phaedrus Systems Page 26 of 67


www.phaedsys.org  Phaedrus Systems Page 27 of 67
www.phaedsys.org  Phaedrus Systems Page 28 of 67
Static Authentication
Static Authentication uses Public Key cryptography based on RSA signed Keys. Static
Authentication is used in the terminal. The card stores the keys and the terminal obtains them
by READ RECORD. The card therefore does not need to know about RSA encryption or key
generation.

Static data authentication is performed by the terminal using a digital signature based on
public key techniques to confirm the legitimacy of critical ICC-resident static data identified
by the AFL. This detects unauthorised alteration of data after personalisation.

The data objects used for signing shall be retrievable by the terminal using the READ
RECORD Command.

RSA
Static data authentication requires the existence of a certification authority, which is a highly
secure cryptographic facility that ‘signs’ the issuer’s public keys. Every terminal conforming
to this specification shall contain the appropriate certification authority's public key(s) for
every application recognised by the terminal. This specification permits multiple AIDs to
share the same ‘set’ of certification authority public keys. The relationship between the data
and the cryptographic keys is shown below.

Issuer Certification Authority Acquirer

Distributed to Acquirer
Private Key Public Key Private Key Public Key (Resides in Terminal)
(Issuer) (Issuer) (CA) (CA)
SI PI SCA PCA

PI certified
with SCA

IC Card IC Terminal
Communication between IC Card and Terminal

Terminal :
Card provides to terminal :
- Uses PCA to verify that the Issuer’s PI
- PI certified by Certification Authority
was certified by the CA
- Card data with digital signature
- Uses PI to verify the digital signature
of the card data

www.phaedsys.org  Phaedrus Systems Page 29 of 67


RSA Keys
The following keys are held on the card to be retrieved by the terminal using READ RECORD.

Issuer Public Key Certificate

Issuer’s public key certified by a certification authority for use in static data authentication.

Format:

320-1024 bits, Tag ’90’h , Length 40-128 bytes

Issuer Public Key Exponent

Issuer specified data to be used with the Issuers’s public key algorithm for use in static data
authentication.

Format:

8-252 bits, Tag ’9F32’h, Length 1-32 bytes

Issuer Public Key Remainder

Remaining digits of the issuers public key to be hashed

Format:

8-272 bits, Tag ‘92’h, Length 1-34 bytes

www.phaedsys.org  Phaedrus Systems Page 30 of 67


File Security
There is no specified file security. There is, however, much implied security. This is part of
the file system and application set up and not a separate security module.

www.phaedsys.org  Phaedrus Systems Page 31 of 67


www.phaedsys.org  Phaedrus Systems Page 32 of 67
Cipher Sources

The cipher sources have been collected from several places all of them
reputable but for obvious reasons some are not attributed and come with
no guarantees of any kind.

As all these ciphers are in the public domain the sources will be available on my web site
(unless or until lawyers tell me different) The C version of DES is available on the Keil CD in
the 8051 examples directory. It originated from Applied Cryptography by Bruce Schneier
however due to the wonderfully democratic laws of the US whilst it was in printed from in the
book the electronic version on the Applied Cryptography CD is only available in the USA.
Bruce Schneier is an internationally acclaimed security and cipher consultant who does not
need me to validate the authenticity of his work. The 8051 assembler implementation comes
from an unimpeachable source at a major smart card vendor. The SHA-1 cipher comes from
another smart card vendor.

The diagrams were produced from the source using DA-C

DES Sources

C Source

The DES example is taken from the book "Applied Cryptography" by Bruce Schneier. It is
adapted for the Keil C51-Compiler. The example code is not optimized for code or data
space and shows the processing from long value arithmetic (56 bit) on an 8051 micro
controller. The source is available on the Keil demo CD

cpkey
Des.c

des_key deskey cookey


Des.c Des.c Des.c

des_enc desfunc
Des.c Des.c

main
Des.c

des_dec unscrun
Des.c Des.c

scrunch
Des.c

www.phaedsys.org  Phaedrus Systems Page 33 of 67


#include <stdio.h>
#include <reg51.h>

typedef struct {
unsigned long ek[32];
unsigned long dk[32];
} des_ctx;

extern void deskey(unsigned char *, short);


/* hexkey[8] MODE
* Sets the internal key register according to the hexadecimal
* key contained in the 8 bytes of hexkey, according to the DES,
* for encryption or decryption according to MODE.
*/

extern void usekey(unsigned long *);


/* cookedkey[32]
* Loads the internal key register with the data in cookedkey.
*/

extern void cpkey(unsigned long *);


/* cookedkey[32]
* Copies the contents of the internal key register into the storage
* located at &cookedkey[0].
*/

extern void des(unsigned char *, unsigned char *);


/* from[8] to[8]
* Encrypts/Decrypts (according to the key currently loaded in the
* internal key register) one block of eight bytes at address 'from'
* into the block at address 'to'. They can be the same.
*/

static void scrunch(unsigned char *, unsigned long *);


static void unscrun(unsigned long *, unsigned char *);
static void desfunc(unsigned long *, unsigned long *);
static void cookey(unsigned long *);

static unsigned long KnL[32] = { 0L };


static unsigned long KnR[32] = { 0L };
static unsigned long Kn3[32] = { 0L };
static unsigned char Df_Key[24] = {
0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67 };

static unsigned short bytebit[8] = {


0200, 0100, 040, 020, 010, 04, 02, 01 };

static unsigned long bigbyte[24] = {


0x800000L, 0x400000L, 0x200000L, 0x100000L,
0x80000L, 0x40000L, 0x20000L, 0x10000L,
0x8000L, 0x4000L, 0x2000L, 0x1000L,
0x800L, 0x400L, 0x200L,
0x100L,
0x80L, 0x40L, 0x20L,
0x10L,
0x8L, 0x4L, 0x2L, 0x1L };

/* Use the key schedule specified in the Standard (ANSI X3.92-1981). */

static unsigned char pc1[56] = {


56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,
9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,
62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,

www.phaedsys.org  Phaedrus Systems Page 34 of 67


13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 };

static unsigned char totrot[16] = {


1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 };

static unsigned char pc2[48] = {


13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,
22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1,
40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 };

void deskey(unsigned char *key, short edf) {


/* Thanks to James Gillogly & Phil Karn! */
register int i, j, l, m, n;
unsigned char pc1m[56], pcr[56];
unsigned long kn[32];

for ( j = 0; j < 56; j++ ) {


l = pc1[j];
m = l & 07;
pc1m[j] = (key[l >> 3] & bytebit[m]) ? 1 : 0;
}
for( i = 0; i < 16; i++ ) {
if( edf == DE1 ) m = (15 - i) << 1;
else m = i << 1;
n = m + 1;
kn[m] = kn[n] = 0L;
for( j = 0; j < 28; j++ ) {
l = j + totrot[i];
if( l < 28 ) pcr[j] = pc1m[l];
else pcr[j] = pc1m[l - 28];
}
for( j = 28; j < 56; j++ ) {
l = j + totrot[i];
if( l < 56 ) pcr[j] = pc1m[l];
else pcr[j] = pc1m[l - 28];
}
for( j = 0; j < 24; j++ ) {
if( pcr[pc2[j]] ) kn[m] |= bigbyte[j];
if( pcr[pc2[j+24]] ) kn[n] |= bigbyte[j];
}
}
cookey(kn);
}

static void cookey(unsigned long *raw1) {


register unsigned long *cook, *raw0;
unsigned long dough[32];
register int i;

cook = dough;
for( i = 0; i < 16; i++, raw1++ ) {
raw0 = raw1++;
*cook = (*raw0 & 0x00fc0000L) << 6;
*cook |= (*raw0 & 0x00000fc0L) << 10;
*cook |= (*raw1 & 0x00fc0000L) >> 10;
*cook++|= (*raw1 & 0x00000fc0L) >> 6;
*cook = (*raw0 & 0x0003f000L) << 12;
*cook |= (*raw0 & 0x0000003fL) << 16;
*cook |= (*raw1 & 0x0003f000L) >> 4;
*cook++ |= (*raw1 & 0x0000003fL);
}
usekey(dough);
}

void cpkey(unsigned long *into) {

www.phaedsys.org  Phaedrus Systems Page 35 of 67


register unsigned long *from, *endp;

from = KnL, endp = &KnL[32];


while( from < endp ) *into++ = *from++;
}

void usekey(unsigned long *from) {


register unsigned long *to, *endp;

to = KnL, endp = &KnL[32];


while( to < endp ) *to++ = *from++;
}

#if 0
void des(unsigned char *inblock, unsigned char *outblock) {
unsigned long work[2];

scrunch(inblock, work);
desfunc(work, KnL);
unscrun(work, outblock);
}
#endif

static void scrunch(unsigned char *outof, unsigned long *into) {


*into = (*outof++ & 0xffL) << 24;
*into |= (*outof++ & 0xffL) << 16;
*into |= (*outof++ & 0xffL) << 8;
*into++ |= (*outof++ & 0xffL);
*into = (*outof++ & 0xffL) << 24;
*into |= (*outof++ & 0xffL) << 16;
*into |= (*outof++ & 0xffL) << 8;
*into |= (*outof & 0xffL);
}

static void unscrun(unsigned long *outof, unsigned char *into) {


*into++ = (*outof >> 24) & 0xffL;
*into++ = (*outof >> 16) & 0xffL;
*into++ = (*outof >> 8) & 0xffL;
*into++ = *outof++ & 0xffL;
*into++ = (*outof >> 24) & 0xffL;
*into++ = (*outof >> 16) & 0xffL;
*into++ = (*outof >> 8) & 0xffL;
*into = *outof & 0xffL;
}

static unsigned long SP1[64] = {


0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L,
0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L,
0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L,
0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L,
0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L,
0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L,
0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L,
0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L,
0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L,
0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L,
0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L,
0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L,
0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L,
0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L,
0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L,
0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L };

static unsigned long SP2[64] = {


0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L,
0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L,

www.phaedsys.org  Phaedrus Systems Page 36 of 67


0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L,
0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L,
0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L,
0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L,
0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L,
0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L,
0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L,
0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L,
0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L,
0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L,
0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L,
0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L,
0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L,
0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L };

static unsigned long SP3[64] = {


0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L,
0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L,
0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L,
0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L,
0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L,
0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L,
0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L,
0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L,
0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L,
0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L,
0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L,
0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L,
0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L,
0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L,
0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L,
0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L };

static unsigned long SP4[64] = {


0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L,
0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L,
0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L,
0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L,
0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L,
0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L,
0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L,
0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L,
0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L,
0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L,
0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L,
0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L,
0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L,
0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L };

static unsigned long SP5[64] = {


0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L,
0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L,
0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L,
0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L,
0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L,
0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L,
0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L,
0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L,
0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L,
0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L,
0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L,
0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L,
0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L,
0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L,

www.phaedsys.org  Phaedrus Systems Page 37 of 67


0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L,
0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L };

static unsigned long SP6[64] = {


0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L,
0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L,
0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L,
0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L,
0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L,
0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L,
0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L,
0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L,
0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L,
0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L,
0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L,
0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L,
0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L,
0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L,
0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L,
0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L };

static unsigned long SP7[64] = {


0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L,
0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L,
0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L,
0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L,
0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L,
0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L,
0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L,
0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L,
0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L,
0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L,
0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L,
0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L,
0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L,
0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L,
0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L,
0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L };

static unsigned long SP8[64] = {


0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L,
0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L,
0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L,
0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L,
0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L,
0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L,
0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L,
0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L,
0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L,
0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L,
0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L,
0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L,
0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L,
0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L,
0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L,
0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L };

static void desfunc(unsigned long *block, unsigned long *keys) {


register unsigned long fval, work, right, leftt;
register int round;

leftt = block[0];
right = block[1];
work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL;
right ^= work;
leftt ^= (work << 4);

www.phaedsys.org  Phaedrus Systems Page 38 of 67


work = ((leftt >> 16) ^ right) & 0x0000ffffL;
right ^= work;
leftt ^= (work << 16);
work = ((right >> 2) ^ leftt) & 0x33333333L;
leftt ^= work;
right ^= (work << 2);
work = ((right >> 8) ^ leftt) & 0x00ff00ffL;
leftt ^= work;
right ^= (work << 8);
right = ((right << 1) | ((right >> 31) & 1L)) & 0xffffffffL;
work = (leftt ^ right) & 0xaaaaaaaaL;
leftt ^= work;
right ^= work;
leftt = ((leftt << 1) | ((leftt >> 31) & 1L)) & 0xffffffffL;

for( round = 0; round < 8; round++ ) {


work = (right << 28) | (right >> 4);
work ^= *keys++;
fval = SP7[ work & 0x3fL];
fval |= SP5[(work >> 8) & 0x3fL];
fval |= SP3[(work >> 16) & 0x3fL];
fval |= SP1[(work >> 24) & 0x3fL];
work = right ^ *keys++;
fval |= SP8[ work & 0x3fL];
fval |= SP6[(work >> 8) & 0x3fL];
fval |= SP4[(work >> 16) & 0x3fL];
fval |= SP2[(work >> 24) & 0x3fL];
leftt ^= fval;
work = (leftt << 28) | (leftt >> 4);
work ^= *keys++;
fval = SP7[ work & 0x3fL];
fval |= SP5[(work >> 8) & 0x3fL];
fval |= SP3[(work >> 16) & 0x3fL];
fval |= SP1[(work >> 24) & 0x3fL];
work = leftt ^ *keys++;
fval |= SP8[ work & 0x3fL];
fval |= SP6[(work >> 8) & 0x3fL];
fval |= SP4[(work >> 16) & 0x3fL];
fval |= SP2[(work >> 24) & 0x3fL];
right ^= fval;
}

right = (right << 31) | (right >> 1);


work = (leftt ^ right) & 0xaaaaaaaaL;
leftt ^= work;
right ^= work;
leftt = (leftt << 31) | (leftt >> 1);
work = ((leftt >> 8) ^ right) & 0x00ff00ffL;
right ^= work;
leftt ^= (work << 8);
work = ((leftt >> 2) ^ right) & 0x33333333L;
right ^= work;
leftt ^= (work << 2);
work = ((right >> 16) ^ leftt) & 0x0000ffffL;
leftt ^= work;
right ^= (work << 16);
work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL;
leftt ^= work;
right ^= (work << 4);
*block++ = right;
*block = leftt;
}

/* Validation sets:
*
* Single-length key, single-length plaintext -

www.phaedsys.org  Phaedrus Systems Page 39 of 67


* Key : 0123 4567 89ab cdef
* Plain : 0123 4567 89ab cde7
* Cipher : c957 4425 6a5e d31d
*
**********************************************************************/

void des_key(des_ctx *dc, unsigned char *key){


deskey(key,EN0);
cpkey(dc->ek);
deskey(key,DE1);
cpkey(dc->dk);
}

/* Encrypt several blocks in ECB mode. Caller is responsible for


short blocks. */
void des_enc(des_ctx *dc, unsigned char *Data, int blocks){
unsigned long work[2];
int i;
unsigned char *cp;

cp = Data;
for(i=0;i<blocks;i++){
scrunch(cp,work);
desfunc(work,dc->ek);
unscrun(work,cp);
cp+=8;
}
}

void des_dec(des_ctx *dc, unsigned char *Data, int blocks){


unsigned long work[2];
int i;
unsigned char *cp;

cp = Data;
for(i=0;i<blocks;i++){
scrunch(cp,work);
desfunc(work,dc->dk);
unscrun(work,cp);
cp+=8;
}
}

void main(void){
des_ctx dc;
int i;
unsigned long Data[10];
char *cp,key[8] = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
char x[8] = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xe7};

/*------------------------------------------------
Setup the serial port for 1200 baud at 16MHz.
------------------------------------------------*/
SCON = 0x50; /* SCON: mode 1, 8-bit UART, enable rcvr */
TMOD |= 0x20; /* TMOD: timer 1, mode 2, 8-bit reload */
TH1 = 221; /* TH1: reload value for 1200 baud @ 16MHz */
TR1 = 1; /* TR1: timer 1 run */
TI = 1; /* TI: set TI to send first char of UART */

cp = x;

des_key(&dc,key);
des_enc(&dc,cp,1);
printf("Enc(0..7,0..7) = ");

www.phaedsys.org  Phaedrus Systems Page 40 of 67


for(i=0;i<8;i++) printf("%02x ", ((unsigned int) cp[i])&0x00ff);
printf("\n");

des_dec(&dc,cp,1);

printf("Dec(above,0..7) = ");
for(i=0;i<8;i++) printf("%02x ",((unsigned int)cp[i])&0x00ff);
printf("\n");

cp = (char *) Data;
for(i=0;i<10;i++) Data[i]=i;

des_enc(&dc,cp,5); /* Enc 5 blocks. */


for(i=0;i<10;i+=2) printf("Block %01d = %08lx %08lx.\n",
i/2,Data[i],Data[i+1]);

des_dec(&dc,cp,1);
des_dec(&dc,cp+8,4);
for(i=0;i<10;i+=2) printf("Block %01d = %08lx %08lx.\n",
i/2,Data[i],Data[i+1]);
while (1);

www.phaedsys.org  Phaedrus Systems Page 41 of 67


www.phaedsys.org  Phaedrus Systems Page 42 of 67
8051 Assembler

The source below has come from a very good source (sic) that wishes not to advertise that it is
their implementation. However I know it has been tested and used at the highest levels.

;******************************************************************
;*
;* $Workfile: DES.A51 $
;* NAME : DES
;*
;* Copyright *******
;*
;* Author: **********
;* $Revision: 1 $
;*
;* Analysis reference:
;*
;* Input Parameters:
;*
;* Output Parameters:
;*
;* Compiler : Keil A51 Asembler
;* Target :
;*
;* $Log: /des2/DES.A51 $
;*
;* 1 4/08/01 11:36 Chris
;*
;/

Extrn Data (CalcArea)


Extrn Code (GErrCrypt)
Public DES
;******************* Definitions *********
Decode equ Acc.5 ;Decode-/Encode~-Flag
MAC equ Acc.4 ;MAC-Flag
BM0 equ 024h ;BitMapMemory, 8 bytes used
BM1 equ BM0+1
BM2 equ BM0+2
BM3 equ BM0+3
BM4 equ BM0+4
BM5 equ BM0+5
BM6 equ BM0+6
BM7 equ BM0+7

R2MAC equ 010h ;error messages


LenErr equ 008h
ModeErr equ 003h

DES_Proc Segment Code


RSeg DES_Proc

;**************** Function DES *************


;R0 0 Pointer, general purpose, outout =
R1+R7 (BuildMac)
;R1 I/O Pointer to 8 byte input data, output =
R2+8
;R2 Pointer to 8 byte working area for D-, C-
Values
;R3 0 RoundCounter, output = 8
;R4 Counter, general purpose

www.phaedsys.org  Phaedrus Systems Page 43 of 67


;R5 I, u parameter P2 of APDU
; b7b6
; 0 0 EBC
; 0 1 CBC
; 1 x reserved
; b5
; 0 encrypt
; 1 decrypt
;
; b4
; 1 Build MAC
;
;R6 Input pointer
;R7 I ByteCount
;B TestRegister for ShiftTest of D-, C-Values
;Dptr I u Pointer to 64/56 bit DES-Key in TLV-Format
;Carry 0 0= Normal Termination
;Abbreviations: I = Input, O = Output, u = unchanged
;Two Stack-entries neccessary
;
;Key format: sequence of TLV records
; 1st record: key handleing information
; 2nd record: DES key
; 3rd record: initialvalue (optional)

;***********************************************************************
**
DES: Mov A, R5 ;mode
Jnb MAC,DES_
Jnb Decode,DES_
;Separate MAC at the end of the datafeild
Mov A, R7 ;Acc := #(Data) + # (MAC)
Add A, #0F8h ;Acc -= #(MAC)
Mov R7, A ;R7 := true DataLength

DES_: Mov R3, #8 ;D, C := PC_1 (DES-Key), 2*28 bit


;Calculate key address (adrC = dptr+R2)
Mov A, #1
MovC A, @A+Dptr ;Acc := HeaderLength
Add A, #4 ;Acc := addr(Key0)
Mov R2, A ;R2 KeyByteOffset
;address of 16 bytes calculation area
Mov A, #CalcArea ;Acc := addr
Xch A, R1 ;Acc := addr (Input0)
Mov R6, A ;R6 := addr (Input0)
;write permuted key to bitmal areA

DesGetKey: Mov R0, #BM0 ;R0 := addr (C0)


Mov A, R2 ;Acc := KeyOffsetByte
MovC A, @A+Dptr ;Acc := ith byte of DES-Key
Inc R2
Mov R4, #7 ;R6 := shift bits 6..0, bit7 not used
Rlc A
Xch A, @R0
Rlc A
Xch A, @R0
Inc R0
Djnz R4, $-5
Djnz R3, DesGetKey

Mov A, BM6 ;Acc := D0


Xch A, BM4 ;Acc := D2
Mov BM6, A ;Store D2 at correct location
;2nd permutation and copy to calculation area

www.phaedsys.org  Phaedrus Systems Page 44 of 67


Mov R0, #BM0 ;R0 := addr (C0)
Mov R3, A ;R3 := permutate 7 bytes

SetKeyNxt: Mov A, R3 ;Acc := addr (D6, C6) - R1 +1


Mov R4, A ;R4 := ByteCounter
Mov A, @R0 ;Acc := next
StandardPuermutationByte
Inc R0
Rrc A
Xch A, @R1
Rrc A
Rrc A
Xch A, @R1
Inc R1
Djnz R4, $-6 ;R1 == addr (D6, C6 ) +1?

Mov R4, A ;Save Accu


Mov A, R1 ;Acc := addr (D6, C6) +1
Add A, #0F9h ;Acc := addr (D0, C0)
Mov R1, A ;R1 := addr (D0, C0)
Clr C
Mov A, #8 ;Acc := all bits
SubB A, R3 ;Acc := remaining bits to shift
Xch A, R4 ;Acc :=remaining bits
Rrc A
Xch A, @R1
Rrc A
Rrc A
Xch A, @R1
Inc R1
Djnz R4, $-6 ;More bits to shift ?
Djnz R3, SetKeyNxt ;All bytes permutated?

Call VecExist ;Initial value to Copy?


; C = 1 : yes
; = 0 : no
;R3 = #8
;copy 0 or initial value to calculation area
Inc R2 ;R2 := addr(Vector0) -1
Clr A

Jnc $+5
Inc R2
Mov A, R2 ;Acc := addr(VectorI)
MovC A, @A+Dptr ;Acc :=VectorI
Inc R1 ;addr (0) += 1
Mov R3, $-7

Mov A, R5 ;Acc := addr (output7)


Add A, #0F1h ;Acc := addr (D0, C0)
Mov R2, A ;R2 := addr (D0, C0)

;check Des mode


Mov A, R5 ;Acc := mode
Jnb Acc.7, DesModeOk
Call GErrCrypt ;Error wrong mode
DB 003h

DesModeOk: Cpl Decode


Mov R5, A
Anl A, #030h ;mask decode and MAC-bit
Jnz DesLgOk ; no len checkwhen MaC or
encrypt

www.phaedsys.org  Phaedrus Systems Page 45 of 67


Mov A, R7 ;Get ByteCount
Anl A, #007h ;James Bond
Jz DesLgOk
Call GErrCrypt ;Error: Length not multiple of 8
DB 008h

DesLgOk: Mov A, R5 ;Acc := mode


Xrl A, #040h ;CBC-Decode
Anl A, #0F0h
Jnz DesSave ;No CBC-decode?
;CBC-Decode starts at end of
data
Mov A, R6 ;Acc := addr (Block0)
Add A, R7 ;Acc := addr (BlockN) +8
Add A, #0F8h ;Acc := addr (BlockN)
Mov R6, A ;R6 := addr (blockN)

DesSave: Push Dpl


Push Dph

;********** Function DES ***************


DESAction: Mov R3, #8 ;Initial permutation IP of 8
bytes
Mov A, R2 ;Acc := addr (D0, C0)
Add A, R3 ;Acc := addr (Output0)
Mov R1, A ;R1 := addr (Output0)
Mov A, R5 ;Acc := Mode
Mov B, A ;B-Accu := Mode
Rl A
Rlc A ; Carry := R5, 6
Anl C, Acc.7 ;CBc-Encode => Carry = 1 !
Orl C, Acc.6 ;BuildMac => Carry = 1 !
Mov 0F0h, C ;B.0 = 1 => ExOr
InputData

;get 8 bytes of data/add padding bytes


InitPerm: Mov R2, #080h ;Padding value
Mov A, R7
Jz Padding
Dec R7 ;ByteCounter
Mov A, R6 ;Acc := addr (InputI)
Mov R0, A ;R0 := addr (InputI)
Mov A, @R0 ;Acc := InputI
SJmp $-6

Padding: Xch A, R2 ;Acc := PaddingByte


Jb 0F4h, $+7 ;BuildMac ? => Skip Increment
Inc R6 ; addr (I) += 1
;add previous output if necessary
Jnb 0F0h, $+4
Xrl A, @R1 ;Acc ^= OutputI
Mov R0, #BM0 ;R0 := addr (Work0), it
contains Right0
Mov R4, #8 ;R4 := shift 8 bits
Djnz R3, $+4
SJmp InitEnd
;permute byte into bitmap area
Inc R1 ;addr (0) += 1
Rlc A
Xch A, @R0
Rlc A
Xch A, @R0
Inc R0 ;addr (W) +=1
Djnz R4, $-5
SJmp InitPerm+2 ;permute last byte
InitEnd: Rl A

www.phaedsys.org  Phaedrus Systems Page 46 of 67


Rl A
Rlc A
Xch A, @R0
Rl A
Rrc A
Xch A, @R0
Inc R0 ;addr (W) += 1
Djnz R4, $-6
; load Permutated input in calculation area
Mov @R1, BM1 ;R1 := addr (Left0)
Dec R1 ;R1 := addr (Left1)
Mov @R1, BM3
Dec R1 ;R1 := addr (Left2)
Mov @R1, BM5
Dec R1 ;R1 := addr (Left3)
Mov @R1, BM7
Dec R1 ;R1 := addr (Right0)
Mov @R1, BM0
Dec R1 ;R1 := addr (Right1)
Mov @R1, BM2
Dec R1 ;R1 := addr (Right2)
Mov @R1, BM4
Dec R1 ;R1 := addr (Right3)
Mov @R1, BM6

; 16 rounds DES opperation


Mov A, R1 ;Acc := addr (Output0)
Add A, #0F8h ;Acc := addr (D0, C0)
Mov R2, A ;R2 := addr (D0, C0)
Mov R3, #16 ;RoundCounter

OneRound: Dec R3 ;Decrement RoundCounter


Mov A, R3 ;Acc := RoundCounter
Mov B, #7 ;DivideValue for Shift1Test
Div AB ;B-Accu := RoundCounter mod 7
Mov A, R5 ;Acc := Parameter2 of
APDU
Anl A, #030h ;Acc5..4 := Decode~, BuildMac
Jz RoundKey ;Decryption ?

Mov A, R2 ;Acc := addr (D0, C0)


Mov R0, A ;R0 := addr (D0, C0)
Mov A, B ;Acc := RoundCounter mod 7
Add A, #0FFh ;Acc != 0 => Shift2
Mov A, R3
Inc A
Anl C, /Acc.4 ;Carry &= First Round ?
Mov BM0.7, C ;BM0.7 == 0 ? => Shift1
Mov A, @R0 ;Acc := D6, C6 << 2 = D0, C0
EncShift2: Mov R4, #6 ;R4 := shift through 7 bytes
Mov R0, A ;R0 := D6, C6 << 2 = D0, C0
Mov A, R2 ;Acc := addr (D0, C0)
Add A, R4 ;Acc := addr (D6,C6)
Xch A, R0 ;Acc := D6, C6 << 2
Rr A ;Acc := D6, C6 << 1
Rr A ;Acc := D6, C6
Xch A, @R0 ;ShiftDown one byte
Dec R0 ;Address -= 1
Djnz R4, $-2
Jbc Bm0.7, EncShift2 ;Shift twice ?
Mov @R0, A ;Store D0, C0

RoundKey: ;Permutation 36 5 27 61 18 54 9 47 = D6, C6

www.phaedsys.org  Phaedrus Systems Page 47 of 67


; 44 13 35 6 26 62 17 55 = D5, C5
; 52 21 43 14 34 7 25 63 = D4, C4
; 60 29 52 22 42 15 33 4 = D3, C3
; 6 37 59 30 50 23 41 12 = D2, C2
; 11 45 2 38 58 31 49 20 = D1, C1
; 19 53 10 46 1 39 57 28 = D0, C1

Mov A, R2 ;RoundKey := PC_2 (D, C), 8*6


bit
Mov R0, A ;R0 := addr (C0)
Mov A, @R0 ;Acc := D0, C0
Mov BM2, A ;Bit8
Rlc A
Mov BM0, A ;Bit1
Rl A
Rl A
Mov BM6, A ;Bit53
Rlc A
Mov BM7, A ;Bit46
Mov BM6.0, C ;Bit39
Rl A
Rlc A
Mov Bm7.7, C ;Bit32
Rlc A
Mov BM1, A ;Bit15
Inc R0
Mov A, @R0 ;Acc :=D1, C1
Rlc A
Mov BM2.6, C ;Bit23
Rl A
Rl A
Rlc A
Mov BM4, A ;Bit47
Mov BM5, A ;Bit33
Mov BM5.3, C ;Bit40
Rlc A
Mov BM3, A ;Bit16
Rl A
Rlc A
Mov BM3.7, C ;Bit2
Inc R0
Mov A, @R0 ;Acc ;= D2, C3
Rlc A
Mov BM0.1, C ;Bit24
Rlc A
Mov BM5.7, C ;Bit48
Rlc A
Mov BM0.7, C ;Bit17
Rlc A
Mov BM4.6, C ;Bit41
Rlc A
Mov BM1.7, C ;Bit10
Rlc A
Mov BM6.2, C ;Bit34
Rlc A
Mov BM1.2, C ;Bit3
Rlc A
Mov BM4.3, C ;Bit55
Inc R0
Mov A, @R0 ;Acc := D3, C3
Rl A
Rlc A
Mov BM6.7, C ;Bit49
Rl A
Rlc A
Mov BM7.3, C ;Bit42

www.phaedsys.org  Phaedrus Systems Page 48 of 67


Rlc A
Mov BM0.0, C ;Bit11
Rl A
Rlc A
Mov BM2.1, C ;Bit4
Rlc A
Mov BM6.1, C ;Bit56
Inc R0
Mov A, @R0 ;Acc := D4, C4
Rlc A
Mov BM2.2, C ;Bit26
Rlc A
Mov BM7.4, C ;Bit50
Rlc A
Mov BM2.7, C ;Bit19
Rl A
Rlc A
Mov BM2.0, C ;Bit12
Rlc A
Mov BM5.7, C ;Bit36
Rlc A
Mov BM0.3, C ;Bit5
Rlc A
Mov BM7.6, C ;Bit29
Inc R0
Mov A, @R0 ;Acc := D5, C5
Rlc A
Mov BM3.4, C ;Bit27
Rlc A
Mov BM5.4, C ;Bit51
Rlc A
Mov BM3.5, C ;Bit20
Rlc A
Mov BM6.6, C ;Bit44
Rlc A
Mov BM3.6, C ;Bit13
Rlc A
Mov BM4.1, C ;Bit37
Rlc A
Mov BM1.5, C ;Bit6
Rlc A
Mov BM5.2, C ;Bit30
Inc R0
Mov A, @R0 ;Acc := D6, C6
Rlc A
Mov BM1.3, C ;Bit28
Rlc A
Mov BM4.7, C ;Bit52
Rlc A
Mov BM1.6, C ;Bit21
Rlc A
Mov BM5.5, C ;Bit45
Rlc A
Mov BM0.6, C ;Bit14
Rl A
Rlc A
Mov BM3.3, C ;Bit7
Rlc A
Mov BM4.0, C ;Bit31

Mov A, R5 ;Acc :=
Parameter2 of APDU
Anl A, #030h ;Acc5..4 := decode~, BuildMac
Jnz InitExpand

Mov A, R2 ;Acc := addr (D0, C0)

www.phaedsys.org  Phaedrus Systems Page 49 of 67


Mov R0, A ;R0 := RoundCounter mod ?
Dec A
Add A, #0FFh ;Carry := Acc != => Shift2
Mov A, R3
Jnz DecShift2-1 ;Last round ?
Clr C ;Carry == 0 => shift1
Mov A, @R0 ;Acc := D0, C0
DecShift2: Mov R4, #6 ;R4 := shift through 7
bytes
Inc R0 ;Address += 1
Xch A, @R0 ;shiftUp one byte
Djnz R4, $-2
Mov R0, A ;R0 := D0, C0 >> 2 = D6, C6
Mov A, R2 ;R0 := addr (D0, C0)
Xch A, R0 ;Acc := D0, C0 >> 2
Rl A ;Acc := D0, C0 >>1
Rl A ;Acc := D0, C0
Jbc PSW.7, DecShift2 ;Shift twice ?
Mov @R0, A ;Store D0, C0

InitExpand: Mov R0, #BM0 ;R0 :=addr (first


SBoxValue)
Mov R4, #4 ;Half number of SBoxes
Mov Dptr, #SBoxes ;Dptr :=addr (SBoxes)
Mov A, @R1 ;Acc := Right3
Inc R1
Inc R1
Inc R1 ;R1 := addr (Right0)

ExpXorSBox: XchD A, @R1 ;Acc3..0 := RightI, 4 bits


Xch A, @R0 Acc := RoundKey, bits 7, 6, 3..0
Xrl A, @R0 Acc := SBoxIndex, bits 7, 6, 3..0
Swap A Acc7..2 := SBoxIndex, 6 bits
Anl A, #0FCh ;Mask SBoxIndex
MovC A, @A+Dptr ;Acc := SBoxValue,
LowNibble valid
Xch A, @R0 ;Acc3..0 := RightI, 4 bits
Inc R0
XchD A, @R1 ;Rebuild RightI
Mov A, @R1 ;Acc7..0 :=RightI
Xrl A, @R0 ;Acc7..2 := SBoxIndex, 6 bit
Anl A, #0FCh ;Mask SBoxIndex
MovC A, @A+Dptr ;Acc := SBoxValue,
HighNibble valid
Mov @R0, A
Inc R0
Mov A, @R1 ;Acc7..0 := RightI
Dec R1
Inc Dptr
Djnz R4, ExpXorSBox

Mov A, R3 ;Acc := RoundCounter


Jnb Acc.0, $+7 ;Odd Round ?
Mov A, R1 ;Acc := addr (Right3) -1
Add A, #8 ;Addres += 8
Mov R1, A ;R1 := addr (Left0)

Mov C, BM1.6 ;P(B)1 :=B7, Righgt := P(B) ExOr Left


Rrc A
Mov C, BM4.3 ;P(B)2 :=B20
Rrc A
Mov C, BM5.4 ;P(B)3 :=B21
Rrc A
Mov C, BM7.4 ;P(B)4 :=B29
Rrc A

www.phaedsys.org  Phaedrus Systems Page 50 of 67


Mov C, BM2.3 ;P(B)5 :=B12
Rrc A
Mov C, BM6.3 ;P(B)6 :=B28
Rrc A
Mov C, BM4.0 ;P(B)7 :=B17
Rrc A
Mov C, BM0.0 ;P(B)8 :=B1
Rrc A
Xrl A, @R1 ;Acc := new Right0
Mov @R1, A ;Left0 := new Right0
Mov C, BM3.6 ;P(B)9 :=B15
Rrc A
Mov C, BM5.6 ;P(B)10 :=B23
Rrc A
Mov C, BM6.1 ;P(B)11 :=B26
Rrc A
Mov C, BM1.4 ;P(B)12 :=B5
Rrc A
Mov C, BM4.1 ;P(B)13 :=B18
Rrc A
Mov C, BM7.6 ;P(B)14 :=B31
Rrc A
Mov C, BM2.1 ;P(B)15 :=B10
Rrc A
Mov C, BM0.1 ;P(B)16 :=B2
Rrc A
Dec R1
Xrl A, @R1 ;Acc := new Rihght1
Mov @R1, A ;Left1 := new Right1
Mov C, BM1.7 ;P(B)17 :=B8
Rrc A
Mov C, BM5.7 ;P(B)18 :=B24
Rrc A
Mov C, BM3.5 ;P(B)19 :=B14
Rrc A
Mov C, BM7.7 ;P(B)20 :=B32
Rrc A
Mov C, BM6.2 ;P(B)21 :=B27
Rrc A
Mov C, BM0.2 ;P(B)22 :=B3
Rrc A
Mov C, BM2.0 ;P(B)23 :=B9
Rrc A
Mov C, BM4.2 ;P(B)24 :=B19
Rrc A
Dec R1
Xrl A, @R1 ;Acc := new Right2
Mov @R1, A ;Left2 := new Right2
Mov C, BM3.4 ;P(B)25 :=B13
Rrc A
Mov C, BM7.5 ;P(B)26 :=B30
Rrc A
Mov C, BM1.5 ;P(B)27 :=B6
Rrc A
Mov C, BM5.5 ;P(B)28 :=B22
Rrc A
Mov C, BM2.2 ;P(B)29 :=B11
Rrc A
Mov C, BM0.3 ;P(B)30 :=B4
Rrc A
Mov C, BM6.0 ;P(B)31 :=B25
Rrc A
Mov C, BM3.7 ;P(B)32 :=B16
Rrc A
Dec R1
Xrl A, @R1 ;Acc := new Right3

www.phaedsys.org  Phaedrus Systems Page 51 of 67


Mov @R1, A ;Left3 := new Right3

Mov A, R3 ;Acc :=RoundCounter


Jz PreOutput ;Ready Rounds ?
Jmp OneRound ;Next Rounds

;Normalise output of 16 Rounds


PreOutPut: Mov BM7, @R1 ;BM7 := Right3
Inc R1
Mov BM5, @R1 ;BM5 := Right2
Inc R1
Mov BM3, @R1 ;BM3 := Right1
Inc R1
Mov BM1, @R1 ;BM1 := Right0
Inc R1
Mov BM6, @R1 ;BM6 := Left3
Inc R1
Mov BM4, @R1 ;BM4 := Left2
Inc R1
Mov BM2, @R1 ;BM2 := Left1
Inc R1
Mov BM0, @R1 ;BM0 := Left0

Mov R3, #8 ;Inverse initial permutation


IP^-1
Mov R0, #BM0

InvItPerm: Mov A, @R0


Inc R0
Rl A ;Due to Left and Right notation
Mov R4, #8 ;which are rotated right 1 bit
Rrc A ;in comparision with standard
Xch A, @R1
Rlc A
Xch A, @R1
Dec R1
Djnz R4, $-5

Mov A, R1 ;Acc := addr (Output0) -1


Add A, #8 ;Acc := addr (Output7)
Mov R1, A ;R1 := addr (Output7)
Djnz R3, InvItPerm

Mov A, @R1 ;Acc := Output7 << 2


Rr A
Rr A
Mov @R1, A
;Results of DEs operation available
Mov A, R6 ;Acc := addr (Input0) + 8
Mov R0, A ;R0 := addr (Input0) + 8
Clr C

Mov A, R5
Jb Acc.4, TestEnd ;BuildMac ?
Rl A
Rlc A
Anl C, /Acc.7 ;Carry := Mode is CBC decode

Mov R3, #8 ;Copy data to input location


Mov A, @R1 ;Acc := OutputI
Dec R1
Dec R0
Mov @R0, A
Djnz R3, $-4

TestEnd: Mov A, R7

www.phaedsys.org  Phaedrus Systems Page 52 of 67


Jz DesEnd ;End of input data reached?
Jnc NoCbcDec
Mov A, R6 ;For CBC decode set pointer to next block
Add A, #0F0h
Mov R6, A
Mov R1, A
Mov R3, #8 ;and XOR it with pervious outout
Mov A, @R1
Xrl A, @R0
Mov @R0, A
Inc R0
Inc R0
Djnz R3, $-5
NoCbcDec: LJmp DesAction

DesEnd: Pop Dph ;Restor DataPointer


Pop Dpl
Jnc DesRet
Call VecExist
Jnc DesRet

Mov A, #1 ;CBC decode only


MovC A, @A+Dptr ;Acc := HeaderLength
Add A, #14 ;Acc := Index (vector0)
Mov R1, A
Mov A, R1
MovC A, @A+Dptr ;Acc := VectorI
Inc R1
Xrl A, @R0
Mov @R0, A
Inc R0
Djnz R3, $-6

DesRet: Mov R3, #8


Mov A, R2 ;Acc := addr (D0, C0)
Add A, R3 ;Acc := addr (Output0)
Mov R1, A ;R1 := addr (Output0)
Mov A, R5 ;Acc := Mode
Jnb Acc.4, NoMAC
;MAC verification/copy MAC to end of data
Mov C, Acc.5
Mov A, @R1
Jc $+5
Xrl A, @R0
Jnz MacErr
Mov @R0, A
Inc R0
Inc R1
Djnz R3, $-9

NoMAC: Mov A, R6
Mov R1, A
Mov A, #8
Clr c
Ret ;Normal termination => Carry == 0!

MacErr: Call GErrCrypt ;Invalid MAC


DB R2MAC

VecExist: Mov A, #2
MovC A, @A+Dptr ;Acc :=KeyType
Rrc A ;Carry :=InitialVectorExistanc
Mov A, #1
MovC A, @A+Dptr ;Acc := HeaderLength

www.phaedsys.org  Phaedrus Systems Page 53 of 67


MovC A, @A+Dptr ;Acc := EntryCount
Dec A
Jnz $+3 ;EntryCount >1
Clr C ;EntryCount == 1 => C := 0
Mov R3, #8
Ret

;***********************************************************************
* SBOX DATA */
SBoxes: ;BoxNr.: 2,1 4,3 6,5 8,7
DB 0F7h,0E5h,034H,02Bh
DB 002h,05Bh,092h,0E8h
DB 09Ch,088h,001h,05Ch
DB 0AFh,0DFh,0EFh,005h
DB 046h,006h,09Eh,06Fh
DB 05Bh,031h,045h,093h
DB 03Ah,0DDh,07Bh,0AAh
DB 09Ch,0AAh,086h,0F0h
DB 01Bh,079h,052h,014h
DB 0E7h,092h,0F8h,02Dh
DB 046h,013h,0CCh,0C9h
DB 039h,0C4h,023h,056h
DB 0CDh,09Fh,06Dh,0d1h
DB 0B4h,0ECh,03Eh,07Eh
DB 0A0h,024h,0A7h,036h
DB 04Ah,017h,0D0h,0A9h
DB 082h,0B0h,083h,04Dh
DB 078h,066h,074h,0D2h
DB 0E5h,04Bh,0BAh,093h
DB 013h,088h,009h,06Fh
DB 0DFh,06Ch,045h,0F0h
DB 026h,0DFh,01Bh,03Ch
DB 009h,032h,0E0h,005h
DB 0C5h,045h,0BCh,0CAh
DB 078h,0C7h,0F8h,027h
DB 0D1h,009h,0ADh,08Bh
DB 0B3h,0AEh,03Fh,07Eh
DB 06Eh,073h,05Ah,0B1h
DB 021h,05Ah,016h,08Bh
DB 08Dh,0B0h,0C1h,047h
DB 05Eh,0f1h,0D9h,0E8h
DB 0F0h,02Eh,067h,014h
DB 0C0h,0BBh,057h,08Bh
DB 0BFh,0C8h,02Dh,046h
DB 035h,024h,06Ah,037h
DB 0DAh,092h,0D6h,0F9h
DB 0F7h,06Ch,0E2h,052h
DB 0C2h,056h,098h,028h
DB 069h,083h,00Ch,004h
DB 005h,03Dh,065h,0C7h
DB 02Eh,0D0h,024h,0BDh
DB 051h,00Bh,043h,07Bh
DB 083h,04Ah,0BFh,06Ah
DB 0ECh,0A7h,080h,090h
DB 01Bh,006h,09Bh,0E8h
DB 028h,0B1h,0F4h,015h
DB 0DCh,07Fh,0C1h,091h
DB 076h,044h,01Ah,06Ch
DB 0BFh,01Eh,0FDh,0F0h
DB 013h,0F5h,0C1h,08Dh
DB 006h,0E1h,080h,0ACh
DB 06Dh,02Fh,07Fh,034h
DB 044h,0f2h,03Eh,0C9h
DB 0F9h,089h,0A7h,052h
DB 09Ah,05Dh,0D9h,07Fh
DB 0A0h,0EAh,002h,0A4h

www.phaedsys.org  Phaedrus Systems Page 54 of 67


DB 0E2h,0A9h,043h,01Eh
DB 084h,060h,03Eh,0E1h
DB 05Dh,037h,075h,0D3h
DB 037h,0DCh,0E9h,00Fh
DB 078h,0C5h,0A8h,025h
DB 04Eh,01Eh,05Bh,0BEh
DB 0A1h,098h,016h,046h
DB 09Bh,073h,0BCh,0d3h

;*************** End of Des **************


End

;*****************************************************************/
;************* End of $Workfile: DES.A51 $ ************************/
;*****************************************************************/

www.phaedsys.org  Phaedrus Systems Page 55 of 67


www.phaedsys.org  Phaedrus Systems Page 56 of 67
SHA-1

This is a basic Hash function used in many smart card systems. This implementation is in Java
is used for electronic data signature. The source is a well known smart card vendor.

You will find at http://www.itl.nist.gov/fipspubs/fip180-1.htm the FIPS PUB 180-1


corresponding specification from the NIST. This implementation for Java (that could easily
be converted for C), is without any guarantee .

import java.awt.*;
import java.applet.*;
import java.io.*;

public class sha {


long a;
long b;
long c;
long d;
long e;

public class Message {


int ml;
long m[] = new long[1024];

Message(){
for (int i=0; i<1024; i++) m[i]=0;}
}

public static long F(long x, long y, long z) {


return (((x & y) | ((x ^ 0xFFFFFFFF) & z)) & 0xFFFFFFFF);}
public static long G(long x, long y, long z) {
return ((x ^ y ^ z) & 0xFFFFFFFF);}
public static long H(long x, long y, long z) {
return (((x & y) | (x & z) | (y & z)) & 0xFFFFFFFF);}
public static long I(long x, long y, long z) {
return ((x ^ y ^ z) & 0xFFFFFFFF);}

public static String hexa(long n) {


char T[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D
','E','F'};
String s="";
int i;
for (i=0; i<8; i++) {
s=T[(int) (n & 0x0F)] + s;
n>>=4;}
return(s);}

public long ROTATE_LEFT(long x, int n) {


int mask1=0x80000000;
int mask2=0x0;
for (int i=0; i<32-n; i++) {mask1>>=1; mask1|=0x80000000;}
for (int i=0; i<n; i++) {mask2<<=1; mask2++;}
return ((((x << n) & mask1) | ((x >> (32-n)) & mask2))
& 0xffffffff);}

sha() {
a = 0x67452301;
b = 0xefcdab89;
c = 0x98badcfe;
d = 0x10325476;
e = 0xc3d2e1f0;}

www.phaedsys.org  Phaedrus Systems Page 57 of 67


sha(long a, long b, long c, long d, long e) {
this.a=a; this.b=b;this.c=c;this.d=d;this.e=e;}

sha(Message input, int len){


a = 0x67452301;
b = 0xefcdab89;
c = 0x98badcfe;
d = 0x10325476;
e = 0xc3d2e1f0;
this.SHAUpdate(input, len);
}

sha(String mot) {
int len,i;
Message input = new Message();

len = mot.length()+1;
i=(len / 4);
if (i*4<len) i++;

input.ml=i;

for (i=0; i<len-1; i++) {


input.m[i/4] <<= 8;
input.m[i/4]+= (int) mot.charAt(i);
}
input.m[i/4]<<= 8;
input.m[i/4]+= 0x80;
i++;
while(i%4 != 0) {
input.m[i/4]<<= 8;
i++;
}

a = 0x67452301;
b = 0xefcdab89;
c = 0x98badcfe;
d = 0x10325476;
e = 0xc3d2e1f0;
this.SHAUpdate(input, len);
}

private void FF(long w) {


long tmp = ROTATE_LEFT(a,5) + F(b, c, d) + e + w + 0x5a827999;
e = d; d = c;
c = ROTATE_LEFT(b,30);
b = a; a = tmp;}

private void GG(long w) {


long tmp = ROTATE_LEFT(a,5) + G(b, c, d) + e + w + 0x6ed9eba1;
e = d; d = c;
c = ROTATE_LEFT(b,30);
b = a; a = tmp;}

private void HH(long w) {


long tmp = ROTATE_LEFT(a,5) + H(b, c, d) + e + w + 0x8f1bbcdc;
e = d; d = c;
c = ROTATE_LEFT(b,30);
b = a; a = tmp;}

private void II(long w) {


long tmp = ROTATE_LEFT(a,5) + I(b, c, d) + e + w + 0xca62c1d6;
e = d; d = c;
c = ROTATE_LEFT(b,30);
b = a; a = tmp;}

www.phaedsys.org  Phaedrus Systems Page 58 of 67


// SHA block update operation. Continues an SHA message-digest
// operation, processing another message block, and updating state
public void SHAUpdate (Message input, int inputLen)
{
int i,j, index;
long buffer[] = new long[32];

for (i=0;i<=input.ml-16;i+=16) {
for (j=0; j<16; j++) buffer[j]=input.m[i+j];
this.SHATransform(buffer);}

index = input.ml & 0x0F;


if (index > 14){
for (j=0; j<index; j++) buffer[j]=input.m[i+j];
for (i=index;i<30;i++)
buffer[i]=0;
buffer[31]=((inputLen-1) << 3);
buffer[30]=((inputLen-1) >> 29);
this.SHATransform(buffer);
for (j=0; j<16; j++) buffer[j]=buffer[16+j];
this.SHATransform(buffer);
}
else {
for (j=0; j<index; j++) buffer[j]=input.m[i+j];
for (i=index;i<15;i++)
buffer[i]=0;
buffer[15]=((((inputLen-1) & 0xffffffff) << 3) &
0xffffffff);
buffer[14]=((((inputLen-1) & 0xffffffff) >> 29) &
0xffffffff);
this.SHATransform(buffer);
}
}

// SHA basic transformation. Transforms state based on block.


private void SHATransform (long x[]) {
long W[] = new long[80];
int i;
sha old = new sha(a,b,c,d,e);

for (i=0;i<16;i++) W[i]=x[i];


for (i=16;i<80;i++)
W[i] = ROTATE_LEFT(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16],1);

for(i=0;i<20;i++) old.FF(W[i]);
for(i=20;i<40;i++) old.GG(W[i]);
for(i=40;i<60;i++) old.HH(W[i]);
for(i=60;i<80;i++) old.II(W[i]);

a += old.a;
b += old.b;
c += old.c;
d += old.d;
e += old.e;
}

public String toString () {


return(hexa(a) + hexa(b) + hexa(c) + hexa(d) + hexa(e));}

www.phaedsys.org  Phaedrus Systems Page 59 of 67


GSM A3A8 algorithm. ( COMP128)

A3A8 An implementation of the GSM A3A8 algorithm. (Specifically,


This code derived from a leaked
document from the GSM standards. COMP128.) This cipher is widely used in the Sim cards (smart
Some missing pieces were filled in by
reverse-engineering a working SIM. cards) for GSM mobile phones
We have verified that this is the
correct COMP128 algorithm.

The first page of the document


This code ware written by Marc Briceno, Ian
identifies it as
_Technical Information: GSM System
Goldberg, and David Wagner
code
This code is for expository purposes only. Coded in C merely
because C is a much more precise, concise form of expression
code

( Load RAND into last 16 bytes of


input ) for these purposes. See Judge
code Patel if you have any problems with this...

( Loop eight times ) Of course, it's only authentication, so it should be exportable for
( Load key into first 16 the usual boring reasons.
bytes of input )

code
This code derived from a leaked document from the GSM
standards. Some missing pieces were filled in by reverse-
engineering a working SIM. We have verified that this is the
( Perform substitutions )

for
correct COMP128 algorithm.
for

The first page of the document identifies it as Technical


( Form bits from bytes ) Information: GSM System Security Study.
for 10-1617-01, 10th June 1988.
code
The bottom of the title page is marked
Racal Research Ltd.
( Permutation but not on the
last loop )
Worton Drive, Worton Grange Industrial Estate,
Reading, Berks. RG2 0SB, England.
Telephone: Reading (0734) 868601
true false
for -

code
Telex: 847152

The relevant bits are in Part I, Section 20 (pages 66--67). Enjoy!


for

( At this stage the vector x[] Note: There are three typos in the spec (discovered by
reverse-engineering).
consists of 32 nibbles.
The first 8 of these are taken as
the output SRES. )

The remainder of the code is not First, "z = (2 * x[n] + x[n]) mod 2^(9-j)"
given explicitly in the
standard, but was derived by
reverse-engineering.
should clearly read
for
"z = (2 * x[m] + x[n]) mod 2^(9-j)".
code
Second, the "k" loop in the "Form bits from bytes" section is
for severely botched: the k index should run only from 0 to 3, and
code clearly the range on "the (8-k)th bit of byte j" is also off (should
be 0..7, not 1..8, to be consistent with the subsequent section).
code

Third, SRES is taken from the first 8 nibbles of x[], not the last 8
as claimed in the document. (And the document doesn't specify how Kc is derived, but that
was also easily discovered with reverse engineering.)

All of these typos have been corrected in the following code.

www.phaedsys.org  Phaedrus Systems Page 60 of 67


/* An implementation of the GSM A3A8 algorithm. (Specifically, COMP128.)
* Copyright 1998, Marc Briceno, Ian Goldberg, and David Wagner.
* All rights reserved.
*/

typedef unsigned char Byte;

#include <stdio.h>
/* #define TEST */

/*
* rand[0..15]: the challenge from the base station
* key[0..15]: the SIM's A3/A8 long-term key Ki
* simoutput[0..11]: what you'd get back if you fed rand and key to a real
* SIM.
*
* The GSM spec states that simoutput[0..3] is SRES,
* and simoutput[4..11] is Kc (the A5 session key).
* (See GSM 11.11, Section 8.16. See also the leaked document
* referenced below.)
* Note that Kc is bits 74..127 of the COMP128 output, followed by 10
* zeros.
* In other words, A5 is keyed with only 54 bits of entropy. This
* represents a deliberate weakening of the key used for voice privacy
* by a factor of over 1000.
*
* Verified with a Pacific Bell Schlumberger SIM. Your mileage may vary.
*
* Marc Briceno <marc@scard.org>, Ian Goldberg <iang@cs.berkeley.edu>,
* and David Wagner <daw@cs.berkeley.edu>
*/

static void A3A8( /* in */ Byte rand[16],


/* in */ Byte key[16],
/* out */ Byte simoutput[12]);

/* The compression tables. */


static const Byte table_0[512] =
{
102,177,186,162, 2,156,112, 75, 55, 25, 8, 12,251,193,246,188,
109,213,151, 53, 42, 79,191,115,233,242,164,223,209,148,108,161,
252, 37,244, 47, 64,211, 6,237,185,160,139,113, 76,138, 59, 70,
67, 26, 13,157, 63,179,221, 30,214, 36,166, 69,152,124,207,116,
247,194, 41, 84, 71, 1, 49, 14, 95, 35,169, 21, 96, 78,215,225,
182,243, 28, 92,201,118, 4, 74,248,128, 17, 11,146,132,245, 48,
149, 90,120, 39, 87,230,106,232,175, 19,126,190,202,141,137,176,
250, 27,101, 40,219,227, 58, 20, 51,178, 98,216,140, 22, 32,121,
61,103,203, 72, 29,110, 85,212,180,204,150,183, 15, 66,172,196,
56,197,158, 0,100, 45,153, 7,144,222,163,167, 60,135,210,231,
174,165, 38,249,224, 34,220,229,217,208,241, 68,206,189,125,255,
239, 54,168, 89,123,122, 73,145,117,234,143, 99,129,200,192, 82,
104,170,136,235, 93, 81,205,173,236, 94,105, 52, 46,228,198, 5,
57,254, 97,155,142,133,199,171,187, 50, 65,181,127,107,147,226,
184,218,131, 33, 77, 86, 31, 44, 88, 62,238, 18, 24, 43,154, 23,
80,159,134,111, 9,114, 3, 91, 16,130, 83, 10,195,240,253,119,
177,102,162,186,156, 2, 75,112, 25, 55, 12, 8,193,251,188,246,
213,109, 53,151, 79, 42,115,191,242,233,223,164,148,209,161,108,
37,252, 47,244,211, 64,237, 6,160,185,113,139,138, 76, 70, 59,
26, 67,157, 13,179, 63, 30,221, 36,214, 69,166,124,152,116,207,
194,247, 84, 41, 1, 71, 14, 49, 35, 95, 21,169, 78, 96,225,215,
243,182, 92, 28,118,201, 74, 4,128,248, 11, 17,132,146, 48,245,
90,149, 39,120,230, 87,232,106, 19,175,190,126,141,202,176,137,
27,250, 40,101,227,219, 20, 58,178, 51,216, 98, 22,140,121, 32,
103, 61, 72,203,110, 29,212, 85,204,180,183,150, 66, 15,196,172,

www.phaedsys.org  Phaedrus Systems Page 61 of 67


197, 56, 0,158, 45,100, 7,153,222,144,167,163,135, 60,231,210,
165,174,249, 38, 34,224,229,220,208,217, 68,241,189,206,255,125,
54,239, 89,168,122,123,145, 73,234,117, 99,143,200,129, 82,192,
170,104,235,136, 81, 93,173,205, 94,236, 52,105,228, 46, 5,198,
254, 57,155, 97,133,142,171,199, 50,187,181, 65,107,127,226,147,
218,184, 33,131, 86, 77, 44, 31, 62, 88, 18,238, 43, 24, 23,154,
159, 80,111,134,114, 9, 91, 3,130, 16, 10, 83,240,195,119,253
};

static const Byte table_1[256] =


{
19, 11, 80,114, 43, 1, 69, 94, 39, 18,127,117, 97, 3, 85, 43,
27,124, 70, 83, 47, 71, 63, 10, 47, 89, 79, 4, 14, 59, 11, 5,
35,107,103, 68, 21, 86, 36, 91, 85,126, 32, 50,109, 94,120, 6,
53, 79, 28, 45, 99, 95, 41, 34, 88, 68, 93, 55,110,125,105, 20,
90, 80, 76, 96, 23, 60, 89, 64,121, 56, 14, 74,101, 8, 19, 78,
76, 66,104, 46,111, 50, 32, 3, 39, 0, 58, 25, 92, 22, 18, 51,
57, 65,119,116, 22,109, 7, 86, 59, 93, 62,110, 78, 99, 77, 67,
12,113, 87, 98,102, 5, 88, 33, 38, 56, 23, 8, 75, 45, 13, 75,
95, 63, 28, 49,123,120, 20,112, 44, 30, 15, 98,106, 2,103, 29,
82,107, 42,124, 24, 30, 41, 16,108,100,117, 40, 73, 40, 7,114,
82,115, 36,112, 12,102,100, 84, 92, 48, 72, 97, 9, 54, 55, 74,
113,123, 17, 26, 53, 58, 4, 9, 69,122, 21,118, 42, 60, 27, 73,
118,125, 34, 15, 65,115, 84, 64, 62, 81, 70, 1, 24,111,121, 83,
104, 81, 49,127, 48,105, 31, 10, 6, 91, 87, 37, 16, 54,116,126,
31, 38, 13, 0, 72,106, 77, 61, 26, 67, 46, 29, 96, 37, 61, 52,
101, 17, 44,108, 71, 52, 66, 57, 33, 51, 25, 90, 2,119,122, 35
};

static const Byte table_2[128] =


{
52, 50, 44, 6, 21, 49, 41, 59, 39, 51, 25, 32, 51, 47, 52, 43,
37, 4, 40, 34, 61, 12, 28, 4, 58, 23, 8, 15, 12, 22, 9, 18,
55, 10, 33, 35, 50, 1, 43, 3, 57, 13, 62, 14, 7, 42, 44, 59,
62, 57, 27, 6, 8, 31, 26, 54, 41, 22, 45, 20, 39, 3, 16, 56,
48, 2, 21, 28, 36, 42, 60, 33, 34, 18, 0, 11, 24, 10, 17, 61,
29, 14, 45, 26, 55, 46, 11, 17, 54, 46, 9, 24, 30, 60, 32, 0,
20, 38, 2, 30, 58, 35, 1, 16, 56, 40, 23, 48, 13, 19, 19, 27,
31, 53, 47, 38, 63, 15, 49, 5, 37, 53, 25, 36, 63, 29, 5, 7
};

static const Byte table_3[64] =


{
1, 5, 29, 6, 25, 1, 18, 23, 17, 19, 0, 9, 24, 25, 6, 31,
28, 20, 24, 30, 4, 27, 3, 13, 15, 16, 14, 18, 4, 3, 8, 9,
20, 0, 12, 26, 21, 8, 28, 2, 29, 2, 15, 7, 11, 22, 14, 10,
17, 21, 12, 30, 26, 27, 16, 31, 11, 7, 13, 23, 10, 5, 22, 19
};

www.phaedsys.org  Phaedrus Systems Page 62 of 67


static const Byte table_4[32] =
{
15, 12, 10, 4, 1, 14, 11, 7, 5, 0, 14, 7, 1, 2, 13, 8,
10, 3, 4, 9, 6, 0, 3, 2, 5, 6, 8, 9, 11, 13, 15, 12
};

static const Byte *table[5] = { table_0, table_1, table_2, table_3,


table_4 };

static void A3A8( /* in */ Byte rand[16],


/* in */ Byte key[16],
/* out */ Byte simoutput[12])
{
Byte x[32];
Byte xsbit[128];

int i;
int j;
int k;
int l;
int m;
int n;
int y;
int z;
int next_bit;

/* ( Load RAND into last 16 bytes of input ) */


for (i=16; i<32; i++)
{
x[i] = rand[i-16];
}

/* ( Loop eight times ) */


for (i=1; i<9; i++)

{
/* ( Load key into first 16 bytes of input ) */
for (j=0; j<16; j++)
{
x[j] = key[j];
}
/* ( Perform substitutions ) */
for (j=0; j<5; j++)
{
for (k=0; k<(1<<j); k++)
{
for (l=0; l<(1<<(4-j)); l++)

{
m = l + k*(1<<(5-j));
n = m + (1<<(4-j));
y = (x[m]+2*x[n]) % (1<<(9-j));
z = (2*x[m]+x[n]) % (1<<(9-j));
x[m] = table[j][y];
x[n] = table[j][z];

www.phaedsys.org  Phaedrus Systems Page 63 of 67


/* ( Form bits from bytes ) */
for (j=0; j<32; j++)
{
for (k=0; k<4; k++)

{
xsbit[4*j+k] = (x[j]>>(3-k)) & 1;

/* ( Permutation but not on the last loop ) */

if (i < 8)

{
for (j=0; j<16; j++)

{
x[j+16] = 0;

for (k=0; k<8; k++)

{
next_bit = ((8*j + k)*17) % 128;
x[j+16] |= xsbit[next_bit] << (7-k);

}
}

/*
* ( At this stage the vector x[] consists of 32 nibbles.
* The first 8 of these are taken as the output SRES. )
*/

/* The remainder of the code is not given explicitly in the


* standard, but was derived by reverse-engineering.
*/

for (i=0; i<4; i++)

{
simoutput[i] = (x[2*i]<<4) | x[2*i+1];
}

for (i=0; i<6; i++)

{
simoutput[4+i] = (x[2*i+18]<<6) | (x[2*i+18+1]<<2)
| (x[2*i+18+2]>>2);

}
simoutput[4+6] = (x[2*6+18]<<6) | (x[2*6+18+1]<<2);
simoutput[4+7] = 0;
}

#ifdef TEST
int hextoint(char x)
{

www.phaedsys.org  Phaedrus Systems Page 64 of 67


x = toupper(x);
if (x >= 'A' && x <= 'F')
return x-'A'+10;
else if (x >= '0' && x <= '9')
return x-'0';
fprintf(stderr, "bad input.\n");
exit(1);
}

int main(int argc, char **argv)


{
Byte rand[16];
Byte key [16];
Byte simoutput[12];
int i;

if (argc != 3 || strlen(argv[1]) != 34 || strlen(argv[2]) != 34


|| strncmp(argv[1], "0x", 2) != 0
|| strncmp(argv[2], "0x", 2) != 0)

fprintf(stderr, "Usage: %s 0x<key> 0x<rand>\n", argv[0]);


exit(1);
}

for (i=0; i<16; i++)


{

key[i] = (hextoint(argv[1][2*i+2])<<4)|
hextoint(argv[1][2*i+3]);

for (i=0; i<16; i++)

rand[i] = (hextoint(argv[2][2*i+2])<<4) |
hextoint(argv[2][2*i+3]);

}
A3A8(key, rand, simoutput);
printf("simoutput: ");
for (i=0; i<12; i++)
{
printf("%02X", simoutput[i]);

printf("\n");
return 0;
}
#endif

www.phaedsys.org  Phaedrus Systems Page 65 of 67


References

Applied Cryptography 2nd Ed By Bruce Schneier pub 1996 by Wiley ISBN 0-471-
11709-9 NOTE US citizens may also obtain a companion CD containing electronic versions of
most of the ciphers in the book. The is THE reference for cryptography for the average
person.

Handbook of Applied Cryptography, by A. Menezes, P. van Oorschot,


and S. Vanstone, CRC Press, 1996. For further information, see
www.cacr.math.uwaterloo.ca/hac where there is a complete electronic
version with source code.

Smart Card Handbook 2nd Ed. By Wrankel & Effing Pub 1999 by Wiley. ISBN 0-471-
98875-8 This is THE smart card reference book. Note the 2nd Edition in English is the 3rd
Edition of the original German version.

SHA-1 see http://www.itl.nist.gov/fipspubs/fip180-1.htm the FIPS PUB 180-1

Minimum Card Requirements V1.1 EuroPay Interational SA


http:/www.europay.com

UKIS V3 (based on VIS 1.2) APACS

ISO 7816 parts 1-9 Design and use of Identification cars having
Integrated circuits with contacts, 7816 part 4 is the most intresting one for sw
engineers

Visa Integrated Circuit Card Specification

EMV96 Integrated Circuit Card Terminal Specification for


Payment Systems

EMV96 Integrated Circuit Card Specification for Payment


Systems
GSM A3A8 algorithm. (Specifically, COMP128.)

www.phaedsys.org  Phaedrus Systems Page 66 of 67


chris@phaedsys.org
www.phaedsys.org

www.phaedsys.org  Phaedrus Systems Page 67 of 67

You might also like