__all__ = [ "hdr_make", "hdr_read", "hdr_fmt", "hdr_fmt_pretty"
+ , "scrypt_hashfile"
, "PDTCRYPT_HDR_SIZE", "AES_GCM_IV_CNT_DATA"
, "AES_GCM_IV_CNT_INFOFILE", "AES_GCM_IV_CNT_INDEX"
]
return partial (fn, params)
+###############################################################################
+## SCRYPT hashing
+###############################################################################
+
+def scrypt_hashsource (pw, ins):
+ """
+ Calculate the SCRYPT hash from the password and the information contained
+ in the first header found in ``ins``.
+
+ This does not validate whether the first object is encrypted correctly.
+ """
+ hdr = None
+ try:
+ hdr = hdr_read_stream (ins)
+ except EndOfFile as exn:
+ noise ("PDT: malformed input: end of file reading first object header")
+ noise ("PDT:")
+ return 1
+
+ nacl = hdr ["nacl"]
+ pver = hdr ["paramversion"]
+ if PDTCRYPT_VERBOSE is True:
+ noise ("PDT: salt of first object : %s" % binascii.hexlify (nacl))
+ noise ("PDT: parameter version of archive : %d" % pver)
+
+ try:
+ defs = ENCRYPTION_PARAMETERS.get(pver, None)
+ kdfname, params = defs ["kdf"]
+ if kdfname != "scrypt":
+ noise ("PDT: input is not an SCRYPT archive")
+ noise ("")
+ return 1
+ kdf = kdf_by_version (None, defs)
+ except ValueError as exn:
+ noise ("PDT: object has unknown parameter version %d" % pver)
+
+ hsh, _void = kdf (pw, nacl)
+
+ return hsh, nacl, params
+
+
+def scrypt_hashfile (pw, fname):
+ with deptdcrypt_mk_stream (PDTCRYPT_SOURCE, fname or "-") as ins:
+ hsh, _void, _void = scrypt_hashsource (pw, ins)
+ return hsh
+
+
+###############################################################################
+## AES-GCM context
+###############################################################################
+
class Crypto (object):
"""
Encryption context to remain alive throughout an entire tarfile pass.
def mode_scrypt (pw, ins):
- hdr = None
- try:
- hdr = hdr_read_stream (ins)
- except EndOfFile as exn:
- noise ("PDT: malformed input: end of file reading first object header")
- noise ("PDT:")
- return 1
- finally:
- ins.close ()
-
- nacl = hdr ["nacl"]
- pver = hdr ["paramversion"]
- if PDTCRYPT_VERBOSE is True:
- noise ("PDT: salt of first object : %s" % binascii.hexlify (nacl))
- noise ("PDT: parameter version of archive : %d" % pver)
-
- try:
- defs = ENCRYPTION_PARAMETERS.get(pver, None)
- kdfname, params = defs ["kdf"]
- if kdfname != "scrypt":
- noise ("PDT: input is not an SCRYPT archive")
- noise ("")
- return 1
- kdf = kdf_by_version (None, defs)
- except ValueError as exn:
- noise ("PDT: object has unknown parameter version %d" % pver)
-
- hsh, _void = kdf (pw, nacl)
+ hsh, nacl, params = scrypt_hashsource (pw, ins)
import json
out = json.dumps ({ "salt" : str (binascii.hexlify (nacl))
else:
raise Unreachable
- if pw is not None:
- pw = pw.encode ()
- else:
+ if pw is None:
if subcommand == PDTCRYPT_SUB_SCRYPT:
noise ("ERROR: scrypt hash mode requested but no password given")
noise ("")
raise Unreachable
# default to stdout
- ins = deptdcrypt_mk_stream (PDTCRYPT_SOURCE, insspec or "-")
+ ins = deptdcrypt_mk_stream (PDTCRYPT_SOURCE, insspec or "-")
if subcommand == PDTCRYPT_SUB_SCRYPT:
- return True, partial (mode_scrypt, pw, ins)
+ return True, partial (mode_scrypt, pw.encode (), ins)
if mode & PDTCRYPT_SPLIT: # destination must be directory
if outsspec is None or outsspec == "-":