Browse Source

Fix two security bugs.

Point::steg_encode was leaving the 24 high bits of the buffer as zero.
It also ignored the size parameter.  The size parameter has now been removed,
the zeros fixed and a test added to make sure that it is fixed.

Per https://github.com/MystenLabs/ed25519-unsafe-libs, deprecate eddsa signing
with separate pubkey and privkey input.  Instead decaf_ed*_keypair_sign
master
Mike Hamburg 1 year ago
parent
commit
703bb3452a
4 changed files with 14 additions and 9 deletions
  1. +1
    -1
      src/generator/template.py
  2. +2
    -2
      src/per_curve/eddsa.tmpl.h
  3. +2
    -3
      src/per_curve/point.tmpl.hxx
  4. +9
    -3
      test/test_decaf.cxx

+ 1
- 1
src/generator/template.py View File

@@ -43,7 +43,7 @@ def fillin(template,data):
ret = ""
while True:
dollars = template.find("$(",position)
if dollars is -1: return ret + template[position:]
if dollars == -1: return ret + template[position:]
ret += template[position:dollars]
position = dollars + 2
parens = 1


+ 2
- 2
src/per_curve/eddsa.tmpl.h View File

@@ -45,8 +45,8 @@ $("DECAF_API_VIS extern const uint8_t * const DECAF_ED" + gf_shortname + "_NO_CO
#define $(C_NS)_EDDSA_DECODE_RATIO ($(cofactor) / $(eddsa_encode_ratio))
#ifndef DECAF_EDDSA_NON_KEYPAIR_API_IS_DEPRECATED
/** If 1, add deprecation attribute to non-keypair API functions. For now, deprecate in Doxygen only. */
#define DECAF_EDDSA_NON_KEYPAIR_API_IS_DEPRECATED 0
/** If 1, add deprecation attribute to non-keypair API functions. Now deprecated. */
#define DECAF_EDDSA_NON_KEYPAIR_API_IS_DEPRECATED 1
#endif

/** @cond internal */


+ 2
- 3
src/per_curve/point.tmpl.hxx View File

@@ -551,12 +551,11 @@ public:
}

/** Steganographically encode this */
inline SecureBuffer steg_encode(Rng &rng, size_t size=STEG_BYTES) const /*throw(std::bad_alloc, LengthException)*/ {
if (size <= HASH_BYTES + 4 || size > 2*HASH_BYTES) throw LengthException();
inline SecureBuffer steg_encode(Rng &rng) const /*throw(std::bad_alloc, LengthException)*/ {
SecureBuffer out(STEG_BYTES);
decaf_error_t done;
do {
rng.read(Buffer(out).slice(HASH_BYTES-4,STEG_BYTES-HASH_BYTES+1));
rng.read(Buffer(out).slice(HASH_BYTES-4,STEG_BYTES-HASH_BYTES+4));
uint32_t hint = 0;
for (int i=0; i<4; i++) { hint |= uint32_t(out[HASH_BYTES-4+i])<<(8*i); }
done = invert_elligator(out, hint);


+ 9
- 3
test/test_decaf.cxx View File

@@ -72,8 +72,8 @@ static void print(const char *name, const Scalar &x) {

static void hexprint(const char *name, const SecureBuffer &buffer) {
printf(" %s = 0x", name);
for (auto i = buffer.rbegin(); i!= buffer.rend(); ++i) {
printf("%02x", *i);
for (int i=buffer.size()-1; i>=0; i--) {
printf("%02x", buffer[i]);
}
printf("\n");
}
@@ -292,7 +292,13 @@ static void test_elligator() {
}
Point t(rng);
point_check(test,t,t,t,0,0,t,Point::from_hash(t.steg_encode(rng)),"steg round-trip");
SecureBuffer bsteg = t.steg_encode(rng);
if (bsteg[Point::STEG_BYTES-1] == 0 && bsteg[Point::STEG_BYTES-2] == 0 && bsteg[Point::STEG_BYTES-3] == 0) {
test.fail();
printf(" Steg is nonuniform (probability of false failure = 2^-24)\n");
hexprint(" steg buffer:", bsteg);
}
point_check(test,t,t,t,0,0,t,Point::from_hash(bsteg),"steg round-trip");
FixedArrayBuffer<Point::HASH_BYTES> b3(rng), b4(b3);
t = Point::from_hash(b3);


Loading…
Cancel
Save