-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathfnf.py
More file actions
134 lines (115 loc) · 3.49 KB
/
fnf.py
File metadata and controls
134 lines (115 loc) · 3.49 KB
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/usr/bin/python3
from Crypto.Cipher import AES
import getopt
import sys
import os
class AESCipher:
def __init__(self, key, iv):
self.key = key
self.iv = iv
def encrypt(self, raw):
"""
Returns encrypted block
"""
cipher = AES.new(self.key, AES.MODE_ECB)
encrypted = cipher.encrypt(raw)
return encrypted
def decrypt(self, enc):
"""
Requires encrypted block, returns decrypted block
"""
cipher = AES.new(self.key, AES.MODE_ECB)
decrypted = cipher.decrypt(enc)
return decrypted
#key = b'abcdefghijklmnop'
key_hex = os.environ.get("KEY")
if key_hex is None:
print("Error: FESTIVAL_MIDI_KEY environment variable not set")
sys.exit(1)
key = bytearray.fromhex(key_hex)
iv = bytearray.fromhex("00000000000000000000000000000000") # null nonce because that's just what they do when they ECB
arglist = sys.argv[1:]
options = "dev"
long_options = ["decrypt","encrypt","verbose"]
cryptor = False
verbose = False
try:
opts, args= getopt.getopt(arglist,options,long_options)
for curArg,curVal in opts:
if curArg in ("-d","--decrypt"):
if cryptor == True:
print("Cannot do both encryption and decryption simultaneously")
quit()
encrypt = False
cryptor = True
elif curArg in ("-e","--encrypt"):
if cryptor == True:
print("Cannot do both encryption and decryption simultaneously")
quit()
encrypt = True
cryptor = True
elif curArg in ("-v","--verbose"):
verbose = True
except getopt.error as err:
print(err)
quit()
if (len(args) == 0) | (len(opts) == 0):
print(os.path.basename(sys.argv[0]), "v1.0\n")
print("Usage: [-d/-e] [-v] <file>\n")
print("-d / --decrypt: decrypt FNF .dat to .mid")
print("-e / --encrypt: encrypt .mid to FNF .dat")
print("-v / --verbose: verbose output")
print("<file>: input file to encrypt or decrypt")
if cryptor == False:
print("Must use one of either -e/--encrypt or -d/--decrypt")
quit()
infile = args[0]
infilename, infileext = os.path.splitext(infile)
if encrypt:
outfile = infilename + ".dat"
else:
outfile = infilename + ".mid"
try:
encfile = open(infile, "rb")
except FileNotFoundError as exc:
print(infile + ": file not found")
quit()
decfile = open(outfile, "wb")
if verbose:
print("AES key is",key.hex())
if encrypt:
print("Encrypting",os.path.basename(infile),"to",os.path.basename(outfile))
else:
print("Decrypting",os.path.basename(infile),"to",os.path.basename(outfile))
c = AESCipher(key, iv)
count=0
while True:
block = encfile.read(16)
if block:
count += 1
elif not block:
break
if len(block) < 16:
blockpad = 16 - len(block)
print("Final block is",len(block),"bytes, adding",blockpad,"padding bytes")
tempblock = bytearray(16)
for b in range(0,len(block)):
tempblock[b] = block[b]
block = bytes(tempblock)
if encrypt:
ptxt = c.encrypt(block)
if verbose:
print("Block",count,": DEC:",block.hex(),"ENC:",ptxt.hex())
else:
ptxt = c.decrypt(block)
if verbose:
print("Block",count,": ENC:",block.hex(),"DEC:",ptxt.hex())
decfile.write(ptxt)
if encrypt:
print("Encrypted",count,"blocks")
if not encrypt:
print("Decrypted",count,"blocks")
print("Closing files...")
encfile.close()
decfile.close()
print("Done!")