def wrapAPDU(self, apdu):
""" Wrap APDU for SCP02, i.e. calculate MAC and encrypt.
Input APDU and output APDU are list of uint8. """
lc = len(apdu) - 5
assert len(apdu) >= 5, "Wrong APDU length: %d" % len(apdu)
assert len(apdu) == 5 or apdu[4] == lc, \
"Lc differs from length of data: %d vs %d" % (apdu[4], lc)
cla = apdu[0]
b8 = cla & 0x80
if cla & 0x03 > 0 or cla & 0x40 != 0:
# nonzero logical channel in APDU, check that are the same
assert cla == self.CLA(False, b8), "CLA mismatch"
sapdu = l2s(apdu)
# CLA without log. channel can be 80 or 00 only
if self.isCMAC:
if self.i & M_CMAC_MODIF: # CMAC on unmodified APDU
mlc = lc
clac = chr(b8)
else: # CMAC on modified APDU
mlc = lc + 8
clac = chr(b8 + 0x04)
mac = self.calcMAC_1d(clac + sapdu[1:4] + chr(mlc) + sapdu[5:])
mac = [ord(x) for x in mac]
if self.isENC:
k = DES3.new(self.ses_ENC, DES.MODE_CBC, ZERO8)
data = s2l(k.encrypt(pad80(sapdu[5:], 8)))
lc = len(data)
else:
data = apdu[5:]
lc += 8
apdu = [self.CLA(True, b8)] + apdu[1:4] + [lc] + data + mac
return apdu
评论列表
文章目录