-
Notifications
You must be signed in to change notification settings - Fork 39
/
opc_calc.py
65 lines (52 loc) · 1.43 KB
/
opc_calc.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#!/usr/bin/env python
"""
Simple script to calculate OPC from Ki and OP.
3GPP TS 35.206 was used to code this script.
"""
__author__ = "mgp25"
__github__ = "https://github.com/mgp25"
from Crypto.Cipher import AES
from Crypto.Util.strxor import strxor
import sys, getopt, binascii
def main(argv):
try:
opts, args = getopt.getopt(argv,"k:o:h",["ki=","op=", 'help'])
except getopt.GetoptError:
print_usage()
sys.exit(2)
ki = None
op = None
for opt, arg in opts:
if opt in ('-h', '--help'):
print_usage()
sys.exit()
elif opt in ("-k", "--ki"):
ki = arg
elif opt in ("-o", "--op"):
op = arg
else:
print_usage()
sys.exit()
if ki is not None and op is not None:
print('\nOPc value: '+derive_milenage_opc(ki, op).decode('utf-8'))
else:
print_usage()
def derive_milenage_opc(ki_hex, op_hex):
"""
Run the milenage algorithm to calculate OPC from Ki and OP.
Following 3GPP TS 35.206
"""
# We pass in hex string and now need to work on bytes
aes = AES.new(h2b(ki_hex), AES.MODE_CBC, h2b('00000000000000000000000000000000'))
opc_bytes = aes.encrypt(h2b(op_hex))
return b2h(strxor(opc_bytes, h2b(op_hex)))
def h2b(s):
return bytes(bytearray.fromhex(s))
def b2h(s):
return binascii.hexlify(s)
def print_usage():
print('Usage:')
print(' opc_calc.py -k <Ki> -o <OP>')
print(' opc_calc.py --ki <Ki> --op <OP>')
if __name__ == "__main__":
main(sys.argv[1:])