start payload encryption counter at 2
authorPhilipp Gesang <philipp.gesang@intra2net.com>
Thu, 23 Mar 2017 09:43:25 +0000 (10:43 +0100)
committerPhilipp Gesang <philipp.gesang@intra2net.com>
Thu, 23 Mar 2017 09:43:29 +0000 (10:43 +0100)
As per the spec, a file counter of 1 is reserved for the info
file.

deltatar/crypto.py
deltatar/tarfile.py

index 64e62f9..0330552 100755 (executable)
@@ -53,7 +53,8 @@ from cryptography.hazmat.backends import default_backend
 
 
 __all__ = [ "hdr_make", "hdr_read", "hdr_fmt", "hdr_fmt_pretty"
-          , "I2N_HDR_SIZE" ]
+          , "I2N_HDR_SIZE" , "AES_GCM_IV_CNT_DATA", "AES_GCM_IV_CNT_INFOFILE"
+          ]
 
 
 ###############################################################################
@@ -115,6 +116,9 @@ AES_GCM_IV_LEN   = 12
 AES_GCM_MAX_SIZE = (1 << 36) - (1 << 5) # 2^39 - 2^8 b ≅ 64 GB
 AES_GCM_FMT_TAG  = "<16s"
 
+AES_GCM_IV_CNT_INFOFILE = 1 # constant
+AES_GCM_IV_CNT_DATA     = AES_GCM_IV_CNT_INFOFILE + 1 # also for multivolume
+
 
 ###############################################################################
 ## header, trailer
@@ -319,11 +323,12 @@ class Crypto (object):
     state = STATE_DEAD
 
     def __init__ (self, *al, **akv):
-        self.cnt  = 1
         self.set_parameters (*al, **akv)
 
 
-    def set_parameters (self, password, paramversion, nacl=None, pfx=None):
+    def set_parameters (self, password, paramversion, nacl=None, pfx=None,
+                        counter=None):
+        self.cnt = counter or AES_GCM_IV_CNT_DATA
         if isinstance (password, bytes) is False: password = str.encode (password)
         self.password = password
         if paramversion is None and nacl is None:
@@ -335,7 +340,7 @@ class Crypto (object):
         if kdf is not None:
             self.key, self.nacl = kdf (password, nacl)
 
-        if pfx is not None:
+        if pfx is not None and isinstance (pfx, bytes) is True:
             self.pfx = pfx
         if self.pfx is None:
             self.pfx = os.urandom(8)
@@ -363,8 +368,9 @@ class Encrypt (Crypto):
     hdrdum = None
     ctsize = -1     # per object from .next() → .done()
 
-    def __init__ (self, password, paramversion, nacl=None):
-        super().__init__ (password, paramversion, nacl)
+    def __init__ (self, password, paramversion, nacl=None,
+                  counter=AES_GCM_IV_CNT_DATA):
+        super().__init__ (password, paramversion, nacl, counter=counter)
 
 
     def iv_make (self):
@@ -420,8 +426,8 @@ class Decrypt (Crypto):
     ctsize       = -1
     ptsize       = -1
 
-    def __init__ (self, password, paramversion=None, nacl=None):
-        super().__init__ (password, paramversion, nacl)
+    def __init__ (self, password, paramversion=None, nacl=None, counter=None):
+        super().__init__ (password, paramversion, nacl, counter=counter)
 
 
     def next (self, hdr):
index c48c8d6..ef50e1d 100644 (file)
@@ -448,7 +448,9 @@ class _Stream:
                                     ("encryption requested (v=%d) but no password given"
                                      % encver)
                         try:
-                            enc = crypto.Encrypt (password, I2N_XXX_ENCRYPTION_VERSION, nacl)
+                            enc = crypto.Encrypt (password,
+                                                  I2N_XXX_ENCRYPTION_VERSION, nacl,
+                                                  counter=crypto.AES_GCM_IV_CNT_DATA)
                         except ValueError as exn:
                             raise InvalidEncryptionError \
                                     ("ctor failed crypto.Encrypt(<PASSWORD>, “%s”, %r)"
@@ -515,7 +517,9 @@ class _Stream:
                                 ("encryption requested (v=%d) but no password given"
                                  % encver)
                     try:
-                        enc = crypto.Encrypt (password, I2N_XXX_ENCRYPTION_VERSION, nacl)
+                        enc = crypto.Encrypt (password,
+                                              I2N_XXX_ENCRYPTION_VERSION, nacl,
+                                              counter=crypto.AES_GCM_IV_CNT_DATA)
                     except ValueError as exn:
                         raise InvalidEncryptionError \
                                 ("ctor failed crypto.Encrypt(<PASSWORD>, “%s”, %r)"