summaryrefslogtreecommitdiff
path: root/nacl/curvecp/safenonce.c
diff options
context:
space:
mode:
Diffstat (limited to 'nacl/curvecp/safenonce.c')
-rw-r--r--nacl/curvecp/safenonce.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/nacl/curvecp/safenonce.c b/nacl/curvecp/safenonce.c
new file mode 100644
index 00000000..cfcabcd2
--- /dev/null
+++ b/nacl/curvecp/safenonce.c
@@ -0,0 +1,74 @@
1#include <sys/types.h>
2#include <sys/stat.h>
3#include <fcntl.h>
4#include <unistd.h>
5#include "crypto_uint64.h"
6#include "uint64_pack.h"
7#include "uint64_unpack.h"
8#include "savesync.h"
9#include "open.h"
10#include "load.h"
11#include "randombytes.h"
12#include "safenonce.h"
13
14#include "crypto_block.h"
15#if crypto_block_BYTES != 16
16error!
17#endif
18#if crypto_block_KEYBYTES != 32
19error!
20#endif
21
22/*
23Output: 128-bit nonce y[0],...,y[15].
24Reads and writes existing 8-byte file ".expertsonly/noncecounter",
25locked via existing 1-byte file ".expertsonly/lock".
26Also reads existing 32-byte file ".expertsonly/noncekey".
27Not thread-safe.
28
29Invariants:
30This process is free to use counters that are >=counterlow and <counterhigh.
31The 8-byte file contains a counter that is safe to use and >=counterhigh.
32
33XXX: should rewrite file in background, rather than briefly pausing
34*/
35
36static crypto_uint64 counterlow = 0;
37static crypto_uint64 counterhigh = 0;
38
39static unsigned char flagkeyloaded = 0;
40static unsigned char noncekey[32];
41static unsigned char data[16];
42
43int safenonce(unsigned char *y,int flaglongterm)
44{
45 if (!flagkeyloaded) {
46 int fdlock;
47 fdlock = open_lock(".expertsonly/lock");
48 if (fdlock == -1) return -1;
49 if (load(".expertsonly/noncekey",noncekey,sizeof noncekey) == -1) { close(fdlock); return -1; }
50 close(fdlock);
51 flagkeyloaded = 1;
52 }
53
54 if (counterlow >= counterhigh) {
55 int fdlock;
56 fdlock = open_lock(".expertsonly/lock");
57 if (fdlock == -1) return -1;
58 if (load(".expertsonly/noncecounter",data,8) == -1) { close(fdlock); return -1; }
59 counterlow = uint64_unpack(data);
60 if (flaglongterm)
61 counterhigh = counterlow + 1048576;
62 else
63 counterhigh = counterlow + 1;
64 uint64_pack(data,counterhigh);
65 if (savesync(".expertsonly/noncecounter",data,8) == -1) { close(fdlock); return -1; }
66 close(fdlock);
67 }
68
69 randombytes(data + 8,8);
70 uint64_pack(data,counterlow++);
71 crypto_block(y,data,noncekey);
72
73 return 0;
74}