summaryrefslogtreecommitdiff
path: root/src/lib/crypt
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/crypt')
-rw-r--r--src/lib/crypt/keyrot.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/src/lib/crypt/keyrot.c b/src/lib/crypt/keyrot.c
index def29297..e98df356 100644
--- a/src/lib/crypt/keyrot.c
+++ b/src/lib/crypt/keyrot.c
@@ -26,6 +26,7 @@
#include <ouroboros/atomics.h>
#include <ouroboros/crypt.h>
+#include <ouroboros/errno.h>
#include <ouroboros/pthread.h>
#include <ouroboros/rcu.h>
@@ -470,17 +471,17 @@ void keyrot_destroy(struct keyrot * kr)
}
/* A dup live epoch shadows straggler RX; epoch is peer-driven. */
-static bool kr_epoch_live(const struct kr_batch * cur,
- const struct kr_batch * prev,
- uint8_t epoch)
+static struct kr_batch * kr_live_batch(struct kr_batch * cur,
+ struct kr_batch * prev,
+ uint8_t epoch)
{
if (epoch == cur->epoch)
- return true;
+ return cur;
- if (prev == NULL)
- return false;
+ if (prev != NULL && epoch == prev->epoch)
+ return prev;
- return epoch == prev->epoch;
+ return NULL;
}
int keyrot_rekey(struct keyrot * kr,
@@ -491,6 +492,8 @@ int keyrot_rekey(struct keyrot * kr,
struct kr_batch * old_prev;
struct kr_batch * cur;
struct kr_batch * prev;
+ struct kr_batch * live;
+ int ret;
assert(kr != NULL);
assert(root != NULL);
@@ -507,10 +510,16 @@ int keyrot_rekey(struct keyrot * kr,
cur = rcu_deref(kr->cur);
prev = rcu_deref(kr->prev);
- if (kr_epoch_live(cur, prev, epoch)) {
+ live = kr_live_batch(cur, prev, epoch);
+ if (live != NULL) {
+ /* The first node key identifies the root. */
+ if (crypt_ct_cmp(live->nodes, nb->nodes, SYMMKEYSZ) == 0)
+ ret = -EREPLAY;
+ else
+ ret = -1;
rcu_wrunlock(&kr->guard);
kr_batch_free(nb);
- return -1;
+ return ret;
}
old_prev = kr->prev;