def aes_gcm_encrypt(master_secret, aes_key, rand, header, iv=mpin.IVL): """Encrypt master secret.""" # AES Key AES_KEY = mpin.ffi.new('octet*') AES_KEY_val = mpin.ffi.new('char [%s]' % len(aes_key), aes_key) AES_KEY[0].val = AES_KEY_val AES_KEY[0].max = len(aes_key) AES_KEY[0].len = len(aes_key) # Initialisation Vector IV = mpin.ffi.new('octet*') IV_val = mpin.ffi.new('char []', iv) IV[0].val = IV_val IV[0].max = iv IV[0].len = iv mpin.libmpin.generateRandom(rand, IV) # Authentication tag TAG = mpin.ffi.new('octet*') TAG_val = mpin.ffi.new('char []', mpin.PAS) TAG[0].val = TAG_val TAG[0].max = mpin.PAS # Header HEADER = mpin.ffi.new('octet*') HEADER_val = mpin.ffi.new('char [%s]' % len(header), header) HEADER[0].val = HEADER_val HEADER[0].max = len(header) HEADER[0].len = len(header) # Plaintext input plaintext = master_secret PLAINTEXT = mpin.ffi.new('octet*') PLAINTEXT_val = mpin.ffi.new('char [%s]' % len(plaintext), plaintext) PLAINTEXT[0].val = PLAINTEXT_val PLAINTEXT[0].max = len(plaintext) PLAINTEXT[0].len = len(plaintext) # Ciphertext CIPHERTEXT = mpin.ffi.new('octet*') CIPHERTEXT_val = mpin.ffi.new('char []', len(plaintext)) CIPHERTEXT[0].val = CIPHERTEXT_val CIPHERTEXT[0].max = len(plaintext) mpin.libmpin.MPIN_AES_GCM_ENCRYPT(AES_KEY, IV, HEADER, PLAINTEXT, CIPHERTEXT, TAG) IV_hex = mpin.toHex(IV) CIPHERTEXT_hex = mpin.toHex(CIPHERTEXT) TAG_hex = mpin.toHex(TAG) return CIPHERTEXT_hex, IV_hex, TAG_hex
def aes_gcm_encrypt(master_secret, aes_key, rand, header, iv=mpin.IVL): """Encrypt master secret.""" # AES Key AES_KEY = mpin.ffi.new('octet*') AES_KEY_val = mpin.ffi.new('char [%s]' % len(aes_key), aes_key) AES_KEY[0].val = AES_KEY_val AES_KEY[0].max = len(aes_key) AES_KEY[0].len = len(aes_key) # Initialisation Vector IV = mpin.ffi.new('octet*') IV_val = mpin.ffi.new('char []', iv) IV[0].val = IV_val IV[0].max = iv IV[0].len = iv mpin.libmpin.generateRandom(rand, IV) # Authentication tag TAG = mpin.ffi.new('octet*') TAG_val = mpin.ffi.new('char []', mpin.PAS) TAG[0].val = TAG_val TAG[0].max = mpin.PAS # Header HEADER = mpin.ffi.new('octet*') HEADER_val = mpin.ffi.new('char [%s]' % len(header), header) HEADER[0].val = HEADER_val HEADER[0].max = len(header) HEADER[0].len = len(header) # Plaintext input plaintext = master_secret PLAINTEXT = mpin.ffi.new('octet*') PLAINTEXT_val = mpin.ffi.new('char [%s]' % len(plaintext), plaintext) PLAINTEXT[0].val = PLAINTEXT_val PLAINTEXT[0].max = len(plaintext) PLAINTEXT[0].len = len(plaintext) # Ciphertext CIPHERTEXT = mpin.ffi.new('octet*') CIPHERTEXT_val = mpin.ffi.new('char []', len(plaintext)) CIPHERTEXT[0].val = CIPHERTEXT_val CIPHERTEXT[0].max = len(plaintext) mpin.libmpin.MPIN_AES_GCM_ENCRYPT(AES_KEY, IV, HEADER, PLAINTEXT, CIPHERTEXT, TAG) IV_hex = mpin.toHex(IV) CIPHERTEXT_hex = mpin.toHex(CIPHERTEXT) TAG_hex = mpin.toHex(TAG) return CIPHERTEXT_hex, IV_hex, TAG_hex
def aes_gcm_decrypt(aes_key, iv, header, ciphertext): """AES GCM Decrypt.""" # AES Key AES_KEY = mpin.ffi.new('octet*') AES_KEY_val = mpin.ffi.new('char [%s]' % len(aes_key), aes_key) AES_KEY[0].val = AES_KEY_val AES_KEY[0].max = len(aes_key) AES_KEY[0].len = len(aes_key) # Initialization Vector IV = mpin.ffi.new('octet*') IV_val = mpin.ffi.new('char [%s]' % len(iv), iv) IV[0].val = IV_val IV[0].max = len(iv) IV[0].len = len(iv) # Header HEADER = mpin.ffi.new('octet*') HEADER_val = mpin.ffi.new('char [%s]' % len(header), header) HEADER[0].val = HEADER_val HEADER[0].max = len(header) HEADER[0].len = len(header) # Ciphertext CIPHERTEXT = mpin.ffi.new('octet*') CIPHERTEXT_val = mpin.ffi.new('char [%s]' % len(ciphertext), ciphertext) CIPHERTEXT[0].val = CIPHERTEXT_val CIPHERTEXT[0].max = len(ciphertext) CIPHERTEXT[0].len = len(ciphertext) # Plaintext PLAINTEXT = mpin.ffi.new('octet*') PLAINTEXT_val = mpin.ffi.new('char []', CIPHERTEXT[0].len) PLAINTEXT[0].val = PLAINTEXT_val PLAINTEXT[0].max = CIPHERTEXT[0].len PLAINTEXT[0].len = CIPHERTEXT[0].len # Authentication tag TAG = mpin.ffi.new('octet*') TAG_val = mpin.ffi.new('char []', mpin.PAS) TAG[0].val = TAG_val TAG[0].max = mpin.PAS # Decrypt ciphertext mpin.libmpin.MPIN_AES_GCM_DECRYPT(AES_KEY, IV, HEADER, CIPHERTEXT, PLAINTEXT, TAG) return mpin.toHex(TAG), mpin.toHex(PLAINTEXT)
def get_client_multiple(master_secret, mpin_id): """Generate client secret.""" MASTER_SECRET = mpin.ffi.new('octet*') MASTER_SECRET_val = mpin.ffi.new('char [%s]' % len(master_secret), master_secret) MASTER_SECRET[0].val = MASTER_SECRET_val MASTER_SECRET[0].max = len(master_secret) MASTER_SECRET[0].len = len(master_secret) CLIENT_SECRET = mpin.ffi.new('octet*') CLIENT_SECRET_val = mpin.ffi.new('char []', mpin.G1) CLIENT_SECRET[0].val = CLIENT_SECRET_val CLIENT_SECRET[0].max = mpin.G1 CLIENT_SECRET[0].len = mpin.G1 HASH_MPIN_ID = mpin.ffi.new('octet*') HASH_MPIN_ID_val = mpin.ffi.new('char [%s]' % len(mpin_id), mpin_id) HASH_MPIN_ID[0].val = HASH_MPIN_ID_val HASH_MPIN_ID[0].max = len(mpin_id) HASH_MPIN_ID[0].len = len(mpin_id) rtn = mpin.libmpin.MPIN_GET_CLIENT_SECRET(MASTER_SECRET, HASH_MPIN_ID, CLIENT_SECRET) if rtn != 0: raise CryptoError(rtn) return mpin.toHex(CLIENT_SECRET)
def test_5(self): """test_5 Make sure all client secret are unique""" # random number generator RNG = ffi.new("csprng*") libmpin.MPIN_CREATE_CSPRNG(RNG, self.RAW) # Generate master secret share rtn = libmpin.MPIN_RANDOM_GENERATE(RNG, MS1) self.assertEqual(rtn, 0) s = set() match = 0 for i in range(1, 1000): rand_val = os.urandom(32) HASH_MPIN_ID = ffi.new("octet*") HASH_MPIN_IDval = ffi.new("char [%s]" % HASH_BYTES, rand_val) HASH_MPIN_ID[0].val = HASH_MPIN_IDval HASH_MPIN_ID[0].max = HASH_BYTES HASH_MPIN_ID[0].len = HASH_BYTES # Generate client secret shares rtn = libmpin.MPIN_GET_CLIENT_SECRET(MS1, HASH_MPIN_ID, CS1) self.assertEqual(rtn, 0) cs1Hex = toHex(CS1) if cs1Hex in s: match = 1 self.assertEqual(match, 0) s.add(cs1Hex)
def get_time_permit(master_secret, mpin_id, date=None): """Generate client time permit.""" MASTER_SECRET = mpin.ffi.new('octet*') MASTER_SECRET_val = mpin.ffi.new('char [%s]' % len(master_secret), master_secret) MASTER_SECRET[0].val = MASTER_SECRET_val MASTER_SECRET[0].max = len(master_secret) MASTER_SECRET[0].len = len(master_secret) TIME_PERMIT = mpin.ffi.new('octet*') TIME_PERMIT_val = mpin.ffi.new('char []', mpin.G1) TIME_PERMIT[0].val = TIME_PERMIT_val TIME_PERMIT[0].max = mpin.G1 TIME_PERMIT[0].len = mpin.G1 HASH_MPIN_ID = mpin.ffi.new('octet*') HASH_MPIN_ID_val = mpin.ffi.new('char [%s]' % len(mpin_id), mpin_id) HASH_MPIN_ID[0].val = HASH_MPIN_ID_val HASH_MPIN_ID[0].max = len(mpin_id) HASH_MPIN_ID[0].len = len(mpin_id) date = date or today() rtn = mpin.libmpin.MPIN_GET_CLIENT_PERMIT(date, MASTER_SECRET, HASH_MPIN_ID, TIME_PERMIT) if rtn != 0: raise CryptoError(rtn) return mpin.toHex(TIME_PERMIT)
def mpin_recombine_g2(certivox_server_secret, customer_server_secret): """Recombine server secret.""" SS1 = mpin.ffi.new("octet*") SS1_val = mpin.ffi.new("char [%s]" % len(certivox_server_secret), certivox_server_secret) SS1[0].val = SS1_val SS1[0].max = mpin.G2 SS1[0].len = len(certivox_server_secret) SS2 = mpin.ffi.new("octet*") SS2_val = mpin.ffi.new("char [%s]" % len(customer_server_secret), customer_server_secret) SS2[0].val = SS2_val SS2[0].max = mpin.G2 SS2[0].len = len(customer_server_secret) SERVER_SECRET = mpin.ffi.new("octet*") SERVER_SECRET_val = mpin.ffi.new("char []", mpin.G2) SERVER_SECRET[0].val = SERVER_SECRET_val SERVER_SECRET[0].max = mpin.G2 SERVER_SECRET[0].len = mpin.G2 rtn = mpin.libmpin.MPIN_RECOMBINE_G2(SS1, SS2, SERVER_SECRET) if rtn != 0: raise CryptoError(rtn) return mpin.toHex(SERVER_SECRET)
def get_time_permit(master_secret, mpin_id, date=None): """Generate client time permit.""" MASTER_SECRET = mpin.ffi.new('octet*') MASTER_SECRET_val = mpin.ffi.new('char [%s]' % len(master_secret), master_secret) MASTER_SECRET[0].val = MASTER_SECRET_val MASTER_SECRET[0].max = len(master_secret) MASTER_SECRET[0].len = len(master_secret) TIME_PERMIT = mpin.ffi.new('octet*') TIME_PERMIT_val = mpin.ffi.new('char []', mpin.G1) TIME_PERMIT[0].val = TIME_PERMIT_val TIME_PERMIT[0].max = mpin.G1 TIME_PERMIT[0].len = mpin.G1 HASH_MPIN_ID = mpin.ffi.new('octet*') HASH_MPIN_ID_val = mpin.ffi.new('char [%s]' % len(mpin_id), mpin_id) HASH_MPIN_ID[0].val = HASH_MPIN_ID_val HASH_MPIN_ID[0].max = len(mpin_id) HASH_MPIN_ID[0].len = len(mpin_id) date = date or today() rtn = mpin.libmpin.MPIN_GET_CLIENT_PERMIT(date, MASTER_SECRET, HASH_MPIN_ID, TIME_PERMIT) if rtn != 0: raise CryptoError(rtn) return mpin.toHex(TIME_PERMIT)
def aes_gcm_decrypt(aes_key, iv, header, ciphertext): """AES GCM Decrypt.""" # AES Key AES_KEY = mpin.ffi.new('octet*') AES_KEY_val = mpin.ffi.new('char [%s]' % len(aes_key), aes_key) AES_KEY[0].val = AES_KEY_val AES_KEY[0].max = len(aes_key) AES_KEY[0].len = len(aes_key) # Initialization Vector IV = mpin.ffi.new('octet*') IV_val = mpin.ffi.new('char [%s]' % len(iv), iv) IV[0].val = IV_val IV[0].max = len(iv) IV[0].len = len(iv) # Header HEADER = mpin.ffi.new('octet*') HEADER_val = mpin.ffi.new('char [%s]' % len(header), header) HEADER[0].val = HEADER_val HEADER[0].max = len(header) HEADER[0].len = len(header) # Ciphertext CIPHERTEXT = mpin.ffi.new('octet*') CIPHERTEXT_val = mpin.ffi.new('char [%s]' % len(ciphertext), ciphertext) CIPHERTEXT[0].val = CIPHERTEXT_val CIPHERTEXT[0].max = len(ciphertext) CIPHERTEXT[0].len = len(ciphertext) # Plaintext PLAINTEXT = mpin.ffi.new('octet*') PLAINTEXT_val = mpin.ffi.new('char []', CIPHERTEXT[0].len) PLAINTEXT[0].val = PLAINTEXT_val PLAINTEXT[0].max = CIPHERTEXT[0].len PLAINTEXT[0].len = CIPHERTEXT[0].len # Authentication tag TAG = mpin.ffi.new('octet*') TAG_val = mpin.ffi.new('char []', mpin.PAS) TAG[0].val = TAG_val TAG[0].max = mpin.PAS # Decrypt ciphertext mpin.libmpin.MPIN_AES_GCM_DECRYPT(AES_KEY, IV, HEADER, CIPHERTEXT, PLAINTEXT, TAG) return mpin.toHex(TAG), mpin.toHex(PLAINTEXT)
def random_generate(rng, length): """Generate random number with predefined length.""" OTT = mpin.ffi.new('octet*') OTTval = mpin.ffi.new('char []', length) OTT[0].val = OTTval OTT[0].max = length OTT[0].len = length mpin.libmpin.generateRandom(rng, OTT) return mpin.toHex(OTT)
def random_generate(rng, length): """Generate random number with predefined length.""" OTT = mpin.ffi.new('octet*') OTTval = mpin.ffi.new('char []', length) OTT[0].val = OTTval OTT[0].max = length OTT[0].len = length mpin.libmpin.generateRandom(rng, OTT) return mpin.toHex(OTT)
def mpin_random_generate(rng): """Generate random secret.""" MASTER_SECRET = mpin.ffi.new('octet*') MASTER_SECRET_val = mpin.ffi.new('char []', mpin.PGS) MASTER_SECRET[0].val = MASTER_SECRET_val MASTER_SECRET[0].max = mpin.PGS MASTER_SECRET[0].len = mpin.PGS rtn = mpin.libmpin.MPIN_RANDOM_GENERATE(rng, MASTER_SECRET) if rtn != 0: raise CryptoError(rtn) master_secret_hex = mpin.toHex(MASTER_SECRET) return master_secret_hex.decode('hex')
def mpin_random_generate(rng): """Generate random secret.""" MASTER_SECRET = mpin.ffi.new('octet*') MASTER_SECRET_val = mpin.ffi.new('char []', mpin.PGS) MASTER_SECRET[0].val = MASTER_SECRET_val MASTER_SECRET[0].max = mpin.PGS MASTER_SECRET[0].len = mpin.PGS rtn = mpin.libmpin.MPIN_RANDOM_GENERATE(rng, MASTER_SECRET) if rtn != 0: raise CryptoError(rtn) master_secret_hex = mpin.toHex(MASTER_SECRET) return master_secret_hex.decode('hex')
def test_10(self): """test_10 Test mss starting with 00 are handled correctly""" for i in range(1, 1000): # Assign a seed value seed = os.urandom(32) RAW = ffi.new("octet*") RAWval = ffi.new("char [%s]" % len(seed), seed) RAW[0].val = RAWval RAW[0].len = len(seed) RAW[0].max = len(seed) # random number generator RNG = ffi.new("csprng*") libmpin.CREATE_CSPRNG(RNG, RAW) # Generate master secret - ms1 rtn = libmpin.MPIN_RANDOM_GENERATE(RNG, MS1) self.assertEqual(rtn, 0) ms1_hex = toHex(MS1) ms1 = ms1_hex.decode("hex") # Assign ms1 to ms2 if it starts with "00" if ms1_hex.startswith('00'): MS2 = ffi.new("octet*") MS2val = ffi.new("char [%s]" % PGS, ms1) MS2[0].val = MS2val MS2[0].max = PGS MS2[0].len = PGS # Generate client secret shares rtn = libmpin.MPIN_GET_CLIENT_SECRET(MS1, self.HASH_MPIN_ID, CS1) self.assertEqual(rtn, 0) cs1_hex = toHex(CS1) rtn = libmpin.MPIN_GET_CLIENT_SECRET(MS2, self.HASH_MPIN_ID, CS2) self.assertEqual(rtn, 0) cs2_hex = toHex(CS2) self.assertEqual(cs1_hex, cs2_hex)
def mpin_server_1(mpin_id, date): """Calculate HID and HTOD.""" HID = mpin.ffi.new("octet*") HIDval = mpin.ffi.new("char []", mpin.G1) HID[0].val = HIDval HID[0].max = mpin.G1 HID[0].len = mpin.G1 # H(T|H(ID)) HTID = mpin.ffi.new("octet*") HTIDval = mpin.ffi.new("char []", mpin.G1) HTID[0].val = HTIDval HTID[0].max = mpin.G1 HTID[0].len = mpin.G1 MPIN_ID = mpin.ffi.new("octet*") MPIN_ID_val = mpin.ffi.new("char [%s]" % len(mpin_id), mpin_id) MPIN_ID[0].val = MPIN_ID_val MPIN_ID[0].max = len(mpin_id) MPIN_ID[0].len = len(mpin_id) mpin.libmpin.MPIN_SERVER_1(date, MPIN_ID, HID, HTID) return mpin.toHex(HID).decode('hex'), mpin.toHex(HTID).decode('hex')
def mpin_server_1(mpin_id, date): """Calculate HID and HTOD.""" HID = mpin.ffi.new("octet*") HIDval = mpin.ffi.new("char []", mpin.G1) HID[0].val = HIDval HID[0].max = mpin.G1 HID[0].len = mpin.G1 # H(T|H(ID)) HTID = mpin.ffi.new("octet*") HTIDval = mpin.ffi.new("char []", mpin.G1) HTID[0].val = HTIDval HTID[0].max = mpin.G1 HTID[0].len = mpin.G1 MPIN_ID = mpin.ffi.new("octet*") MPIN_ID_val = mpin.ffi.new("char [%s]" % len(mpin_id), mpin_id) MPIN_ID[0].val = MPIN_ID_val MPIN_ID[0].max = len(mpin_id) MPIN_ID[0].len = len(mpin_id) mpin.libmpin.MPIN_SERVER_1(date, MPIN_ID, HID, HTID) return mpin.toHex(HID).decode('hex'), mpin.toHex(HTID).decode('hex')
def get_server_secret(master_secret): """Generate secret secret.""" MASTER_SECRET = mpin.ffi.new('octet*') MASTER_SECRET_val = mpin.ffi.new('char [%s]' % len(master_secret), master_secret) MASTER_SECRET[0].val = MASTER_SECRET_val MASTER_SECRET[0].max = len(master_secret) MASTER_SECRET[0].len = len(master_secret) SERVER_SECRET = mpin.ffi.new('octet*') SERVER_SECRET_val = mpin.ffi.new('char []', mpin.G2) SERVER_SECRET[0].val = SERVER_SECRET_val SERVER_SECRET[0].max = mpin.G2 SERVER_SECRET[0].len = mpin.G2 rtn = mpin.libmpin.MPIN_GET_SERVER_SECRET(MASTER_SECRET, SERVER_SECRET) if rtn != 0: raise CryptoError(rtn) return mpin.toHex(SERVER_SECRET)
def get_server_secret(master_secret): """Generate secret secret.""" MASTER_SECRET = mpin.ffi.new('octet*') MASTER_SECRET_val = mpin.ffi.new('char [%s]' % len(master_secret), master_secret) MASTER_SECRET[0].val = MASTER_SECRET_val MASTER_SECRET[0].max = len(master_secret) MASTER_SECRET[0].len = len(master_secret) SERVER_SECRET = mpin.ffi.new('octet*') SERVER_SECRET_val = mpin.ffi.new('char []', mpin.G2) SERVER_SECRET[0].val = SERVER_SECRET_val SERVER_SECRET[0].max = mpin.G2 SERVER_SECRET[0].len = mpin.G2 rtn = mpin.libmpin.MPIN_GET_SERVER_SECRET(MASTER_SECRET, SERVER_SECRET) if rtn != 0: raise CryptoError(rtn) return mpin.toHex(SERVER_SECRET)
def test_4(self): """test_4 Test hash function""" HASH_MPIN_ID = ffi.new("octet*") HASH_MPIN_IDval = ffi.new("char []", HASH_BYTES) HASH_MPIN_ID[0].val = HASH_MPIN_IDval HASH_MPIN_ID[0].max = HASH_BYTES HASH_MPIN_ID[0].len = HASH_BYTES for i in range(1, 10000): bytesStr = os.urandom(128) hash_object2 = hashlib.sha256(bytesStr) digest = hash_object2.hexdigest() MPIN_ID = ffi.new("octet*") MPIN_IDval = ffi.new("char [%s]" % len(bytesStr), bytesStr) MPIN_ID[0].val = MPIN_IDval MPIN_ID[0].max = len(bytesStr) MPIN_ID[0].len = len(bytesStr) libmpin.MPIN_HASH_ID(MPIN_ID, HASH_MPIN_ID) self.assertEqual(digest, toHex(HASH_MPIN_ID))
def mpin_recombine_g2(certivox_server_secret, customer_server_secret): """Recombine server secret.""" SS1 = mpin.ffi.new("octet*") SS1_val = mpin.ffi.new("char [%s]" % len(certivox_server_secret), certivox_server_secret) SS1[0].val = SS1_val SS1[0].max = mpin.G2 SS1[0].len = len(certivox_server_secret) SS2 = mpin.ffi.new("octet*") SS2_val = mpin.ffi.new("char [%s]" % len(customer_server_secret), customer_server_secret) SS2[0].val = SS2_val SS2[0].max = mpin.G2 SS2[0].len = len(customer_server_secret) SERVER_SECRET = mpin.ffi.new("octet*") SERVER_SECRET_val = mpin.ffi.new("char []", mpin.G2) SERVER_SECRET[0].val = SERVER_SECRET_val SERVER_SECRET[0].max = mpin.G2 SERVER_SECRET[0].len = mpin.G2 rtn = mpin.libmpin.MPIN_RECOMBINE_G2(SS1, SS2, SERVER_SECRET) if rtn != 0: raise CryptoError(rtn) return mpin.toHex(SERVER_SECRET)
def get_client_multiple(master_secret, mpin_id): """Generate client secret.""" MASTER_SECRET = mpin.ffi.new('octet*') MASTER_SECRET_val = mpin.ffi.new('char [%s]' % len(master_secret), master_secret) MASTER_SECRET[0].val = MASTER_SECRET_val MASTER_SECRET[0].max = len(master_secret) MASTER_SECRET[0].len = len(master_secret) CLIENT_SECRET = mpin.ffi.new('octet*') CLIENT_SECRET_val = mpin.ffi.new('char []', mpin.G1) CLIENT_SECRET[0].val = CLIENT_SECRET_val CLIENT_SECRET[0].max = mpin.G1 CLIENT_SECRET[0].len = mpin.G1 HASH_MPIN_ID = mpin.ffi.new('octet*') HASH_MPIN_ID_val = mpin.ffi.new('char [%s]' % len(mpin_id), mpin_id) HASH_MPIN_ID[0].val = HASH_MPIN_ID_val HASH_MPIN_ID[0].max = len(mpin_id) HASH_MPIN_ID[0].len = len(mpin_id) rtn = mpin.libmpin.MPIN_GET_CLIENT_SECRET(MASTER_SECRET, HASH_MPIN_ID, CLIENT_SECRET) if rtn != 0: raise CryptoError(rtn) return mpin.toHex(CLIENT_SECRET)
def test_7(self): """test_7 Make sure all random values are random i.e. they should collide""" # random number generator RNG = ffi.new("csprng*") libmpin.MPIN_CREATE_CSPRNG(RNG, self.RAW) # Generate 100 byte random number RANDOMlen = 3 RANDOM = ffi.new("octet*") RANDOMval = ffi.new("char []", RANDOMlen) RANDOM[0].val = RANDOMval RANDOM[0].max = RANDOMlen RANDOM[0].len = RANDOMlen s = set() match = 0 for i in range(1, 10000): libmpin.generateRandom(RNG, RANDOM) random = toHex(RANDOM) if random in s: # print i match = 1 s.add(random) self.assertEqual(match, 1)
def test_auth_success(): """Test the basic authentication flow.""" seed = open('/dev/urandom', 'rb').read(100) RNG = crypto.get_random_generator(seed) y = crypto.mpin_random_generate(RNG) date = 16238 PIN = 1234 mpin_id = '{"mobile": 1, "issued": "2013-10-19T06:12:28Z", "userID": "*****@*****.**", "salt": "e0842acc8cc38fc4"}' token = "040d73e9b7c746525edbb90e042a6b8f6e41e2417a0c0c1600f8b693c0b6c0bbce0c61b73100798c7505b3eb12c2393187355145090333f904fd896684ec4990d3".decode("hex") timePermit = "0408ba13483e817626a45be598b1b89296aa805a6aa31e98503321c30d7177711a1c98a77cbf8edf2497d0f5f7593c72457b36cd3e4f19e1f3c5636c0ca7a1817d".decode("hex") serverSecret = "0d5a0bb4621c4eec9ee28b0339047e7afdaae87c5f0f972253f2e90f55dbda4a16efc98cb3b925d4237a14527b1db361f460dae271f115c28ff5f3ef5fb5dae20a8ccc12bea3fc3f5911853eff3642e649140fcf0892a13ec8b22e94a750a2930c64f5792a22bc01580cbd041c7a8c21659abacead12fd4460f17b27f5940d4d".decode("hex") # Client part Y = mpin.ffi.new("octet*") Yval = mpin.ffi.new("char [%s]" % len(y), y) Y[0].val = Yval Y[0].max = len(y) Y[0].len = len(y) MPIN_ID = mpin.ffi.new("octet*") MPIN_IDval = mpin.ffi.new("char [%s]" % len(mpin_id), mpin_id) MPIN_ID[0].val = MPIN_IDval MPIN_ID[0].max = len(mpin_id) MPIN_ID[0].len = len(mpin_id) TOKEN = mpin.ffi.new("octet*") TOKENval = mpin.ffi.new("char [%s]" % len(token), token) TOKEN[0].val = TOKENval TOKEN[0].len = len(token) TOKEN[0].max = len(token) X = mpin.ffi.new("octet*") Xval = mpin.ffi.new("char []", mpin.PGS) X[0].val = Xval X[0].max = mpin.PGS X[0].len = mpin.PGS CLIENT_SECRET = mpin.ffi.new("octet*") CLIENT_SECRETval = mpin.ffi.new("char []", mpin.G1) CLIENT_SECRET[0].val = CLIENT_SECRETval CLIENT_SECRET[0].max = mpin.G1 CLIENT_SECRET[0].len = mpin.G1 U = mpin.ffi.new("octet*") Uval = mpin.ffi.new("char []", mpin.G1) U[0].val = Uval U[0].max = mpin.G1 U[0].len = mpin.G1 UT = mpin.ffi.new("octet*") UTval = mpin.ffi.new("char []", mpin.G1) UT[0].val = UTval UT[0].max = mpin.G1 UT[0].len = mpin.G1 TIMEPERMIT = mpin.ffi.new("octet*") TIMEPERMITval = mpin.ffi.new("char [%s]" % len(timePermit), timePermit) TIMEPERMIT[0].val = TIMEPERMITval TIMEPERMIT[0].len = len(timePermit) TIMEPERMIT[0].max = len(timePermit) # Client first pass rtn = mpin.libmpin.MPIN_CLIENT_1(date, MPIN_ID, RNG, X, PIN, TOKEN, CLIENT_SECRET, U, UT, TIMEPERMIT) assert rtn == 0 # Client second pass rtn = mpin.libmpin.MPIN_CLIENT_2(X, Y, CLIENT_SECRET) assert rtn == 0 # Server second pass hid, htid = crypto.mpin_server_1(mpin_id, date) success_code, _, _ = crypto.mpin_server_2( serverSecret, mpin.toHex(CLIENT_SECRET).decode('hex'), date, hid, htid, mpin.toHex(Y).decode('hex'), mpin.toHex(U).decode('hex'), mpin.toHex(UT).decode('hex')) assert success_code == 0
def test_1(self): """test_1 Good PIN and good token""" vectors = json.load(open("./MPINTestVectors.json", "r")) for vector in vectors: print "Test vector {}".format(vector['test_no']) PIN1 = vector['PIN1'] PIN2 = vector['PIN2'] date = vector['DATE'] # random number generator RNG = ffi.new("csprng*") libmpin.MPIN_CREATE_CSPRNG(RNG, self.RAW) MS1_HEX = vector['MS1'] MS2_HEX = vector['MS2'] ms1_bin = MS1_HEX.decode("hex") MS1 = ffi.new("octet*") MS1val = ffi.new("char [%s]" % len(ms1_bin), ms1_bin) MS1[0].val = MS1val MS1[0].max = PGS MS1[0].len = PGS ms2_bin = MS2_HEX.decode("hex") MS2 = ffi.new("octet*") MS2val = ffi.new("char [%s]" % len(ms2_bin), ms2_bin) MS2[0].val = MS2val MS2[0].max = PGS MS2[0].len = PGS # Generate server secret shares rtn = libmpin.MPIN_GET_SERVER_SECRET(MS1, SS1) self.assertEqual(rtn, 0) self.assertEqual(vector['SS1'], toHex(SS1)) rtn = libmpin.MPIN_GET_SERVER_SECRET(MS2, SS2) self.assertEqual(rtn, 0) self.assertEqual(vector['SS2'], toHex(SS2)) # Combine server secret shares rtn = libmpin.MPIN_RECOMBINE_G2(SS1, SS2, SERVER_SECRET) self.assertEqual(rtn, 0) self.assertEqual(vector['SERVER_SECRET'], toHex(SERVER_SECRET)) mpin_id = vector['MPIN_ID_HEX'].decode("hex") MPIN_ID = ffi.new("octet*") MPIN_IDval = ffi.new("char [%s]" % len(mpin_id), mpin_id) MPIN_ID[0].val = MPIN_IDval MPIN_ID[0].max = len(mpin_id) MPIN_ID[0].len = len(mpin_id) # Hash value of MPIN_ID HASH_MPIN_ID = ffi.new("octet*") HASH_MPIN_IDval = ffi.new("char []", HASH_BYTES) HASH_MPIN_ID[0].val = HASH_MPIN_IDval HASH_MPIN_ID[0].max = HASH_BYTES HASH_MPIN_ID[0].len = HASH_BYTES libmpin.MPIN_HASH_ID(MPIN_ID, HASH_MPIN_ID) self.assertEqual(vector['HASH_MPIN_ID_HEX'], toHex(HASH_MPIN_ID)) # Generate client secret shares rtn = libmpin.MPIN_GET_CLIENT_SECRET(MS1, HASH_MPIN_ID, CS1) self.assertEqual(rtn, 0) self.assertEqual(vector['CS1'], toHex(CS1)) rtn = libmpin.MPIN_GET_CLIENT_SECRET(MS2, HASH_MPIN_ID, CS2) self.assertEqual(rtn, 0) self.assertEqual(vector['CS2'], toHex(CS2)) # Combine client secret shares : TOKEN is the full client secret rtn = libmpin.MPIN_RECOMBINE_G1(CS1, CS2, TOKEN) self.assertEqual(rtn, 0) self.assertEqual(vector['CLIENT_SECRET'], toHex(TOKEN)) # Generate Time Permit shares rtn = libmpin.MPIN_GET_CLIENT_PERMIT(date, MS1, HASH_MPIN_ID, TP1) self.assertEqual(rtn, 0) self.assertEqual(vector['TP1'], toHex(TP1)) rtn = libmpin.MPIN_GET_CLIENT_PERMIT(date, MS2, HASH_MPIN_ID, TP2) self.assertEqual(rtn, 0) self.assertEqual(vector['TP2'], toHex(TP2)) # Combine Time Permit shares rtn = libmpin.MPIN_RECOMBINE_G1(TP1, TP2, TIME_PERMIT) self.assertEqual(rtn, 0) self.assertEqual(vector['TIME_PERMIT'], toHex(TIME_PERMIT)) # Client extracts PIN from secret to create Token rtn = libmpin.MPIN_EXTRACT_PIN(MPIN_ID, PIN1, TOKEN) self.assertEqual(rtn, 0) self.assertEqual(vector['TOKEN'], toHex(TOKEN)) x = vector['X'].decode("hex") X = ffi.new("octet*") Xval = ffi.new("char [%s]" % PGS, x) X[0].val = Xval X[0].max = PGS X[0].len = PGS # Client first pass. Use X value from test vectors rtn = libmpin.MPIN_CLIENT_1(date, MPIN_ID, ffi.NULL, X, PIN2, TOKEN, SEC, U, UT, TIME_PERMIT) self.assertEqual(rtn, 0) self.assertEqual(vector['X'], toHex(X)) self.assertEqual(vector['U'], toHex(U)) self.assertEqual(vector['UT'], toHex(UT)) self.assertEqual(vector['SEC'], toHex(SEC)) # Server calculates H(ID) and H(T|H(ID)) libmpin.MPIN_SERVER_1(date, HASH_MPIN_ID, HID, HTID) # Server generates Random number Y and sends it to Client # rtn = libmpin.MPIN_RANDOM_GENERATE(RNG,Y) # self.assertEqual(rtn, 0) # Use Y value from test vectors y = vector['Y'].decode("hex") Y = ffi.new("octet*") Yval = ffi.new("char [%s]" % PGS, y) Y[0].val = Yval Y[0].max = PGS Y[0].len = PGS # Client second pass rtn = libmpin.MPIN_CLIENT_2(X, Y, SEC) self.assertEqual(rtn, 0) self.assertEqual(vector['V'], toHex(SEC)) # Server second pass rtn = libmpin.MPIN_SERVER_2(date, HID, HTID, Y, SERVER_SECRET, U, UT, SEC, E, F) self.assertEqual(rtn, vector['SERVER_OUTPUT'])
HID = ffi.NULL U = ffi.NULL prHID = HTID else: HTID = ffi.NULL UT = ffi.NULL prHID = HID # Assign a seed value RAW = ffi.new("octet*") RAWval = ffi.new("char [%s]" % len(seed), seed) RAW[0].val = RAWval RAW[0].len = len(seed) RAW[0].max = len(seed) if DEBUG: print "RAW: %s" % toHex(RAW) # random number generator RNG = ffi.new("csprng*") libmpin.MPIN_CREATE_CSPRNG(RNG, RAW) # Hash MPIN_ID libmpin.MPIN_HASH_ID(MPIN_ID, HASH_MPIN_ID) if DEBUG: print "MPIN_ID: %s" % toHex(MPIN_ID) print "HASH_MPIN_ID: %s" % toHex(HASH_MPIN_ID) # Generate master secret for MIRACL and Customer rtn = libmpin.MPIN_RANDOM_GENERATE(RNG, MS1) if rtn != 0: print "libmpin.MPIN_RANDOM_GENERATE(RNG,MS1) Error %s", rtn
date = libmpin.today() if date: HID = ffi.NULL U = ffi.NULL else: HTID = ffi.NULL UT = ffi.NULL # Assign a seed value RAW = ffi.new("octet*") RAWval = ffi.new("char [%s]" % len(seed), seed) RAW[0].val = RAWval RAW[0].len = len(seed) RAW[0].max = len(seed) if DEBUG: print "RAW: %s" % toHex(RAW) # random number generator RNG = ffi.new("csprng*") libmpin.CREATE_CSPRNG(RNG, RAW) # Hash MPIN_ID libmpin.MPIN_HASH_ID(MPIN_ID, HASH_MPIN_ID) if DEBUG: print "MPIN_ID: %s" % toHex(MPIN_ID) print "HASH_MPIN_ID: %s" % toHex(HASH_MPIN_ID) # Generate master secret for MIRACL and Customer rtn = libmpin.MPIN_RANDOM_GENERATE(RNG, MS1) if rtn != 0: print "libmpin.MPIN_RANDOM_GENERATE(RNG,MS1) Error %s", rtn
date = libmpin.MPIN_today() if date: HID = ffi.NULL U = ffi.NULL else: HTID = ffi.NULL UT = ffi.NULL # Assign a seed value RAW = ffi.new("octet*") RAWval = ffi.new("char [%s]" % len(seed), seed) RAW[0].val = RAWval RAW[0].len = len(seed) RAW[0].max = len(seed) if DEBUG: print "RAW: %s" % toHex(RAW) # random number generator RNG = ffi.new("csprng*") libmpin.MPIN_CREATE_CSPRNG(RNG, RAW) # Hash MPIN_ID libmpin.MPIN_HASH_ID(MPIN_ID, HASH_MPIN_ID) if DEBUG: print "MPIN_ID: %s" % toHex(MPIN_ID) print "HASH_MPIN_ID: %s" % toHex(HASH_MPIN_ID) # Generate master secret for MIRACL and Customer rtn = libmpin.MPIN_RANDOM_GENERATE(RNG, MS1) if rtn != 0: print "libmpin.MPIN_RANDOM_GENERATE(RNG,MS1) Error %s", rtn
def test_10(self): """test_10 AES-GCM: Failed encryption and decryption by changing a header byte""" # Generate 16 byte key key_val = os.urandom(PAS) AES_KEY = ffi.new("octet*") AES_KEYval = ffi.new("char [%s]" % PAS, key_val) AES_KEY[0].val = AES_KEYval AES_KEY[0].max = PAS AES_KEY[0].len = PAS # Generate 12 byte IV iv_val = os.urandom(IVL) IV = ffi.new("octet*") IVval = ffi.new("char [%s]" % IVL, iv_val) IV[0].val = IVval IV[0].max = IVL IV[0].len = IVL # Generate a 32 byte random header header_val = os.urandom(32) HEADER = ffi.new("octet*") HEADERval = ffi.new("char [%s]" % len(header_val), header_val) HEADER[0].val = HEADERval HEADER[0].max = len(header_val) HEADER[0].len = len(header_val) # Plaintext input plaintext1 = "A test message" PLAINTEXT1 = ffi.new("octet*") PLAINTEXT1val = ffi.new("char [%s]" % len(plaintext1), plaintext1) PLAINTEXT1[0].val = PLAINTEXT1val PLAINTEXT1[0].max = len(plaintext1) PLAINTEXT1[0].len = len(plaintext1) # print "Input message: %s" % ffi.string(PLAINTEXT1[0].val, PLAINTEXT1[0].len) # Ciphertext CIPHERTEXT = ffi.new("octet*") CIPHERTEXTval = ffi.new("char []", len(plaintext1)) CIPHERTEXT[0].val = CIPHERTEXTval CIPHERTEXT[0].max = len(plaintext1) # 16 byte authentication tag TAG1 = ffi.new("octet*") TAG1val = ffi.new("char []", PAS) TAG1[0].val = TAG1val TAG1[0].max = PAS libmpin.MPIN_AES_GCM_ENCRYPT(AES_KEY, IV, HEADER, PLAINTEXT1, CIPHERTEXT, TAG1) # Plaintext output PLAINTEXT2 = ffi.new("octet*") PLAINTEXT2val = ffi.new("char []", CIPHERTEXT[0].len) PLAINTEXT2[0].val = PLAINTEXT2val PLAINTEXT2[0].max = CIPHERTEXT[0].len PLAINTEXT2[0].len = CIPHERTEXT[0].len # Change one byte of header HEADER[0].val[0] = "\xa5" # 16 byte authentication tag TAG2 = ffi.new("octet*") TAG2val = ffi.new("char []", PAS) TAG2[0].val = TAG2val TAG2[0].max = PAS libmpin.MPIN_AES_GCM_DECRYPT(AES_KEY, IV, HEADER, CIPHERTEXT, PLAINTEXT2, TAG2) self.assertNotEqual(toHex(TAG1), toHex(TAG2)) self.assertEqual(toHex(PLAINTEXT1), toHex(PLAINTEXT2))
def mpin_server_2(server_secret, v, date, hid, htid, y, u, ut): """Check credentials.""" SERVER_SECRET = mpin.ffi.new("octet*") SERVER_SECRET_val = mpin.ffi.new("char [%s]" % len(server_secret), server_secret) SERVER_SECRET[0].val = SERVER_SECRET_val SERVER_SECRET[0].max = mpin.G2 SERVER_SECRET[0].len = len(server_secret) V = mpin.ffi.new("octet*") V_val = mpin.ffi.new("char [%s]" % len(v), v) V[0].val = V_val V[0].max = len(v) V[0].len = len(v) lenEF = 12 * mpin.PFS E = mpin.ffi.new("octet*") Eval = mpin.ffi.new("char []", lenEF) E[0].val = Eval E[0].max = lenEF E[0].len = lenEF F = mpin.ffi.new("octet*") Fval = mpin.ffi.new("char []", lenEF) F[0].val = Fval F[0].max = lenEF F[0].len = lenEF HID = mpin.ffi.new("octet*") HIDval = mpin.ffi.new("char [%s]" % len(hid), hid) HID[0].val = HIDval HID[0].max = len(hid) HID[0].len = len(hid) # H(T|H(ID)) HTID = mpin.ffi.new("octet*") HTIDval = mpin.ffi.new("char [%s]" % len(htid), htid) HTID[0].val = HTIDval HTID[0].max = len(htid) HTID[0].len = len(htid) # Client part Y = mpin.ffi.new("octet*") Yval = mpin.ffi.new("char [%s]" % len(y), y) Y[0].val = Yval Y[0].max = len(y) Y[0].len = len(y) U = mpin.ffi.new("octet*") Uval = mpin.ffi.new("char [%s]" % len(u), u) U[0].val = Uval U[0].max = len(u) U[0].len = len(u) UT = mpin.ffi.new("octet*") UTval = mpin.ffi.new("char [%s]" % len(ut), ut) UT[0].val = UTval UT[0].max = len(ut) UT[0].len = len(ut) return mpin.libmpin.MPIN_SERVER_2(date, HID, HTID, Y, SERVER_SECRET, U, UT, V, E, F), mpin.toHex(E), mpin.toHex(F)
HID = ffi.NULL U = ffi.NULL prHID = HTID else: HTID = ffi.NULL UT = ffi.NULL prHID = HID # Assign a seed value RAW = ffi.new("octet*") RAWval = ffi.new("char [%s]" % len(seed), seed) RAW[0].val = RAWval RAW[0].len = len(seed) RAW[0].max = len(seed) if DEBUG: print "RAW: %s" % toHex(RAW) # random number generator RNG = ffi.new("csprng*") libmpin.CREATE_CSPRNG(RNG, RAW) # Hash MPIN_ID libmpin.MPIN_HASH_ID(MPIN_ID, HASH_MPIN_ID) if DEBUG: print "MPIN_ID: %s" % toHex(MPIN_ID) print "HASH_MPIN_ID: %s" % toHex(HASH_MPIN_ID) # Generate master secret for MIRACL and Customer rtn = libmpin.MPIN_RANDOM_GENERATE(RNG, MS1) if rtn != 0: print "libmpin.MPIN_RANDOM_GENERATE(RNG,MS1) Error %s", rtn
def genVector(mpin_id, date, PIN1, PIN2, test_no): """Generate a single test vector Use mpin_id and date to generate a valid Client Secret and Time Permit Args:: mpin_id: The M-Pin ID date: The date of M-Pin Authentication PIN1: PIN for generating token PIN2: PIN for authenticating test_no: Test vector identifier Returns: vector: A test vector Raises: Exception """ vector = {} if DEBUG: print test_no vector['test_no'] = test_no vector['mpin_id'] = mpin_id # Generate master secret shares rtn = mpin.libmpin.MPIN_RANDOM_GENERATE(RNG,MS1) assert rtn is 0, "MS1" vector['MS1'] = mpin.toHex(MS1) rtn = mpin.libmpin.MPIN_RANDOM_GENERATE(RNG,MS2) assert rtn is 0, "MS2" vector['MS2'] = mpin.toHex(MS2) # Generate server secret shares rtn = mpin.libmpin.MPIN_GET_SERVER_SECRET(MS1,SS1) assert rtn is 0, "SS1" vector['SS1'] = mpin.toHex(SS1) rtn = mpin.libmpin.MPIN_GET_SERVER_SECRET(MS2,SS2) assert rtn is 0, "SS2" vector['SS2'] = mpin.toHex(SS2) # Combine server secret shares rtn = mpin.libmpin.MPIN_RECOMBINE_G2(SS1, SS2, SERVER_SECRET) assert rtn is 0, "SERVER_SECRET" vector['SERVER_SECRET'] = mpin.toHex(SERVER_SECRET) # Identity MPIN_ID = mpin.ffi.new("octet*") MPIN_IDval = mpin.ffi.new("char [%s]" % len(mpin_id), mpin_id) MPIN_ID[0].val = MPIN_IDval MPIN_ID[0].max = len(mpin_id) MPIN_ID[0].len = len(mpin_id) vector['MPIN_ID_HEX'] = mpin.toHex(MPIN_ID) # Hash MPIN_ID mpin.libmpin.MPIN_HASH_ID(MPIN_ID, HASH_MPIN_ID) vector['HASH_MPIN_ID_HEX'] = mpin.toHex(HASH_MPIN_ID) # Generate client secret shares rtn = mpin.libmpin.MPIN_GET_CLIENT_SECRET(MS1,HASH_MPIN_ID,CS1) assert rtn is 0, "CS1" vector['CS1'] = mpin.toHex(CS1) rtn = mpin.libmpin.MPIN_GET_CLIENT_SECRET(MS2,HASH_MPIN_ID,CS2) assert rtn is 0, "CS2" vector['CS2'] = mpin.toHex(CS2) # Combine client secret shares : TOKEN is the full client secret rtn = mpin.libmpin.MPIN_RECOMBINE_G1(CS1, CS2, TOKEN) assert rtn is 0, "CS1+CS2" vector['CLIENT_SECRET'] = mpin.toHex(TOKEN) # Generate Time Permit shares rtn = mpin.libmpin.MPIN_GET_CLIENT_PERMIT(date,MS1,HASH_MPIN_ID,TP1) assert rtn is 0, "TP1" vector['TP1'] = mpin.toHex(TP1) vector['DATE'] = date rtn = mpin.libmpin.MPIN_GET_CLIENT_PERMIT(date,MS2,HASH_MPIN_ID,TP2) assert rtn is 0, "TP2" vector['TP2'] = mpin.toHex(TP2) # Combine Time Permit shares rtn = mpin.libmpin.MPIN_RECOMBINE_G1(TP1, TP2, TIME_PERMIT) assert rtn is 0, "TP1+TP2" vector['TIME_PERMIT'] = mpin.toHex(TIME_PERMIT) # Client extracts PIN from secret to create Token rtn = mpin.libmpin.MPIN_EXTRACT_PIN(MPIN_ID, PIN1, TOKEN) assert rtn is 0, "TOKEN" vector['PIN1'] = PIN1 vector['TOKEN'] = mpin.toHex(TOKEN) # Client pass TimeValue = mpin.libmpin.MPIN_GET_TIME() rtn = mpin.libmpin.MPIN_CLIENT(date, MPIN_ID, RNG, X, PIN2, TOKEN, SEC, U, UT, TIME_PERMIT, TimeValue, Y1) assert rtn is 0, "MPIN_CLIENT" vector['PIN2'] = PIN2 vector['X'] = mpin.toHex(X) vector['U'] = mpin.toHex(U) vector['UT'] = mpin.toHex(UT) vector['SEC'] = mpin.toHex(SEC) vector['TimeValue'] = TimeValue vector['Y'] = mpin.toHex(Y1) # Server pass rtn = mpin.libmpin.MPIN_SERVER(date, HID, HTID, Y2, SERVER_SECRET, U, UT, SEC, E, F, MPIN_ID, TimeValue) assert mpin.toHex(Y1) == mpin.toHex(Y2), "Y equal" vector['SERVER_OUTPUT'] = rtn if PIN1 == PIN2: assert rtn == 0, "successful authentication" else: assert rtn == -19, "failed authentication" return vector
def test_1(self): """test_1 Good PIN and good token""" vectors = json.load(open("./MPINTestVectors.json", "r")) for vector in vectors: print "Test vector {}".format(vector['test_no']) PIN1 = vector['PIN1'] PIN2 = vector['PIN2'] date = vector['DATE'] # random number generator RNG = ffi.new("csprng*") libmpin.CREATE_CSPRNG(RNG, self.RAW) MS1_HEX = vector['MS1'] MS2_HEX = vector['MS2'] ms1_bin = MS1_HEX.decode("hex") MS1 = ffi.new("octet*") MS1val = ffi.new("char [%s]" % len(ms1_bin), ms1_bin) MS1[0].val = MS1val MS1[0].max = PGS MS1[0].len = PGS ms2_bin = MS2_HEX.decode("hex") MS2 = ffi.new("octet*") MS2val = ffi.new("char [%s]" % len(ms2_bin), ms2_bin) MS2[0].val = MS2val MS2[0].max = PGS MS2[0].len = PGS # Generate server secret shares rtn = libmpin.MPIN_GET_SERVER_SECRET(MS1, SS1) self.assertEqual(rtn, 0) self.assertEqual(vector['SS1'], toHex(SS1)) rtn = libmpin.MPIN_GET_SERVER_SECRET(MS2, SS2) self.assertEqual(rtn, 0) self.assertEqual(vector['SS2'], toHex(SS2)) # Combine server secret shares rtn = libmpin.MPIN_RECOMBINE_G2(SS1, SS2, SERVER_SECRET) self.assertEqual(rtn, 0) self.assertEqual(vector['SERVER_SECRET'], toHex(SERVER_SECRET)) mpin_id = vector['MPIN_ID_HEX'].decode("hex") MPIN_ID = ffi.new("octet*") MPIN_IDval = ffi.new("char [%s]" % len(mpin_id), mpin_id) MPIN_ID[0].val = MPIN_IDval MPIN_ID[0].max = len(mpin_id) MPIN_ID[0].len = len(mpin_id) # Hash value of MPIN_ID HASH_MPIN_ID = ffi.new("octet*") HASH_MPIN_IDval = ffi.new("char []", HASH_BYTES) HASH_MPIN_ID[0].val = HASH_MPIN_IDval HASH_MPIN_ID[0].max = HASH_BYTES HASH_MPIN_ID[0].len = HASH_BYTES libmpin.MPIN_HASH_ID(MPIN_ID, HASH_MPIN_ID) self.assertEqual(vector['HASH_MPIN_ID_HEX'], toHex(HASH_MPIN_ID)) # Generate client secret shares rtn = libmpin.MPIN_GET_CLIENT_SECRET(MS1, HASH_MPIN_ID, CS1) self.assertEqual(rtn, 0) self.assertEqual(vector['CS1'], toHex(CS1)) rtn = libmpin.MPIN_GET_CLIENT_SECRET(MS2, HASH_MPIN_ID, CS2) self.assertEqual(rtn, 0) self.assertEqual(vector['CS2'], toHex(CS2)) # Combine client secret shares : TOKEN is the full client secret rtn = libmpin.MPIN_RECOMBINE_G1(CS1, CS2, TOKEN) self.assertEqual(rtn, 0) self.assertEqual(vector['CLIENT_SECRET'], toHex(TOKEN)) # Generate Time Permit shares rtn = libmpin.MPIN_GET_CLIENT_PERMIT(date, MS1, HASH_MPIN_ID, TP1) self.assertEqual(rtn, 0) self.assertEqual(vector['TP1'], toHex(TP1)) rtn = libmpin.MPIN_GET_CLIENT_PERMIT(date, MS2, HASH_MPIN_ID, TP2) self.assertEqual(rtn, 0) self.assertEqual(vector['TP2'], toHex(TP2)) # Combine Time Permit shares rtn = libmpin.MPIN_RECOMBINE_G1(TP1, TP2, TIME_PERMIT) self.assertEqual(rtn, 0) self.assertEqual(vector['TIME_PERMIT'], toHex(TIME_PERMIT)) # Client extracts PIN from secret to create Token rtn = libmpin.MPIN_EXTRACT_PIN(MPIN_ID, PIN1, TOKEN) self.assertEqual(rtn, 0) self.assertEqual(vector['TOKEN'], toHex(TOKEN)) x = vector['X'].decode("hex") X = ffi.new("octet*") Xval = ffi.new("char [%s]" % PGS, x) X[0].val = Xval X[0].max = PGS X[0].len = PGS # Client first pass. Use X value from test vectors rtn = libmpin.MPIN_CLIENT_1(date, MPIN_ID, ffi.NULL, X, PIN2, TOKEN, SEC, U, UT, TIME_PERMIT) self.assertEqual(rtn, 0) self.assertEqual(vector['X'], toHex(X)) self.assertEqual(vector['U'], toHex(U)) self.assertEqual(vector['UT'], toHex(UT)) self.assertEqual(vector['SEC'], toHex(SEC)) # Server calculates H(ID) and H(T|H(ID)) libmpin.MPIN_SERVER_1(date, MPIN_ID, HID, HTID) # Server generates Random number Y and sends it to Client # rtn = libmpin.MPIN_RANDOM_GENERATE(RNG,Y) # self.assertEqual(rtn, 0) # Use Y value from test vectors y = vector['Y'].decode("hex") Y = ffi.new("octet*") Yval = ffi.new("char [%s]" % PGS, y) Y[0].val = Yval Y[0].max = PGS Y[0].len = PGS # Client second pass rtn = libmpin.MPIN_CLIENT_2(X, Y, SEC) self.assertEqual(rtn, 0) self.assertEqual(vector['V'], toHex(SEC)) # Server second pass rtn = libmpin.MPIN_SERVER_2(date, HID, HTID, Y, SERVER_SECRET, U, UT, SEC, E, F) self.assertEqual(rtn, vector['SERVER_OUTPUT'])
def mpin_server_2(server_secret, v, date, hid, htid, y, u, ut): """Check credentials.""" SERVER_SECRET = mpin.ffi.new("octet*") SERVER_SECRET_val = mpin.ffi.new("char [%s]" % len(server_secret), server_secret) SERVER_SECRET[0].val = SERVER_SECRET_val SERVER_SECRET[0].max = mpin.G2 SERVER_SECRET[0].len = len(server_secret) V = mpin.ffi.new("octet*") V_val = mpin.ffi.new("char [%s]" % len(v), v) V[0].val = V_val V[0].max = len(v) V[0].len = len(v) lenEF = 12 * mpin.PFS E = mpin.ffi.new("octet*") Eval = mpin.ffi.new("char []", lenEF) E[0].val = Eval E[0].max = lenEF E[0].len = lenEF F = mpin.ffi.new("octet*") Fval = mpin.ffi.new("char []", lenEF) F[0].val = Fval F[0].max = lenEF F[0].len = lenEF HID = mpin.ffi.new("octet*") HIDval = mpin.ffi.new("char [%s]" % len(hid), hid) HID[0].val = HIDval HID[0].max = len(hid) HID[0].len = len(hid) # H(T|H(ID)) HTID = mpin.ffi.new("octet*") HTIDval = mpin.ffi.new("char [%s]" % len(htid), htid) HTID[0].val = HTIDval HTID[0].max = len(htid) HTID[0].len = len(htid) # Client part Y = mpin.ffi.new("octet*") Yval = mpin.ffi.new("char [%s]" % len(y), y) Y[0].val = Yval Y[0].max = len(y) Y[0].len = len(y) U = mpin.ffi.new("octet*") Uval = mpin.ffi.new("char [%s]" % len(u), u) U[0].val = Uval U[0].max = len(u) U[0].len = len(u) UT = mpin.ffi.new("octet*") UTval = mpin.ffi.new("char [%s]" % len(ut), ut) UT[0].val = UTval UT[0].max = len(ut) UT[0].len = len(ut) return mpin.libmpin.MPIN_SERVER_2(date, HID, HTID, Y, SERVER_SECRET, U, UT, V, E, F), mpin.toHex(E), mpin.toHex(F)
def test_8(self): """test_8 Generation of secrets and time permits""" # random number generator RNG = ffi.new("csprng*") libmpin.CREATE_CSPRNG(RNG, self.RAW) # Generate Client master secret share for MIRACL and Customer rtn = libmpin.MPIN_RANDOM_GENERATE(RNG, MS1) self.assertEqual(rtn, 0) self.assertEqual(self.ms1Hex, toHex(MS1)) rtn = libmpin.MPIN_RANDOM_GENERATE(RNG, MS2) self.assertEqual(rtn, 0) self.assertEqual(self.ms2Hex, toHex(MS2)) # Generate server secret shares rtn = libmpin.MPIN_GET_SERVER_SECRET(MS1, SS1) self.assertEqual(rtn, 0) self.assertEqual(self.ss1Hex, toHex(SS1)) rtn = libmpin.MPIN_GET_SERVER_SECRET(MS2, SS2) self.assertEqual(rtn, 0) self.assertEqual(self.ss2Hex, toHex(SS2)) # Combine server secret shares rtn = libmpin.MPIN_RECOMBINE_G2(SS1, SS2, SERVER_SECRET) self.assertEqual(rtn, 0) self.assertEqual(self.serverSecretHex, toHex(SERVER_SECRET)) # Generate client secret shares rtn = libmpin.MPIN_GET_CLIENT_SECRET(MS1, self.HASH_MPIN_ID, CS1) self.assertEqual(rtn, 0) self.assertEqual(self.cs1Hex, toHex(CS1)) rtn = libmpin.MPIN_GET_CLIENT_SECRET(MS2, self.HASH_MPIN_ID, CS2) self.assertEqual(rtn, 0) self.assertEqual(self.cs2Hex, toHex(CS2)) # Combine client secret shares : TOKEN is the full client secret rtn = libmpin.MPIN_RECOMBINE_G1(CS1, CS2, TOKEN) self.assertEqual(rtn, 0) self.assertEqual(self.clientSecretHex, toHex(TOKEN)) # Generate Time Permit shares rtn = libmpin.MPIN_GET_CLIENT_PERMIT(self.date, MS1, self.HASH_MPIN_ID, TP1) self.assertEqual(rtn, 0) self.assertEqual(self.tp1Hex, toHex(TP1)) rtn = libmpin.MPIN_GET_CLIENT_PERMIT(self.date, MS2, self.HASH_MPIN_ID, TP2) self.assertEqual(rtn, 0) self.assertEqual(self.tp2Hex, toHex(TP2)) # Combine Time Permit shares rtn = libmpin.MPIN_RECOMBINE_G1(TP1, TP2, TIME_PERMIT) self.assertEqual(rtn, 0) self.assertEqual(self.timePermitHex, toHex(TIME_PERMIT)) # Client extracts PIN from secret to create Token PIN = 1234 rtn = libmpin.MPIN_EXTRACT_PIN(self.MPIN_ID, PIN, TOKEN) self.assertEqual(rtn, 0) self.assertEqual(self.tokenHex, toHex(TOKEN))