mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2025-02-23 06:35:28 +01:00
Introduce ed25519_{sign,checksig}_prefixed functions().
This commit is contained in:
parent
261f4c3f6f
commit
b8bfdf638e
3 changed files with 141 additions and 0 deletions
|
@ -184,9 +184,43 @@ ed25519_keypair_generate(ed25519_keypair_t *keypair_out, int extra_strong)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return a heap-allocated array that contains <b>msg</b> prefixed by the
|
||||||
|
* string <b>prefix_str</b>. Set <b>final_msg_len_out</b> to the size of the
|
||||||
|
* final array. If an error occured, return NULL. It's the resonsibility of the
|
||||||
|
* caller to free the returned array. */
|
||||||
|
static uint8_t *
|
||||||
|
get_prefixed_msg(const uint8_t *msg, size_t msg_len,
|
||||||
|
const char *prefix_str,
|
||||||
|
size_t *final_msg_len_out)
|
||||||
|
{
|
||||||
|
size_t prefixed_msg_len, prefix_len;
|
||||||
|
uint8_t *prefixed_msg;
|
||||||
|
|
||||||
|
tor_assert(prefix_str);
|
||||||
|
tor_assert(final_msg_len_out);
|
||||||
|
|
||||||
|
prefix_len = strlen(prefix_str);
|
||||||
|
|
||||||
|
/* msg_len + strlen(prefix_str) must not overflow. */
|
||||||
|
if (msg_len > SIZE_T_CEILING - prefix_len) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
prefixed_msg_len = msg_len + prefix_len;
|
||||||
|
prefixed_msg = tor_malloc_zero(prefixed_msg_len);
|
||||||
|
|
||||||
|
memcpy(prefixed_msg, prefix_str, prefix_len);
|
||||||
|
memcpy(prefixed_msg + prefix_len, msg, msg_len);
|
||||||
|
|
||||||
|
*final_msg_len_out = prefixed_msg_len;
|
||||||
|
return prefixed_msg;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set <b>signature_out</b> to a signature of the <b>len</b>-byte message
|
* Set <b>signature_out</b> to a signature of the <b>len</b>-byte message
|
||||||
* <b>msg</b>, using the secret and public key in <b>keypair</b>.
|
* <b>msg</b>, using the secret and public key in <b>keypair</b>.
|
||||||
|
*
|
||||||
|
* Return 0 if we successfuly signed the message, otherwise return -1.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
ed25519_sign(ed25519_signature_t *signature_out,
|
ed25519_sign(ed25519_signature_t *signature_out,
|
||||||
|
@ -202,6 +236,37 @@ ed25519_sign(ed25519_signature_t *signature_out,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Like ed25519_sign(), but also prefix <b>msg</b> with <b>prefix_str</b>
|
||||||
|
* before signing. <b>prefix_str</b> must be a NUL-terminated string.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
ed25519_sign_prefixed(ed25519_signature_t *signature_out,
|
||||||
|
const uint8_t *msg, size_t msg_len,
|
||||||
|
const char *prefix_str,
|
||||||
|
const ed25519_keypair_t *keypair)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
size_t prefixed_msg_len;
|
||||||
|
uint8_t *prefixed_msg;
|
||||||
|
|
||||||
|
tor_assert(prefix_str);
|
||||||
|
|
||||||
|
prefixed_msg = get_prefixed_msg(msg, msg_len, prefix_str,
|
||||||
|
&prefixed_msg_len);
|
||||||
|
if (!prefixed_msg) {
|
||||||
|
log_warn(LD_GENERAL, "Failed to get prefixed msg.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = ed25519_sign(signature_out,
|
||||||
|
prefixed_msg, prefixed_msg_len,
|
||||||
|
keypair);
|
||||||
|
tor_free(prefixed_msg);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether if <b>signature</b> is a valid signature for the
|
* Check whether if <b>signature</b> is a valid signature for the
|
||||||
* <b>len</b>-byte message in <b>msg</b> made with the key <b>pubkey</b>.
|
* <b>len</b>-byte message in <b>msg</b> made with the key <b>pubkey</b>.
|
||||||
|
@ -217,6 +282,36 @@ ed25519_checksig(const ed25519_signature_t *signature,
|
||||||
get_ed_impl()->open(signature->sig, msg, len, pubkey->pubkey) < 0 ? -1 : 0;
|
get_ed_impl()->open(signature->sig, msg, len, pubkey->pubkey) < 0 ? -1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Like ed2519_checksig(), but also prefix <b>msg</b> with <b>prefix_str</b>
|
||||||
|
* before verifying signature. <b>prefix_str</b> must be a NUL-terminated
|
||||||
|
* string.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
ed25519_checksig_prefixed(const ed25519_signature_t *signature,
|
||||||
|
const uint8_t *msg, size_t msg_len,
|
||||||
|
const char *prefix_str,
|
||||||
|
const ed25519_public_key_t *pubkey)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
size_t prefixed_msg_len;
|
||||||
|
uint8_t *prefixed_msg;
|
||||||
|
|
||||||
|
prefixed_msg = get_prefixed_msg(msg, msg_len, prefix_str,
|
||||||
|
&prefixed_msg_len);
|
||||||
|
if (!prefixed_msg) {
|
||||||
|
log_warn(LD_GENERAL, "Failed to get prefixed msg.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = ed25519_checksig(signature,
|
||||||
|
prefixed_msg, prefixed_msg_len,
|
||||||
|
pubkey);
|
||||||
|
tor_free(prefixed_msg);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
/** Validate every signature among those in <b>checkable</b>, which contains
|
/** Validate every signature among those in <b>checkable</b>, which contains
|
||||||
* exactly <b>n_checkable</b> elements. If <b>okay_out</b> is non-NULL, set
|
* exactly <b>n_checkable</b> elements. If <b>okay_out</b> is non-NULL, set
|
||||||
* the i'th element of <b>okay_out</b> to 1 if the i'th element of
|
* the i'th element of <b>okay_out</b> to 1 if the i'th element of
|
||||||
|
|
|
@ -55,6 +55,17 @@ int ed25519_checksig(const ed25519_signature_t *signature,
|
||||||
const uint8_t *msg, size_t len,
|
const uint8_t *msg, size_t len,
|
||||||
const ed25519_public_key_t *pubkey);
|
const ed25519_public_key_t *pubkey);
|
||||||
|
|
||||||
|
int
|
||||||
|
ed25519_sign_prefixed(ed25519_signature_t *signature_out,
|
||||||
|
const uint8_t *msg, size_t len,
|
||||||
|
const char *prefix_str,
|
||||||
|
const ed25519_keypair_t *keypair);
|
||||||
|
int
|
||||||
|
ed25519_checksig_prefixed(const ed25519_signature_t *signature,
|
||||||
|
const uint8_t *msg, size_t len,
|
||||||
|
const char *prefix_str,
|
||||||
|
const ed25519_public_key_t *pubkey);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A collection of information necessary to check an Ed25519 signature. Used
|
* A collection of information necessary to check an Ed25519 signature. Used
|
||||||
* for batch verification.
|
* for batch verification.
|
||||||
|
|
|
@ -2242,6 +2242,41 @@ test_crypto_ed25519_simple(void *arg)
|
||||||
tt_int_op(0, OP_EQ, ed25519_checksig_batch(NULL, ch, 2));
|
tt_int_op(0, OP_EQ, ed25519_checksig_batch(NULL, ch, 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Test the string-prefixed sign/checksig functions */
|
||||||
|
{
|
||||||
|
ed25519_signature_t manual_sig;
|
||||||
|
char *prefixed_msg;
|
||||||
|
|
||||||
|
/* Generate a signature with a prefixed msg. */
|
||||||
|
tt_int_op(0, OP_EQ, ed25519_sign_prefixed(&sig1, msg, msg_len,
|
||||||
|
"always in the mood",
|
||||||
|
&kp1));
|
||||||
|
|
||||||
|
/* First, check that ed25519_sign_prefixed() returns the exact same sig as
|
||||||
|
if we had manually prefixed the msg ourselves. */
|
||||||
|
tor_asprintf(&prefixed_msg, "%s%s", "always in the mood", msg);
|
||||||
|
tt_int_op(0, OP_EQ, ed25519_sign(&manual_sig, (uint8_t *)prefixed_msg,
|
||||||
|
strlen(prefixed_msg), &kp1));
|
||||||
|
tor_free(prefixed_msg);
|
||||||
|
tt_assert(!memcmp(sig1.sig, manual_sig.sig, sizeof(sig1.sig)));
|
||||||
|
|
||||||
|
/* Test that prefixed checksig verifies it properly. */
|
||||||
|
tt_int_op(0, OP_EQ, ed25519_checksig_prefixed(&sig1, msg, msg_len,
|
||||||
|
"always in the mood",
|
||||||
|
&pub1));
|
||||||
|
|
||||||
|
/* Test that checksig with wrong prefix fails. */
|
||||||
|
tt_int_op(-1, OP_EQ, ed25519_checksig_prefixed(&sig1, msg, msg_len,
|
||||||
|
"always in the moo",
|
||||||
|
&pub1));
|
||||||
|
tt_int_op(-1, OP_EQ, ed25519_checksig_prefixed(&sig1, msg, msg_len,
|
||||||
|
"always in the moon",
|
||||||
|
&pub1));
|
||||||
|
tt_int_op(-1, OP_EQ, ed25519_checksig_prefixed(&sig1, msg, msg_len,
|
||||||
|
"always in the mood!",
|
||||||
|
&pub1));
|
||||||
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue