-
Type: New Feature
-
Status: Resolved
-
Priority: Major
-
Resolution: Fixed
-
Affects Version/s: None
-
Fix Version/s: ODF 1.5
-
Component/s: Packaging, Part 2 (Packages) [1.2: 3], Security
-
Labels:None
-
Proposal:Hide
The problems can only be solved with an incompatible change to the standard.
To preserve compatibility with existing ODF 1.4 or older documents, the existing elements and attributes should be preserved, and new features specified for new documents in ODF 1.5.
Solutions:
1. produce an unencrypted ODF package, and store it as a single encrypted file entry in a wrapper ODF package
2. while we are making incompatible changes, use Argon2 instead of PBKDF2 to have a memory-hard KDF
3. use an AEAD like AES-GCM for authenticated encryption
4. with authenticated encryption, SHA/1k checksums are obsolete, don't produce themProposal:
1.3 Normative References
Add:
[RFC9106] A. Biryukov, D. Dinu, D. Khovratovich, S. Josefsson, Argon2 Memory-Hard Function for Password Hashing and Proof-of-Work Applications, https://www.ietf.org/rfc/rfc9106.txt, IETF, 2021
Replace [xmlenc-core] with (needed to reference AES-GCM):
[xmlenc-core] Donald Eastlake, Joseph Reagle, Frederick Hirsch, Thomas Roessler, XML Encryption Syntax and Processing Version 1.1, http://www.w3.org/TR/2013/REC-xmlenc-core1-20130411/, W3C, 2013
3.4.1 General
Add:
Fundamentally, there are 2 ways to encrypt an OpenDocument package. In every version of OpenDocument, it has been possible to encrypt every file entry in the package separately; some or all files within the package may be encrypted. With OpenDocument 1.5, it is now possible to encrypt the whole package at once, which is considered a better approach as it is both more efficient and more secure. This method is specified in section 3.4.4.Current best practice is to use full package encryption with SHA256 start key derivation, Argon2id key derivation function and AES-GCM authenticated encryption algorithm.
Remove:
OpenDocument packages may be encrypted by encrypting some or all files within the package.3.4.2 Encrypting a File Entry (this is the old 3.4.1 General, renamed)
This contains the text of the old 3.4.1 General, except the first sentence (removed, as noted above).
Replace "* The files are encrypted ..." with "* The file is encrypted ..."
3.4.3 Encryption Process
Replace "* The files are encrypted ..." with "* The file is encrypted ..."
Add new section: 3.4.4 Full Package Encryption
An OpenDocument package can be produced in the usual way (without encryption), and then wrapped in an outer OpenDocument package in an encrypted file entry with the special name "encrypted-package".
This is called full package encryption.The encrypted wrapper package should contain only "mimetype", "encrypted-package", and files in "META-INF/".
3.9 Interactions Between Encryption and Digital Signatures
(sort of obvious, but perhaps better add it explicitly: )
"If the encryption of the files is done first, the digital signatures files shall not be encrypted."
Append: "and in the case of full package encryption shall be placed in the outer wrapper package.""If the files in the package are encrypted after applying the digital signatures, the digital signature files shall be encrypted."
Append: "and in the case of full package encryption shall be placed in the inner package."4.16.1 manifest:algorithm-name
The new algorithm AES-GCM https://www.w3.org/TR/xmlenc-core1/#sec-AES-GCM is already allowed by the first bullet item, so doesn't need a new item.
Replace paragraph "Package producers that support encryption shall support the value Blowfish CFB.... " with:
Package producers that support encryption should support the value http://www.w3.org/2009/xmlenc11#aes256-gcm. Package consumers that support encryption should support the values http://www.w3.org/2009/xmlenc11#aes256-gcm, http://www.w3.org/2001/04/xmlenc#aes256-cbc, Blowfish CFB and urn:oasis:names:tc:opendocument:xmlns:manifest:1.0#blowfish.
4.16.2 manifest:checksum
The proposal is to make this attribute optional.
Add: (deprecated)
Add:
The manifest:checksum attribute should not be produced if the algorithm referenced by manifest:algorithm-name provides authenticated encryption, e.g., AES-GCM.4.16.3 manifest:checksum-type
The proposal is to make this attribute optional.
Add: (deprecated)
Add:
The manifest:checksum-type attribute should not be produced if the algorithm referenced by manifest:algorithm-name provides authenticated encryption, e.g., AES-GCM.4.16.5 manifest:initialisation-vector
Add:
Producers should generate fresh random initialization vector values every time they create a package, instead of reusing a salt value consumed from an existing package.4.16.6 manifest:start-key-generation-name
(As discussed in OFFICE-3708 ODF uses a wrong URL for SHA256 so if we make an incompatible change we should use the opportunity to fix it.)
Replace "Package producers that support encryption should use the http://www.w3.org/2000/09/xmldsig#sha256 algorithm."
with "Package producers that support encryption should use the http://www.w3.org/2001/04/xmlenc#sha256 algorithm.""Package consumers that support encryption shall support the values ..."
Add at the end: "and http://www.w3.org/2001/04/xmlenc#sha256"4.16.7 manifest:key-size
Remove "For a <manifest:start-key-generation> element, the default value for this attribute is 20."
Replace in the first Note "The value used will need to be compatible with the result obtain" -> "The value used with the <manifest:start-key-generation> element will need to be one obtainable"
Remove "For a <manifest:key-derivation> element, the default value for this attribute is 16."
Replace in the second Note "The value used" -> "The value used with the <manifest:key-derivation> element"(As the Note says, the default is dependent on the used encryption algorithm, so AES256 would have a default of 32. The attribute only makes sense in case an encryption algorithm doesn't have a fixed key size, or a start-key-algorithm doesn't have a fixed output size.)
4.16.8 manifest:iteration-count
Add:
Note: Current recommendation for PBKDF2 is to use 600000 iterations.4.16.9 manifest:key-derivation-name
Add bullet item:
- urn:oasis:names:tc:opendocument:xmlns:manifest:1.5#argon2id : The Argon2id algorithm as specified by [RFC9106]. From section 3.1. Argon2 Inputs and Outputs, the parameters "K" and "X" are not used. If this value is used, the attributes manifest:argon2-iterations, manifest:argon2-memory, and manifest:argon2-lanes shall be present to provide the "t", "m", and "p" parameters.
4.16.12 manifest:salt
Add:
Producers should generate fresh random salt values every time they create a package, instead of reusing a salt value consumed from an existing package.Add new section: 4.16.x manifest:argon2-iterations
Specifies parameter "t" in [RFC9106], 3.1. Argon2 Inputs and Outputs.
Add new section: 4.16.x manifest:argon2-memory
Specifies parameter "m" in [RFC9106], 3.1. Argon2 Inputs and Outputs.
Add new section: 4.16.x manifest:argon2-lanes
Specifies parameter "p" in [RFC9106], 3.1. Argon2 Inputs and Outputs.
ShowThe problems can only be solved with an incompatible change to the standard. To preserve compatibility with existing ODF 1.4 or older documents, the existing elements and attributes should be preserved, and new features specified for new documents in ODF 1.5. Solutions: 1. produce an unencrypted ODF package, and store it as a single encrypted file entry in a wrapper ODF package 2. while we are making incompatible changes, use Argon2 instead of PBKDF2 to have a memory-hard KDF 3. use an AEAD like AES-GCM for authenticated encryption 4. with authenticated encryption, SHA/1k checksums are obsolete, don't produce them Proposal: 1.3 Normative References Add: [RFC9106] A. Biryukov, D. Dinu, D. Khovratovich, S. Josefsson, Argon2 Memory-Hard Function for Password Hashing and Proof-of-Work Applications, https://www.ietf.org/rfc/rfc9106.txt , IETF, 2021 Replace [xmlenc-core] with (needed to reference AES-GCM): [xmlenc-core] Donald Eastlake, Joseph Reagle, Frederick Hirsch, Thomas Roessler, XML Encryption Syntax and Processing Version 1.1, http://www.w3.org/TR/2013/REC-xmlenc-core1-20130411/ , W3C, 2013 3.4.1 General Add: Fundamentally, there are 2 ways to encrypt an OpenDocument package. In every version of OpenDocument, it has been possible to encrypt every file entry in the package separately; some or all files within the package may be encrypted. With OpenDocument 1.5, it is now possible to encrypt the whole package at once, which is considered a better approach as it is both more efficient and more secure. This method is specified in section 3.4.4. Current best practice is to use full package encryption with SHA256 start key derivation, Argon2id key derivation function and AES-GCM authenticated encryption algorithm. Remove: OpenDocument packages may be encrypted by encrypting some or all files within the package. 3.4.2 Encrypting a File Entry (this is the old 3.4.1 General, renamed) This contains the text of the old 3.4.1 General, except the first sentence (removed, as noted above). Replace "* The files are encrypted ..." with "* The file is encrypted ..." 3.4.3 Encryption Process Replace "* The files are encrypted ..." with "* The file is encrypted ..." Add new section: 3.4.4 Full Package Encryption An OpenDocument package can be produced in the usual way (without encryption), and then wrapped in an outer OpenDocument package in an encrypted file entry with the special name "encrypted-package". This is called full package encryption. The encrypted wrapper package should contain only "mimetype", "encrypted-package", and files in "META-INF/". 3.9 Interactions Between Encryption and Digital Signatures (sort of obvious, but perhaps better add it explicitly: ) "If the encryption of the files is done first, the digital signatures files shall not be encrypted." Append: "and in the case of full package encryption shall be placed in the outer wrapper package." "If the files in the package are encrypted after applying the digital signatures, the digital signature files shall be encrypted." Append: "and in the case of full package encryption shall be placed in the inner package." 4.16.1 manifest:algorithm-name The new algorithm AES-GCM https://www.w3.org/TR/xmlenc-core1/#sec-AES-GCM is already allowed by the first bullet item, so doesn't need a new item. Replace paragraph "Package producers that support encryption shall support the value Blowfish CFB.... " with: Package producers that support encryption should support the value http://www.w3.org/2009/xmlenc11#aes256-gcm . Package consumers that support encryption should support the values http://www.w3.org/2009/xmlenc11#aes256-gcm , http://www.w3.org/2001/04/xmlenc#aes256-cbc , Blowfish CFB and urn:oasis:names:tc:opendocument:xmlns:manifest:1.0#blowfish. 4.16.2 manifest:checksum The proposal is to make this attribute optional. Add: (deprecated) Add: The manifest:checksum attribute should not be produced if the algorithm referenced by manifest:algorithm-name provides authenticated encryption, e.g., AES-GCM. 4.16.3 manifest:checksum-type The proposal is to make this attribute optional. Add: (deprecated) Add: The manifest:checksum-type attribute should not be produced if the algorithm referenced by manifest:algorithm-name provides authenticated encryption, e.g., AES-GCM. 4.16.5 manifest:initialisation-vector Add: Producers should generate fresh random initialization vector values every time they create a package, instead of reusing a salt value consumed from an existing package. 4.16.6 manifest:start-key-generation-name (As discussed in OFFICE-3708 ODF uses a wrong URL for SHA256 so if we make an incompatible change we should use the opportunity to fix it.) Replace "Package producers that support encryption should use the http://www.w3.org/2000/09/xmldsig#sha256 algorithm." with "Package producers that support encryption should use the http://www.w3.org/2001/04/xmlenc#sha256 algorithm." "Package consumers that support encryption shall support the values ..." Add at the end: "and http://www.w3.org/2001/04/xmlenc#sha256 " 4.16.7 manifest:key-size Remove "For a <manifest:start-key-generation> element, the default value for this attribute is 20." Replace in the first Note "The value used will need to be compatible with the result obtain" -> "The value used with the <manifest:start-key-generation> element will need to be one obtainable" Remove "For a <manifest:key-derivation> element, the default value for this attribute is 16." Replace in the second Note "The value used" -> "The value used with the <manifest:key-derivation> element" (As the Note says, the default is dependent on the used encryption algorithm, so AES256 would have a default of 32. The attribute only makes sense in case an encryption algorithm doesn't have a fixed key size, or a start-key-algorithm doesn't have a fixed output size.) 4.16.8 manifest:iteration-count Add: Note: Current recommendation for PBKDF2 is to use 600000 iterations. 4.16.9 manifest:key-derivation-name Add bullet item: urn:oasis:names:tc:opendocument:xmlns:manifest:1.5#argon2id : The Argon2id algorithm as specified by [RFC9106] . From section 3.1. Argon2 Inputs and Outputs, the parameters "K" and "X" are not used. If this value is used, the attributes manifest:argon2-iterations, manifest:argon2-memory, and manifest:argon2-lanes shall be present to provide the "t", "m", and "p" parameters. 4.16.12 manifest:salt Add: Producers should generate fresh random salt values every time they create a package, instead of reusing a salt value consumed from an existing package. Add new section: 4.16.x manifest:argon2-iterations Specifies parameter "t" in [RFC9106] , 3.1. Argon2 Inputs and Outputs. Add new section: 4.16.x manifest:argon2-memory Specifies parameter "m" in [RFC9106] , 3.1. Argon2 Inputs and Outputs. Add new section: 4.16.x manifest:argon2-lanes Specifies parameter "p" in [RFC9106] , 3.1. Argon2 Inputs and Outputs. -
Resolution:Hide
1.3 Normative References
Add:
[RFC9106] A. Biryukov, D. Dinu, D. Khovratovich, S. Josefsson, Argon2 Memory-Hard Function for Password Hashing and Proof-of-Work Applications, https://www.ietf.org/rfc/rfc9106.txt, IETF, 2021Update:
[xmlenc-core] Donald Eastlake, Joseph Reagle, Frederick Hirsch, Thomas Roessler, XML Encryption Syntax and Processing, https://www.w3.org/TR/2013/REC-xmlenc-core-20130411/, W3C, 2013.3.4 Encryption
Add new 3.4.1:
3.4.1 General
Fundamentally, there are 2 ways to encrypt an OpenDocument package. In every version of OpenDocument, it has been possible to encrypt every file entry in the package separately; some or all files within the package may be encrypted. With OpenDocument 1.5, it is now possible to encrypt the whole package at once, which is considered a better approach as it is both more efficient and more secure. This method is specified in section 3.4.4.
Current best practice is to use full package encryption with SHA256 start key derivation, Argon2id key derivation function and AES-GCM authenticated encryption algorithm.
Renumber and update existing 3.4.1 and 3.4.2:
3.4.2 Encrypting a File Entry
The encryption process takes place in the following stages:
- A single start key is generated and used for all of the keys that will be derived.
- The derived key is generated based on the start key.
- The file is encrypted based on the derived key and the encryption algorithm.
The information regarding the algorithms that were used to encrypt a file and required parameters are contained in the manifest. The manifest shall not be encrypted.
Each file entry that is encrypted shall be compressed with the “deflate” algorithm before being encrypted. Encrypted file entries shall be flagged as 'STORED' rather than 'DEFLATED' in the Zip file's central directory. The size of the encrypted file should replace the real size value in the file entry's central directory records, its local file header and the data descriptor, if any. The original uncompressed, unencrypted size shall be contained in the manifest:size 4.16.13 attribute of the <manifest:file-entry> 4.3 element for the file entry.
The encrypted form can be of greater size than the DEFLATED file used as the plaintext.
Note: The encrypted form may be of greater size because of padding of plaintext, inclusion of additional information, and other characteristics of the encryption technique).
The encryption method shall be such that the exact size and value of the plaintext DEFLATED file is recovered by the corresponding decryption process.
3.4.3 Encryption Process
The three stages of the encryption process proceed as follows, using the legacy algorithms to illustrate each stage:
1. The start key is generated: The byte sequence representing the password in UTF-8 is used to generate a 20-byte SHA1 digest (see [RFC3174]).
2. A separate derived key is generated from the start key: The PBKDF2 algorithm based on the HMAC-SHA-1 function (see [RFC2898]) is used for the key derivation. A 16-byte salt is generated by a random generator. The salt is used together with the start key to derive a unique 128-bit key. The default iteration count for the algorithm is 1024.
3. The file is encrypted: The random number generator is used to generate the 8-byte initialization vector for the algorithm. The derived key is used together with the initialization vector to encrypt the file using the Blowfish algorithm in 8-bit cipher feedback (8-bit CFB) mode (see [Schneier]).
Add new 3.4.4:
3.4.4 Full Package Encryption
An OpenDocument package can be produced in the usual way (without encryption), and then wrapped in an outer OpenDocument package in an encrypted file entry with the special name "encrypted-package". This is called full package encryption.
The encrypted wrapper package should contain only "mimetype", "encrypted-package", and files in "META-INF/".
3.9 Interactions Between Encryption and Digital Signatures
Update 3.9:
An OpenDocument Package Producer that both encrypts files in the package and applies digital signatures to files in the package should either first encrypt (per section 3.4) and then apply the digital signatures (per section 5) or first apply the digital signatures and then encrypt.
If the encryption of the files is done first, the digital signatures files shall not be encrypted and, in the case of full package encryption, shall be placed in the outer wrapper package.
If the files in the package are encrypted after applying the digital signatures, the digital signature files shall be encrypted and, in the case of full package encryption, shall be placed in the inner package.
See also section 5.2.
Note: It is current practice to first encrypt and then apply the digital signatures.
4.16 Manifest Attributes
In 4.16.1 replace the fourth bullet point with the following paragraph (not bulleted):
Package producers that support encryption should support the value http://www.w3.org/2009/xmlenc11#aes256-gcm. Package consumers that support encryption should support the values http://www.w3.org/2009/xmlenc11#aes256-gcm, http://www.w3.org/2001/04/xmlenc#aes256-cbc, Blowfish CFB and urn:oasis:names:tc:opendocument:xmlns:manifest:1.0#blowfish.
Update 4.16.2, 4.16.3, 4.16.5 - 4.16.9, 4.16.12:
4.16.2 manifest:checksum (deprecated)
The manifest:checksum attribute specifies a digest in base64Binary encoding that can be used to detect password correctness as specified by a manifest:checksum-type attribute 4.16.3.
The manifest:checksum attribute should not be produced if the algorithm referenced by manifest:algorithm-name provides authenticated encryption, e.g., AES-GCM.
...
4.16.3 manifest:checksum-type (deprecated)
The manifest:checksum-type attribute specifies the name of a digest algorithm that can be used to check password correctness. The digest is build from the compressed unencrypted file.
The manifest:checksum-type attribute should not be produced if the algorithm referenced by manifest:algorithm-name provides authenticated encryption, e.g. AES-GCM.
The defined values for the manifest:checksum-type attribute are:
...
4.16.5 manifest:initialisation-vector
The manifest:initialisation-vector attribute value provides the byte-sequence for the initialization vector used by the encryption algorithm when delivery of a required initialization vector is not specified as part of the encryption algorithm definition. The initialization vector is a base64Binary encoded sequence. The format and length of an initialization vector, in bytes, shall be as required by its encryption algorithm specification.
Producers should generate fresh random initialization vector values every time they create a package, instead of reusing a salt value consumed from an existing package.
...
4.16.6 manifest:start-key-generation-name
...
Package producers that support encryption should use the http://www.w3.org/2001/04/xmldsig#sha256 algorithm. Package consumers that support encryption shall support the values SHA1, http://www.w3.org/2000/09/xmldsig#sha1, http://www.w3.org/2000/09/xmldsig#sha256 and http://www.w3.org/2001/04/xmldsig#sha256.
...
4.16.7 manifest:key-size
The manifest:key-size attribute specifies the length in octets of a key delivered by a key-developing algorithm.
Note: The value used with the <manifest:start-key-generation> element will need to be one obtainable from the start-key-generation algorithm and the input requirements of the key derivation algorithm.
Note: The value used with the <manifest:key-derivation> element will need to be one obtainable from the key-derivation algorithm and acceptable for the encryption algorithm being used.
...
4.16.8 manifest:iteration-count
The manifest:iteration-count attribute specifies the number of iterations used by the key derivation algorithm to derive a key.
Note: Current recommendation for PBKDF2 is to use 600000 iterations.
...
4.16.9 manifest:key-derivation-name
The manifest:key-derivation-name attribute specifies the password-based key-derivation algorithm used to derive a cryptographic key for use in encryption and decryption of the file.
The defined values for the manifest:key-derivation-name attribute are:
...
- urn:oasis:names:tc:opendocument:xmlns:manifest:1.5#argon2id : The Argon2id algorithm as specified by [RFC9106]. From section 3.1 Argon2 Inputs and Outputs, the parameters "K" and "X" are not used. If this value is used, the attributes manifest:argon2-iterations, manifest:argon2-memory, and manifest:argon2-lanes shall be present to provide the "t", "m", and "p" parameters
...
4.16.12 manifest:salt
The manifest:salt attribute carries the value of a cryptographically-random binary value designed to mitigate certain cryptographic attacks on the password. There is no maximum length to the salt. See for further considerations in the use of salts with key-derivation and other cryptographic functions. The salt is encoded in the attribute value as a base64Binary value.
Producers should generate fresh random salt values every time they create a package, instead of reusing a salt value consumed from an existing package.
...
Add new sections 4.16.15, 4.16.16 and 4.16.17:
4.16.15 manifest:argon2-iterations
Specifies parameter "t" in [RFC9106], §3.1 Argon2 Inputs and Outputs.
4.16.16 manifest:argon2-memory
Specifies parameter "m" in [RFC9106], §3.1 Argon2 Inputs and Outputs.
4.16.17 manifest:argon2-lanes
Specifies parameter "p" in [RFC9106], §3.1 Argon2 Inputs and Outputs.
Show1.3 Normative References Add : [RFC9106] A. Biryukov, D. Dinu, D. Khovratovich, S. Josefsson, Argon2 Memory-Hard Function for Password Hashing and Proof-of-Work Applications, https://www.ietf.org/rfc/rfc9106.txt , IETF, 2021 Update : [xmlenc-core] Donald Eastlake, Joseph Reagle, Frederick Hirsch, Thomas Roessler, XML Encryption Syntax and Processing, https://www.w3.org/TR/2013/REC-xmlenc-core-20130411/ , W3C, 2013. 3.4 Encryption Add new 3.4.1 : 3.4.1 General Fundamentally, there are 2 ways to encrypt an OpenDocument package. In every version of OpenDocument, it has been possible to encrypt every file entry in the package separately; some or all files within the package may be encrypted. With OpenDocument 1.5, it is now possible to encrypt the whole package at once, which is considered a better approach as it is both more efficient and more secure. This method is specified in section 3.4.4. Current best practice is to use full package encryption with SHA256 start key derivation, Argon2id key derivation function and AES-GCM authenticated encryption algorithm. Renumber and update existing 3.4.1 and 3.4.2 : 3.4.2 Encrypting a File Entry The encryption process takes place in the following stages: A single start key is generated and used for all of the keys that will be derived. The derived key is generated based on the start key. The file is encrypted based on the derived key and the encryption algorithm. The information regarding the algorithms that were used to encrypt a file and required parameters are contained in the manifest. The manifest shall not be encrypted. Each file entry that is encrypted shall be compressed with the “deflate” algorithm before being encrypted. Encrypted file entries shall be flagged as 'STORED' rather than 'DEFLATED' in the Zip file's central directory. The size of the encrypted file should replace the real size value in the file entry's central directory records, its local file header and the data descriptor, if any. The original uncompressed, unencrypted size shall be contained in the manifest:size 4.16.13 attribute of the <manifest:file-entry> 4.3 element for the file entry. The encrypted form can be of greater size than the DEFLATED file used as the plaintext. Note: The encrypted form may be of greater size because of padding of plaintext, inclusion of additional information, and other characteristics of the encryption technique). The encryption method shall be such that the exact size and value of the plaintext DEFLATED file is recovered by the corresponding decryption process. 3.4.3 Encryption Process The three stages of the encryption process proceed as follows, using the legacy algorithms to illustrate each stage: 1. The start key is generated: The byte sequence representing the password in UTF-8 is used to generate a 20-byte SHA1 digest (see [RFC3174] ). 2. A separate derived key is generated from the start key: The PBKDF2 algorithm based on the HMAC-SHA-1 function (see [RFC2898] ) is used for the key derivation. A 16-byte salt is generated by a random generator. The salt is used together with the start key to derive a unique 128-bit key. The default iteration count for the algorithm is 1024. 3. The file is encrypted: The random number generator is used to generate the 8-byte initialization vector for the algorithm. The derived key is used together with the initialization vector to encrypt the file using the Blowfish algorithm in 8-bit cipher feedback (8-bit CFB) mode (see [Schneier] ). Add new 3.4.4 : 3.4.4 Full Package Encryption An OpenDocument package can be produced in the usual way (without encryption), and then wrapped in an outer OpenDocument package in an encrypted file entry with the special name "encrypted-package". This is called full package encryption. The encrypted wrapper package should contain only "mimetype", "encrypted-package", and files in "META-INF/". 3.9 Interactions Between Encryption and Digital Signatures Update 3.9 : An OpenDocument Package Producer that both encrypts files in the package and applies digital signatures to files in the package should either first encrypt (per section 3.4) and then apply the digital signatures (per section 5) or first apply the digital signatures and then encrypt. If the encryption of the files is done first, the digital signatures files shall not be encrypted and, in the case of full package encryption, shall be placed in the outer wrapper package. If the files in the package are encrypted after applying the digital signatures, the digital signature files shall be encrypted and, in the case of full package encryption, shall be placed in the inner package. See also section 5.2. Note: It is current practice to first encrypt and then apply the digital signatures. 4.16 Manifest Attributes In 4.16.1 replace the fourth bullet point with the following paragraph (not bulleted) : Package producers that support encryption should support the value http://www.w3.org/2009/xmlenc11#aes256-gcm . Package consumers that support encryption should support the values http://www.w3.org/2009/xmlenc11#aes256-gcm , http://www.w3.org/2001/04/xmlenc#aes256-cbc , Blowfish CFB and urn:oasis:names:tc:opendocument:xmlns:manifest:1.0#blowfish . Update 4.16.2, 4.16.3, 4.16.5 - 4.16.9, 4.16.12 : 4.16.2 manifest:checksum (deprecated) The manifest:checksum attribute specifies a digest in base64Binary encoding that can be used to detect password correctness as specified by a manifest:checksum-type attribute 4.16.3. The manifest:checksum attribute should not be produced if the algorithm referenced by manifest:algorithm-name provides authenticated encryption, e.g., AES-GCM. ... 4.16.3 manifest:checksum-type (deprecated) The manifest:checksum-type attribute specifies the name of a digest algorithm that can be used to check password correctness. The digest is build from the compressed unencrypted file. The manifest:checksum-type attribute should not be produced if the algorithm referenced by manifest:algorithm-name provides authenticated encryption, e.g. AES-GCM. The defined values for the manifest:checksum-type attribute are: ... 4.16.5 manifest:initialisation-vector The manifest:initialisation-vector attribute value provides the byte-sequence for the initialization vector used by the encryption algorithm when delivery of a required initialization vector is not specified as part of the encryption algorithm definition. The initialization vector is a base64Binary encoded sequence. The format and length of an initialization vector, in bytes, shall be as required by its encryption algorithm specification. Producers should generate fresh random initialization vector values every time they create a package, instead of reusing a salt value consumed from an existing package. ... 4.16.6 manifest:start-key-generation-name ... Package producers that support encryption should use the http://www.w3.org/2001/04/xmldsig#sha256 algorithm. Package consumers that support encryption shall support the values SHA1 , http://www.w3.org/2000/09/xmldsig#sha1 , http://www.w3.org/2000/09/xmldsig#sha256 and http://www.w3.org/2001/04/xmldsig#sha256 . ... 4.16.7 manifest:key-size The manifest:key-size attribute specifies the length in octets of a key delivered by a key-developing algorithm. Note : The value used with the <manifest:start-key-generation> element will need to be one obtainable from the start-key-generation algorithm and the input requirements of the key derivation algorithm. Note : The value used with the <manifest:key-derivation> element will need to be one obtainable from the key-derivation algorithm and acceptable for the encryption algorithm being used. ... 4.16.8 manifest:iteration-count The manifest:iteration-count attribute specifies the number of iterations used by the key derivation algorithm to derive a key. Note : Current recommendation for PBKDF2 is to use 600000 iterations. ... 4.16.9 manifest:key-derivation-name The manifest:key-derivation-name attribute specifies the password-based key-derivation algorithm used to derive a cryptographic key for use in encryption and decryption of the file. The defined values for the manifest:key-derivation-name attribute are: ... urn:oasis:names:tc:opendocument:xmlns:manifest:1.5#argon2id : The Argon2id algorithm as specified by [RFC9106] . From section 3.1 Argon2 Inputs and Outputs, the parameters "K" and "X" are not used. If this value is used, the attributes manifest:argon2-iterations , manifest:argon2-memory , and manifest:argon2-lanes shall be present to provide the "t", "m", and "p" parameters ... 4.16.12 manifest:salt The manifest:salt attribute carries the value of a cryptographically-random binary value designed to mitigate certain cryptographic attacks on the password. There is no maximum length to the salt. See for further considerations in the use of salts with key-derivation and other cryptographic functions. The salt is encoded in the attribute value as a base64Binary value. Producers should generate fresh random salt values every time they create a package, instead of reusing a salt value consumed from an existing package. ... Add new sections 4.16.15, 4.16.16 and 4.16.17 : 4.16.15 manifest:argon2-iterations Specifies parameter "t" in [RFC9106] , §3.1 Argon2 Inputs and Outputs. 4.16.16 manifest:argon2-memory Specifies parameter "m" in [RFC9106] , §3.1 Argon2 Inputs and Outputs. 4.16.17 manifest:argon2-lanes Specifies parameter "p" in [RFC9106] , §3.1 Argon2 Inputs and Outputs.
Current situation
Encryption is currently specified in ODF 1.4 Part 2, 3.4 "Encryption" and individual elements and attributes in 4.*.
Currently for password-based encryption an ODF package, every file entry in the package is stored following these steps:
1. original size and checksum of first 1KiB of plain text are stored as attributes (to enable verifying the password on decryption)
- manifest:size
- <manifest:encryption-data>
- manifest:checksum, manifest:checksum-type
2. file data is compressed with "deflate"
3. password entered by user is hashed once (typically with SHA256)
- <manifest:start-key-generation>
- manifest:start-key-generation-name
- manifest:key-size
4. salt is randomly generated, KDF is applied to result of step 3 (typically PBKDF2)
- <manifest:key-derivation>
- manifest:salt
- manifest:iteration-count
- manifest:key-derivation-name
- manifest:key-size
5. initialization vector is randomly generated, file data is encrypted (typically AES256 CFB)
- <manifest:algorithm>
- manifest:initialisation-vector
- manifest:algorithm-name
6. the encrypted file data is STORED (uncompressed) in the ZIP package
Problems
There are problems with this approach:
1. deriving a new key for each file entry is wasteful and in practice a serious performance problem
2. PBKDF2 is susceptible to brute-forcing with GPUs, requiring large number of iterations to mitigate https://security.stackexchange.com/questions/3959/recommended-of-iterations-when-using-pbkdf2-sha256
3. there is no authentication of the encrypted data
4. information is leaked, most importantly the SHA/1k checksums, and also names and sizes of file entries
Problems 3 and 4 also affect PGP encrypted ODF packages.