You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by rn...@apache.org on 2022/05/09 10:27:11 UTC
[couchdb] 01/01: use top bits of the IV as a nonce?
This is an automated email from the ASF dual-hosted git repository.
rnewson pushed a commit to branch aegis_3.x_nonce
in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit 1f4b4b0be5fd469e0e4bbcf9fad69401e11461b5
Author: Robert Newson <rn...@apache.org>
AuthorDate: Mon May 9 11:26:47 2022 +0100
use top bits of the IV as a nonce?
---
src/couch/src/couch_file.erl | 37 ++++++++++++++++++++-----------------
1 file changed, 20 insertions(+), 17 deletions(-)
diff --git a/src/couch/src/couch_file.erl b/src/couch/src/couch_file.erl
index f64c36ef2..a326aadeb 100644
--- a/src/couch/src/couch_file.erl
+++ b/src/couch/src/couch_file.erl
@@ -36,7 +36,8 @@
db_monitor,
pread_limit = 0,
enc,
- dec
+ dec,
+ nonce
}).
% public API
@@ -931,21 +932,23 @@ reset_eof(#file{} = File) ->
%% we've wiped all the data, including the wrapped key, so we need a new one.
init_crypto(#file{eof = 0} = File) ->
Key = crypto:strong_rand_bytes(32),
+ Nonce = crypto:strong_rand_bytes(8),
WrappedKey = couch_keywrap:key_wrap(master_key(), Key),
Header = <<?ENCRYPTED_HEADER, WrappedKey/binary>>,
ok = file:write(File#file.fd, Header),
+ ok = file:write(File#file.fd, Nonce),
ok = file:sync(File#file.fd),
- {ok, init_crypto(File#file{eof = iolist_size(Header)}, Key)};
+ {ok, init_crypto(File#file{eof = iolist_size(Header) + byte_size(Nonce)}, Key, Nonce)};
%% we're opening an existing file and need to unwrap the key.
init_crypto(#file{enc = undefined, dec = undefined} = File) ->
- case file:pread(File#file.fd, 0, 48) of
- {ok, <<?ENCRYPTED_HEADER, WrappedKey/binary>>} ->
+ case file:pread(File#file.fd, 0, 56) of
+ {ok, <<?ENCRYPTED_HEADER, WrappedKey:40/binary, Nonce:8/binary>>} ->
case couch_keywrap:key_unwrap(master_key(), WrappedKey) of
fail ->
{error, unwrap_failed};
Key when is_binary(Key) ->
- {ok, init_crypto(File, Key)}
+ {ok, init_crypto(File, Key, Nonce)}
end;
{ok, _} ->
{ok, File#file{enc = unencrypted, dec = unencrypted}};
@@ -955,13 +958,13 @@ init_crypto(#file{enc = undefined, dec = undefined} = File) ->
%% we're opening an existing file that contains a wrapped key
%% which we've already unwrapped.
-init_crypto(#file{eof = Eof, enc = Enc, dec = Dec} = File) when Eof > 48, Enc /= undefined, Dec /= undefined ->
+init_crypto(#file{eof = Eof, enc = Enc, dec = Dec} = File) when Eof > 56, Enc /= undefined, Dec /= undefined ->
{ok, File}.
-init_crypto(#file{} = File, Key) ->
+init_crypto(#file{} = File, Key, Nonce) ->
EncState = crypto:crypto_dyn_iv_init(aes_256_ctr, Key, true),
DecState = crypto:crypto_dyn_iv_init(aes_256_ctr, Key, false),
- File#file{enc = EncState, dec = DecState}.
+ File#file{enc = EncState, dec = DecState, nonce = Nonce}.
%% We can encrypt any section of the file but we must make
@@ -970,7 +973,7 @@ encrypted_write(#file{enc = unencrypted} = File, Data) ->
file:write(File#file.fd, Data);
encrypted_write(#file{} = File, Data) ->
- CipherText = encrypt(File#file.enc, File#file.eof, pad(File#file.eof, Data)),
+ CipherText = encrypt(File#file.enc, File#file.eof, File#file.nonce, pad(File#file.eof, Data)),
file:write(File#file.fd, unpad(File#file.eof, CipherText)).
@@ -982,7 +985,7 @@ encrypted_pread(#file{} = File, LocNums) ->
{ok, DataL} ->
{ok, lists:zipwith(
fun({Pos, _Len}, CipherText) ->
- PlainText = decrypt(File#file.dec, Pos, pad(Pos, CipherText)),
+ PlainText = decrypt(File#file.dec, Pos, File#file.nonce, pad(Pos, CipherText)),
unpad(Pos, PlainText) end,
LocNums,
DataL)};
@@ -997,25 +1000,25 @@ encrypted_pread(#file{dec = unencrypted} = File, Pos, Len) ->
encrypted_pread(#file{} = File, Pos, Len) ->
case file:pread(File#file.fd, Pos, Len) of
{ok, CipherText} ->
- PlainText = decrypt(File#file.dec, Pos, pad(Pos, CipherText)),
+ PlainText = decrypt(File#file.dec, Pos, File#file.nonce, pad(Pos, CipherText)),
{ok, unpad(Pos, PlainText)};
Else ->
Else
end.
-encrypt(Enc, Pos, Data) ->
- IV = aes_ctr_iv(Pos),
+encrypt(Enc, Pos, Nonce, Data) ->
+ IV = aes_ctr_iv(Nonce, Pos),
crypto:crypto_dyn_iv_update(Enc, Data, IV).
-decrypt(Dec, Pos, Data) ->
- IV = aes_ctr_iv(Pos),
+decrypt(Dec, Pos, Nonce, Data) ->
+ IV = aes_ctr_iv(Nonce, Pos),
crypto:crypto_dyn_iv_update(Dec, Data, IV).
-aes_ctr_iv(Pos) ->
- <<(Pos div 16):128>>.
+aes_ctr_iv(Nonce, Pos) ->
+ <<Nonce:8/binary, (Pos div 16):64>>.
pad(Pos, IOData) ->