#* #* GRUB -- GRand Unified Bootloader #* Copyright (C) 2009 Free Software Foundation, Inc. #* #* GRUB is free software: you can redistribute it and/or modify #* it under the terms of the GNU General Public License as published by #* the Free Software Foundation, either version 3 of the License, or #* (at your option) any later version. #* #* GRUB is distributed in the hope that it will be useful, #* but WITHOUT ANY WARRANTY; without even the implied warranty of #* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #* GNU General Public License for more details. #* #* You should have received a copy of the GNU General Public License #* along with GRUB. If not, see . #* import re import sys import os import datetime if len (sys.argv) < 3: print ("Usage: %s SOURCE DESTINATION" % sys.argv[0]) exit (0) indir = sys.argv[1] outdir = sys.argv[2] basedir = os.path.join (outdir, "lib/libgcrypt-grub") try: os.makedirs (basedir) except: print ("WARNING: %s already exists" % basedir) cipher_dir_in = os.path.join (indir, "cipher") cipher_dir_out = os.path.join (basedir, "cipher") try: os.makedirs (cipher_dir_out) except: print ("WARNING: %s already exists" % cipher_dir_out) cipher_files = os.listdir (cipher_dir_in) conf = open (os.path.join (outdir, "conf", "gcry.rmk"), "w") conf.write ("# -*- makefile -*-\n\n") chlog = "" # Strictly speaking CRC32/CRC24 work on bytes so this value should be 1 # But libgcrypt uses 64. Let's keep the value for compatibility. Since # noone uses CRC24/CRC32 for HMAC this is no problem mdblocksizes = {"_gcry_digest_spec_crc32" : 64, "_gcry_digest_spec_crc32_rfc1510" : 64, "_gcry_digest_spec_crc24_rfc2440" : 64, "_gcry_digest_spec_md4" : 64, "_gcry_digest_spec_md5" : 64, "_gcry_digest_spec_rmd160" : 64, "_gcry_digest_spec_sha1" : 64, "_gcry_digest_spec_sha224" : 64, "_gcry_digest_spec_sha256" : 64, "_gcry_digest_spec_sha384" : 128, "_gcry_digest_spec_sha512" : 128, "_gcry_digest_spec_tiger" : 64, "_gcry_digest_spec_whirlpool" : 64} for cipher_file in cipher_files: infile = os.path.join (cipher_dir_in, cipher_file) outfile = os.path.join (cipher_dir_out, cipher_file) if cipher_file == "ChangeLog": continue chlognew = " * %s" % cipher_file nch = False if re.match (".*\.[ch]$", cipher_file): isc = re.match (".*\.c$", cipher_file) f = open (infile, "r") fw = open (outfile, "w") fw.write ("/* This file was automatically imported with \n") fw.write (" import_gcry.py. Please don't modify it */\n"); ciphernames = [] mdnames = [] hold = False skip = False skip2 = False ismd = False iscomma = False for line in f: if skip: if line[0] == "}": skip = False continue if skip2: if not re.search (" *};", line) is None: skip2 = False continue if ismd: if not re.search (" *};", line) is None: if not mdblocksizes.has_key (mdname): print ("ERROR: Unknown digest blocksize: %s\n" % mdname) exit (1) if not iscomma: fw.write (" ,\n") fw.write (" .blocksize = %s\n" % mdblocksizes [mdname]) ismd = False iscomma = not re.search (",$", line) is None if hold: hold = False # We're optimising for size. if not re.match ("(run_selftests|selftest|_gcry_aes_c.._..c|_gcry_[a-z0-9]*_hash_buffer)", line) is None: skip = True fname = re.match ("[a-zA-Z0-9_]*", line).group () chmsg = "(%s): Removed." % fname if nch: chlognew = "%s\n %s" % (chlognew, chmsg) else: chlognew = "%s %s" % (chlognew, chmsg) nch = True continue else: fw.write (holdline) m = re.match ("#include <.*>", line) if not m is None: chmsg = "Removed including of %s" % \ m.group () [len ("#include <"):len (m.group ()) - 1] if nch: chlognew = "%s\n %s" % (chlognew, chmsg) else: chlognew = "%s: %s" % (chlognew, chmsg) nch = True continue m = re.match ("gcry_cipher_spec_t", line) if isc and not m is None: ciphername = line [len ("gcry_cipher_spec_t"):].strip () ciphername = re.match("[a-zA-Z0-9_]*",ciphername).group () ciphernames.append (ciphername) m = re.match ("gcry_md_spec_t", line) if isc and not m is None: assert (not ismd) mdname = line [len ("gcry_md_spec_t"):].strip () mdname = re.match("[a-zA-Z0-9_]*",mdname).group () mdnames.append (mdname) ismd = True m = re.match ("static const char \*selftest.*;$", line) if not m is None: fname = line[len ("static const char \*"):] fname = re.match ("[a-zA-Z0-9_]*", fname).group () chmsg = "(%s): Removed declaration." % fname if nch: chlognew = "%s\n %s" % (chlognew, chmsg) else: chlognew = "%s %s" % (chlognew, chmsg) nch = True continue m = re.match ("(static const char( |)\*|static gpg_err_code_t|void)$", line) if not m is None: hold = True holdline = line continue m = re.match ("cipher_extra_spec_t", line) if isc and not m is None: skip2 = True fname = line[len ("cipher_extra_spec_t "):] fname = re.match ("[a-zA-Z0-9_]*", fname).group () chmsg = "(%s): Removed." % fname if nch: chlognew = "%s\n %s" % (chlognew, chmsg) else: chlognew = "%s %s" % (chlognew, chmsg) nch = True continue m = re.match ("md_extra_spec_t", line) if isc and not m is None: skip2 = True fname = line[len ("md_extra_spec_t "):] fname = re.match ("[a-zA-Z0-9_]*", fname).group () chmsg = "(%s): Removed." % fname if nch: chlognew = "%s\n %s" % (chlognew, chmsg) else: chlognew = "%s %s" % (chlognew, chmsg) nch = True continue fw.write (line) if len (ciphernames) > 0 or len (mdnames) > 0: modname = cipher_file [0:len(cipher_file) - 2] if re.match (".*-glue$", modname): modfiles = "libgcrypt-grub/cipher/%s libgcrypt-grub/cipher/%s" \ % (cipher_file, cipher_file.replace ("-glue.c", ".c")) modname = modname.replace ("-glue", "") else: modfiles = "libgcrypt-grub/cipher/%s" % cipher_file modname = "gcry_%s" % modname chmsg = "(GRUB_MOD_INIT(%s)): New function\n" % modname if nch: chlognew = "%s\n %s" % (chlognew, chmsg) else: chlognew = "%s%s" % (chlognew, chmsg) nch = True fw.write ("\n\nGRUB_MOD_INIT(%s)\n" % modname) fw.write ("{\n") for ciphername in ciphernames: chmsg = "Register cipher %s" % ciphername chlognew = "%s\n %s" % (chlognew, chmsg) fw.write (" grub_cipher_register (&%s);\n" % ciphername) for mdname in mdnames: chmsg = "Register digest %s" % mdname chlognew = "%s\n %s" % (chlognew, chmsg) fw.write (" grub_md_register (&%s);\n" % mdname) fw.write ("}") chmsg = "(GRUB_MOD_FINI(%s)): New function\n" % modname chlognew = "%s\n %s" % (chlognew, chmsg) fw.write ("\n\nGRUB_MOD_FINI(%s)\n" % modname) fw.write ("{\n") for ciphername in ciphernames: chmsg = "Unregister cipher %s" % ciphername chlognew = "%s\n %s" % (chlognew, chmsg) fw.write (" grub_cipher_unregister (&%s);\n" % ciphername) for mdname in mdnames: chmsg = "Unregister MD %s" % mdname chlognew = "%s\n %s" % (chlognew, chmsg) fw.write (" grub_md_unregister (&%s);\n" % mdname) fw.write ("}\n") conf.write ("pkglib_MODULES += %s.mod\n" % modname) conf.write ("%s_mod_SOURCES = %s\n" %\ (modname, modfiles)) conf.write ("%s_mod_CFLAGS = $(COMMON_CFLAGS) -Wno-missing-field-initializers -Wno-error\n" % modname) conf.write ("%s_mod_LDFLAGS = $(COMMON_LDFLAGS)\n\n" % modname) elif isc and cipher_file != "camellia.c": print ("WARNING: C file isn't a module: %s" % cipher_file) f.close () fw.close () if nch: chlog = "%s%s\n" % (chlog, chlognew) continue if re.match ("(Manifest|Makefile\.am)$", cipher_file): chlog = "%s%sRemoved\n" % (chlog, chlognew) continue # Autogenerated files. Not even worth mentionning in ChangeLog if re.match ("Makefile\.in$", cipher_file): chlog = "%s%sRemoved\n" % (chlog, chlognew) continue chlog = "%s%sSkipped unknown file\n" % (chlog, chlognew) print ("WARNING: unknown file %s" % cipher_file) outfile = os.path.join (cipher_dir_out, "types.h") fw=open (outfile, "w") fw.write ("#include \n") fw.write ("#include \n") chlog = "%s * types.h: New file.\n" % chlog fw.close () outfile = os.path.join (cipher_dir_out, "memory.h") fw=open (outfile, "w") fw.write ("#include \n") chlog = "%s * memory.h: New file.\n" % chlog fw.close () outfile = os.path.join (cipher_dir_out, "cipher.h") fw=open (outfile, "w") fw.write ("#include \n") fw.write ("#include \n") chlog = "%s * cipher.h: Likewise.\n" % chlog fw.close () outfile = os.path.join (cipher_dir_out, "g10lib.h") fw=open (outfile, "w") fw.write ("#include \n") chlog = "%s * g10lib.h: Likewise.\n" % chlog fw.close () infile = os.path.join (cipher_dir_in, "ChangeLog") outfile = os.path.join (cipher_dir_out, "ChangeLog") f=open (infile, "r") fw=open (outfile, "w") dt = datetime.date.today () fw.write ("%04d-%02d-%02d Automatic import tool\n" % \ (dt.year,dt.month, dt.day)) fw.write ("\n") fw.write (" Imported ciphers to GRUB\n") fw.write ("\n") fw.write (chlog) fw.write ("\n") for line in f: fw.write (line) f.close () fw.close ()