summaryrefslogtreecommitdiff
path: root/plugins/MirOTR/libotr/src/sm.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/MirOTR/libotr/src/sm.c')
-rw-r--r--plugins/MirOTR/libotr/src/sm.c213
1 files changed, 141 insertions, 72 deletions
diff --git a/plugins/MirOTR/libotr/src/sm.c b/plugins/MirOTR/libotr/src/sm.c
index 535ae2243c..4fb679ea81 100644
--- a/plugins/MirOTR/libotr/src/sm.c
+++ b/plugins/MirOTR/libotr/src/sm.c
@@ -1,6 +1,8 @@
/*
* Off-the-Record Messaging library
- * Copyright (C) 2004-2008 Ian Goldberg, Chris Alexander, Nikita Borisov
+ * Copyright (C) 2004-2014 Ian Goldberg, David Goulet, Rob Smits,
+ * Chris Alexander, Willy Lew, Lisa Du,
+ * Nikita Borisov
* <otr@cypherpunks.ca>
*
* This library is free software; you can redistribute it and/or
@@ -14,13 +16,13 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* system headers */
#include <stdlib.h>
#include <stdio.h>
-#include <sys/types.h>
+#include <sys/types.h>
/* libgcrypt headers */
#include <gcrypt.h>
@@ -29,6 +31,30 @@
#include "sm.h"
#include "serial.h"
+#if OTRL_DEBUGGING
+
+/* Dump the contents of an SMState to the FILE *f. */
+void otrl_sm_dump(FILE *f, const OtrlSMState *sm)
+{
+ fprintf(f, " SM state:\n");
+ fprintf(f, " Next expected: %d (%s)\n", sm->nextExpected,
+ sm->nextExpected == OTRL_SMP_EXPECT1 ? "EXPECT1" :
+ sm->nextExpected == OTRL_SMP_EXPECT2 ? "EXPECT2" :
+ sm->nextExpected == OTRL_SMP_EXPECT3 ? "EXPECT3" :
+ sm->nextExpected == OTRL_SMP_EXPECT4 ? "EXPECT4" :
+ sm->nextExpected == OTRL_SMP_EXPECT5 ? "EXPECT5" :
+ "INVALID");
+ fprintf(f, " Received_Q: %d\n", sm->received_question);
+ fprintf(f, " Progress state: %d (%s)\n", sm->sm_prog_state,
+ sm->sm_prog_state == OTRL_SMP_PROG_OK ? "OK" :
+ sm->sm_prog_state == OTRL_SMP_PROG_CHEATED ? "CHEATED" :
+ sm->sm_prog_state == OTRL_SMP_PROG_FAILED ? "FAILED" :
+ sm->sm_prog_state == OTRL_SMP_PROG_SUCCEEDED ? "SUCCEEDED" :
+ "INVALID");
+}
+
+#endif
+
static const int SM_MSG1_LEN = 6;
static const int SM_MSG2_LEN = 11;
static const int SM_MSG3_LEN = 8;
@@ -70,10 +96,12 @@ static gcry_mpi_t SM_MODULUS_MINUS_2 = NULL;
void otrl_sm_init(void)
{
gcry_check_version(NULL);
- gcry_mpi_scan(&SM_MODULUS, GCRYMPI_FMT_HEX, SM_MODULUS_S, 0, NULL);
- gcry_mpi_scan(&SM_ORDER, GCRYMPI_FMT_HEX, SM_ORDER_S, 0, NULL);
- gcry_mpi_scan(&SM_GENERATOR, GCRYMPI_FMT_HEX, SM_GENERATOR_S,
- 0, NULL);
+ gcry_mpi_scan(&SM_MODULUS, GCRYMPI_FMT_HEX,
+ (const unsigned char *)SM_MODULUS_S, 0, NULL);
+ gcry_mpi_scan(&SM_ORDER, GCRYMPI_FMT_HEX,
+ (const unsigned char *)SM_ORDER_S, 0, NULL);
+ gcry_mpi_scan(&SM_GENERATOR, GCRYMPI_FMT_HEX,
+ (const unsigned char *)SM_GENERATOR_S, 0, NULL);
SM_MODULUS_MINUS_2 = gcry_mpi_new(SM_MOD_LEN_BITS);
gcry_mpi_sub_ui(SM_MODULUS_MINUS_2, SM_MODULUS, 2);
}
@@ -106,7 +134,7 @@ void otrl_sm_state_new(OtrlSMState *smst)
void otrl_sm_state_init(OtrlSMState *smst)
{
otrl_sm_state_free(smst);
- smst->secret = gcry_mpi_new(SM_MOD_LEN_BITS);
+ smst->secret = gcry_mpi_snew(SM_MOD_LEN_BITS);
smst->x2 = NULL;
smst->x3 = NULL;
smst->g1 = gcry_mpi_copy(SM_GENERATOR);
@@ -156,7 +184,7 @@ void otrl_sm_msg2_init(gcry_mpi_t **msg2)
msg[7] = gcry_mpi_new(SM_MOD_LEN_BITS);
msg[8] = NULL;
msg[9] = gcry_mpi_new(SM_MOD_LEN_BITS);
- msg[10] = gcry_mpi_new(SM_MOD_LEN_BITS);
+ msg[10] = gcry_mpi_new(SM_MOD_LEN_BITS);
*msg2 = msg;
}
@@ -223,7 +251,7 @@ void otrl_sm_msg_free(gcry_mpi_t **message, int msglen)
gcry_mpi_t *msg = *message;
int i;
for (i=0; i<msglen; i++) {
- gcry_mpi_release(msg[i]);
+ gcry_mpi_release(msg[i]);
}
free(msg);
*message = NULL;
@@ -255,7 +283,7 @@ static gcry_error_t otrl_sm_hash(gcry_mpi_t* hash, int version,
size_t totalsize;
unsigned char* dataa;
unsigned char* datab;
-
+
gcry_mpi_aprint(GCRYMPI_FMT_USG, &dataa, &sizea, a);
totalsize = 1 + 4 + sizea;
if (b) {
@@ -306,9 +334,9 @@ static gcry_error_t serialize_mpi_array(unsigned char **buffer, int *buflen,
unsigned char *bufp;
for (i=0; i<count; i++) {
- gcry_mpi_aprint(GCRYMPI_FMT_USG, &(tempbuffer[i]), &(list_sizes[i]),
+ gcry_mpi_aprint(GCRYMPI_FMT_USG, &(tempbuffer[i]), &(list_sizes[i]),
mpis[i]);
- totalsize += list_sizes[i];
+ totalsize += list_sizes[i];
}
*buflen = (count+1)*4 + totalsize;
@@ -320,15 +348,15 @@ static gcry_error_t serialize_mpi_array(unsigned char **buffer, int *buflen,
write_int(count);
for(i=0; i<count; i++)
{
- nextsize = list_sizes[i];
- write_int(nextsize);
-
- for(j=0; j<nextsize; j++)
- bufp[j] = tempbuffer[i][j];
-
+ nextsize = list_sizes[i];
+ write_int(nextsize);
+
+ for(j=0; j<nextsize; j++)
+ bufp[j] = tempbuffer[i][j];
+
bufp += nextsize;
- lenp -= nextsize;
- gcry_free(tempbuffer[i]);
+ lenp -= nextsize;
+ gcry_free(tempbuffer[i]);
}
free(tempbuffer);
free(list_sizes);
@@ -344,8 +372,8 @@ static gcry_error_t serialize_mpi_array(unsigned char **buffer, int *buflen,
static gcry_error_t unserialize_mpi_array(gcry_mpi_t **mpis,
unsigned int expcount, const unsigned char *buffer, const int buflen)
{
- int i;
- int lenp = buflen;
+ unsigned int i;
+ size_t lenp = buflen;
unsigned int thecount = 0;
const unsigned char* bufp = buffer;
*mpis = NULL;
@@ -400,10 +428,11 @@ static int check_expon(gcry_mpi_t x)
/*
* Proof of knowledge of a discrete logarithm
*/
-static gcry_error_t otrl_sm_proof_know_log(gcry_mpi_t *c, gcry_mpi_t *d, const gcry_mpi_t g, const gcry_mpi_t x, int version)
+static gcry_error_t otrl_sm_proof_know_log(gcry_mpi_t *c, gcry_mpi_t *d,
+ const gcry_mpi_t g, const gcry_mpi_t x, int version)
{
gcry_mpi_t r = randomExponent();
- gcry_mpi_t temp = gcry_mpi_new(SM_MOD_LEN_BITS);
+ gcry_mpi_t temp = gcry_mpi_snew(SM_MOD_LEN_BITS);
gcry_mpi_powm(temp, g, r, SM_MODULUS);
otrl_sm_hash(c, version, temp, NULL);
gcry_mpi_mulm(temp, x, *c, SM_ORDER);
@@ -415,9 +444,11 @@ static gcry_error_t otrl_sm_proof_know_log(gcry_mpi_t *c, gcry_mpi_t *d, const g
}
/*
- * Verify a proof of knowledge of a discrete logarithm. Checks that c = h(g^d x^c)
+ * Verify a proof of knowledge of a discrete logarithm.
+ * Checks that c = h(g^d x^c)
*/
-static int otrl_sm_check_know_log(const gcry_mpi_t c, const gcry_mpi_t d, const gcry_mpi_t g, const gcry_mpi_t x, int version)
+static int otrl_sm_check_know_log(const gcry_mpi_t c, const gcry_mpi_t d,
+ const gcry_mpi_t g, const gcry_mpi_t x, int version)
{
int comp;
@@ -430,7 +461,7 @@ static int otrl_sm_check_know_log(const gcry_mpi_t c, const gcry_mpi_t d, const
gcry_mpi_powm(xc, x, c, SM_MODULUS);
gcry_mpi_mulm(gdxc, gd, xc, SM_MODULUS);
otrl_sm_hash(&hgdxc, version, gdxc, NULL);
-
+
comp = gcry_mpi_cmp(hgdxc, c);
gcry_mpi_release(gd);
gcry_mpi_release(xc);
@@ -443,7 +474,9 @@ static int otrl_sm_check_know_log(const gcry_mpi_t c, const gcry_mpi_t d, const
/*
* Proof of knowledge of coordinates with first components being equal
*/
-static gcry_error_t otrl_sm_proof_equal_coords(gcry_mpi_t *c, gcry_mpi_t *d1, gcry_mpi_t *d2, const OtrlSMState *state, const gcry_mpi_t r, int version)
+static gcry_error_t otrl_sm_proof_equal_coords(gcry_mpi_t *c, gcry_mpi_t *d1,
+ gcry_mpi_t *d2, const OtrlSMState *state, const gcry_mpi_t r,
+ int version)
{
gcry_mpi_t r1 = randomExponent();
gcry_mpi_t r2 = randomExponent();
@@ -475,7 +508,9 @@ static gcry_error_t otrl_sm_proof_equal_coords(gcry_mpi_t *c, gcry_mpi_t *d1, gc
/*
* Verify a proof of knowledge of coordinates with first components being equal
*/
-static gcry_error_t otrl_sm_check_equal_coords(const gcry_mpi_t c, const gcry_mpi_t d1, const gcry_mpi_t d2, const gcry_mpi_t p, const gcry_mpi_t q, const OtrlSMState *state, int version)
+static gcry_error_t otrl_sm_check_equal_coords(const gcry_mpi_t c,
+ const gcry_mpi_t d1, const gcry_mpi_t d2, const gcry_mpi_t p,
+ const gcry_mpi_t q, const OtrlSMState *state, int version)
{
int comp;
@@ -518,7 +553,8 @@ static gcry_error_t otrl_sm_check_equal_coords(const gcry_mpi_t c, const gcry_mp
/*
* Proof of knowledge of logs with exponents being equal
*/
-static gcry_error_t otrl_sm_proof_equal_logs(gcry_mpi_t *c, gcry_mpi_t *d, OtrlSMState *state, int version)
+static gcry_error_t otrl_sm_proof_equal_logs(gcry_mpi_t *c, gcry_mpi_t *d,
+ OtrlSMState *state, int version)
{
gcry_mpi_t r = randomExponent();
gcry_mpi_t temp1 = gcry_mpi_new(SM_MOD_LEN_BITS);
@@ -543,7 +579,9 @@ static gcry_error_t otrl_sm_proof_equal_logs(gcry_mpi_t *c, gcry_mpi_t *d, OtrlS
/*
* Verify a proof of knowledge of logs with exponents being equal
*/
-static gcry_error_t otrl_sm_check_equal_logs(const gcry_mpi_t c, const gcry_mpi_t d, const gcry_mpi_t r, const OtrlSMState *state, int version)
+static gcry_error_t otrl_sm_check_equal_logs(const gcry_mpi_t c,
+ const gcry_mpi_t d, const gcry_mpi_t r, const OtrlSMState *state,
+ int version)
{
int comp;
@@ -555,7 +593,7 @@ static gcry_error_t otrl_sm_check_equal_logs(const gcry_mpi_t c, const gcry_mpi_
/* Here, we recall the exponents used to create g3.
* If we have previously seen g3o = g1^x where x is unknown
* during the DH exchange to produce g3, then we may proceed with:
- *
+ *
* To verify, we test that hash(g1^d * g3o^c, qab^d * r^c) = c
* If indeed c = hash(g1^r1, qab^r1), d = r1- x * c
* And if indeed r = qab^x
@@ -601,11 +639,11 @@ gcry_error_t otrl_sm_step1(OtrlSMAliceState *astate,
*output = NULL;
*outputlen = 0;
-
+
gcry_mpi_scan(&secret_mpi, GCRYMPI_FMT_USG, secret, secretlen, NULL);
if (! astate->g1) {
- otrl_sm_state_init(astate);
+ otrl_sm_state_init(astate);
}
gcry_mpi_set(astate->secret, secret_mpi);
gcry_mpi_release(secret_mpi);
@@ -631,7 +669,8 @@ gcry_error_t otrl_sm_step1(OtrlSMAliceState *astate,
/* Receive the first message in SMP exchange, which was generated by
* otrl_sm_step1. Input is saved until the user inputs their secret
* information. No output. */
-gcry_error_t otrl_sm_step2a(OtrlSMBobState *bstate, const unsigned char* input, const int inputlen, int received_question)
+gcry_error_t otrl_sm_step2a(OtrlSMBobState *bstate, const unsigned char* input,
+ const int inputlen, int received_question)
{
gcry_mpi_t *msg1;
gcry_error_t err;
@@ -645,21 +684,23 @@ gcry_error_t otrl_sm_step2a(OtrlSMBobState *bstate, const unsigned char* input,
/* Read from input to find the mpis */
err = unserialize_mpi_array(&msg1, SM_MSG1_LEN, input, inputlen);
-
+
if (err != gcry_error(GPG_ERR_NO_ERROR)) return err;
if (check_group_elem(msg1[0]) || check_expon(msg1[2]) ||
check_group_elem(msg1[3]) || check_expon(msg1[5])) {
- return gcry_error(GPG_ERR_INV_VALUE);
+ otrl_sm_msg_free(&msg1, SM_MSG1_LEN);
+ return gcry_error(GPG_ERR_INV_VALUE);
}
/* Store Alice's g3a value for later in the protocol */
gcry_mpi_set(bstate->g3o, msg1[3]);
-
+
/* Verify Alice's proofs */
- if (otrl_sm_check_know_log(msg1[1], msg1[2], bstate->g1, msg1[0], 1) ||
- otrl_sm_check_know_log(msg1[4], msg1[5], bstate->g1, msg1[3], 2)) {
- return gcry_error(GPG_ERR_INV_VALUE);
+ if (otrl_sm_check_know_log(msg1[1], msg1[2], bstate->g1, msg1[0], 1) ||
+ otrl_sm_check_know_log(msg1[4], msg1[5], bstate->g1, msg1[3], 2)) {
+ otrl_sm_msg_free(&msg1, SM_MSG1_LEN);
+ return gcry_error(GPG_ERR_INV_VALUE);
}
/* Create Bob's half of the generators g2 and g3 */
@@ -671,6 +712,8 @@ gcry_error_t otrl_sm_step2a(OtrlSMBobState *bstate, const unsigned char* input,
gcry_mpi_powm(bstate->g3, msg1[3], bstate->x3, SM_MODULUS);
bstate->sm_prog_state = OTRL_SMP_PROG_OK;
+
+ otrl_sm_msg_free(&msg1, SM_MSG1_LEN);
return gcry_error(GPG_ERR_NO_ERROR);
}
@@ -684,7 +727,8 @@ gcry_error_t otrl_sm_step2a(OtrlSMBobState *bstate, const unsigned char* input,
* [4] = c3, [5] = d3, Bob's ZK proof of knowledge of g3b exponent
* [6] = pb, [7] = qb, Bob's halves of the (Pa/Pb) and (Qa/Qb) values
* [8] = cp, [9] = d5, [10] = d6, Bob's ZK proof that pb, qb formed correctly */
-gcry_error_t otrl_sm_step2b(OtrlSMBobState *bstate, const unsigned char* secret, int secretlen, unsigned char **output, int* outputlen)
+gcry_error_t otrl_sm_step2b(OtrlSMBobState *bstate, const unsigned char* secret,
+ int secretlen, unsigned char **output, int* outputlen)
{
/* Convert the given secret to the proper form and store it */
gcry_mpi_t r, qb1, qb2;
@@ -693,7 +737,7 @@ gcry_error_t otrl_sm_step2b(OtrlSMBobState *bstate, const unsigned char* secret,
*output = NULL;
*outputlen = 0;
-
+
gcry_mpi_scan(&secret_mpi, GCRYMPI_FMT_USG, secret, secretlen, NULL);
gcry_mpi_set(bstate->secret, secret_mpi);
gcry_mpi_release(secret_mpi);
@@ -717,7 +761,8 @@ gcry_error_t otrl_sm_step2b(OtrlSMBobState *bstate, const unsigned char* secret,
gcry_mpi_mulm(bstate->q, qb1, qb2, SM_MODULUS);
gcry_mpi_set(msg2[7], bstate->q);
- otrl_sm_proof_equal_coords(&(msg2[8]), &(msg2[9]), &(msg2[10]), bstate, r, 5);
+ otrl_sm_proof_equal_coords(&(msg2[8]), &(msg2[9]),
+ &(msg2[10]), bstate, r, 5);
/* Convert to serialized form */
serialize_mpi_array(output, outputlen, SM_MSG2_LEN, msg2);
@@ -738,18 +783,19 @@ gcry_error_t otrl_sm_step2b(OtrlSMBobState *bstate, const unsigned char* secret,
* [2] = cp, [3] = d5, [4] = d6, Alice's ZK proof that pa, qa formed correctly
* [5] = ra, calculated as (Qa/Qb)^x3 where x3 is the exponent used in g3a
* [6] = cr, [7] = d7, Alice's ZK proof that ra is formed correctly */
-gcry_error_t otrl_sm_step3(OtrlSMAliceState *astate, const unsigned char* input, const int inputlen, unsigned char **output, int* outputlen)
+gcry_error_t otrl_sm_step3(OtrlSMAliceState *astate, const unsigned char* input,
+ const int inputlen, unsigned char **output, int* outputlen)
{
/* Read from input to find the mpis */
gcry_mpi_t r, qa1, qa2, inv;
gcry_mpi_t *msg2;
gcry_mpi_t *msg3;
gcry_error_t err;
-
+
*output = NULL;
*outputlen = 0;
astate->sm_prog_state = OTRL_SMP_PROG_CHEATED;
-
+
err = unserialize_mpi_array(&msg2, SM_MSG2_LEN, input, inputlen);
if (err != gcry_error(GPG_ERR_NO_ERROR)) return err;
@@ -757,7 +803,8 @@ gcry_error_t otrl_sm_step3(OtrlSMAliceState *astate, const unsigned char* input,
check_group_elem(msg2[6]) || check_group_elem(msg2[7]) ||
check_expon(msg2[2]) || check_expon(msg2[5]) ||
check_expon(msg2[9]) || check_expon(msg2[10])) {
- return gcry_error(GPG_ERR_INV_VALUE);
+ otrl_sm_msg_free(&msg2, SM_MSG2_LEN);
+ return gcry_error(GPG_ERR_INV_VALUE);
}
otrl_sm_msg3_init(&msg3);
@@ -765,10 +812,12 @@ gcry_error_t otrl_sm_step3(OtrlSMAliceState *astate, const unsigned char* input,
/* Store Bob's g3a value for later in the protocol */
gcry_mpi_set(astate->g3o, msg2[3]);
- /* Verify Bob's knowledge of discreet log proofs */
- if (otrl_sm_check_know_log(msg2[1], msg2[2], astate->g1, msg2[0], 3) ||
- otrl_sm_check_know_log(msg2[4], msg2[5], astate->g1, msg2[3], 4)) {
- return gcry_error(GPG_ERR_INV_VALUE);
+ /* Verify Bob's knowledge of discrete log proofs */
+ if (otrl_sm_check_know_log(msg2[1], msg2[2], astate->g1, msg2[0], 3) ||
+ otrl_sm_check_know_log(msg2[4], msg2[5], astate->g1, msg2[3], 4)) {
+ otrl_sm_msg_free(&msg2, SM_MSG2_LEN);
+ otrl_sm_msg_free(&msg3, SM_MSG3_LEN);
+ return gcry_error(GPG_ERR_INV_VALUE);
}
/* Combine the two halves from Bob and Alice and determine g2 and g3 */
@@ -776,8 +825,12 @@ gcry_error_t otrl_sm_step3(OtrlSMAliceState *astate, const unsigned char* input,
gcry_mpi_powm(astate->g3, msg2[3], astate->x3, SM_MODULUS);
/* Verify Bob's coordinate equality proof */
- if (otrl_sm_check_equal_coords(msg2[8], msg2[9], msg2[10], msg2[6], msg2[7], astate, 5))
- return gcry_error(GPG_ERR_INV_VALUE);
+ if (otrl_sm_check_equal_coords(msg2[8], msg2[9], msg2[10], msg2[6], msg2[7],
+ astate, 5)) {
+ otrl_sm_msg_free(&msg2, SM_MSG2_LEN);
+ otrl_sm_msg_free(&msg3, SM_MSG3_LEN);
+ return gcry_error(GPG_ERR_INV_VALUE);
+ }
/* Calculate P and Q values for Alice */
r = randomExponent();
@@ -790,7 +843,8 @@ gcry_error_t otrl_sm_step3(OtrlSMAliceState *astate, const unsigned char* input,
gcry_mpi_mulm(astate->q, qa1, qa2, SM_MODULUS);
gcry_mpi_set(msg3[1], astate->q);
- otrl_sm_proof_equal_coords(&(msg3[2]), &(msg3[3]), &(msg3[4]), astate, r, 6);
+ otrl_sm_proof_equal_coords(&(msg3[2]), &(msg3[3]), &(msg3[4]), astate,
+ r, 6);
/* Calculate Ra and proof */
inv = gcry_mpi_new(SM_MOD_LEN_BITS);
@@ -822,7 +876,8 @@ gcry_error_t otrl_sm_step3(OtrlSMAliceState *astate, const unsigned char* input,
* This method also checks if Alice and Bob's secrets were the same. If
* so, it returns NO_ERROR. If the secrets differ, an INV_VALUE error is
* returned instead. */
-gcry_error_t otrl_sm_step4(OtrlSMBobState *bstate, const unsigned char* input, const int inputlen, unsigned char **output, int* outputlen)
+gcry_error_t otrl_sm_step4(OtrlSMBobState *bstate, const unsigned char* input,
+ const int inputlen, unsigned char **output, int* outputlen)
{
/* Read from input to find the mpis */
int comp;
@@ -835,7 +890,7 @@ gcry_error_t otrl_sm_step4(OtrlSMBobState *bstate, const unsigned char* input, c
*output = NULL;
*outputlen = 0;
bstate->sm_prog_state = OTRL_SMP_PROG_CHEATED;
-
+
if (err != gcry_error(GPG_ERR_NO_ERROR)) return err;
otrl_sm_msg4_init(&msg4);
@@ -843,12 +898,18 @@ gcry_error_t otrl_sm_step4(OtrlSMBobState *bstate, const unsigned char* input, c
if (check_group_elem(msg3[0]) || check_group_elem(msg3[1]) ||
check_group_elem(msg3[5]) || check_expon(msg3[3]) ||
check_expon(msg3[4]) || check_expon(msg3[7])) {
- return gcry_error(GPG_ERR_INV_VALUE);
+ otrl_sm_msg_free(&msg3, SM_MSG3_LEN);
+ otrl_sm_msg_free(&msg4, SM_MSG4_LEN);
+ return gcry_error(GPG_ERR_INV_VALUE);
}
/* Verify Alice's coordinate equality proof */
- if (otrl_sm_check_equal_coords(msg3[2], msg3[3], msg3[4], msg3[0], msg3[1], bstate, 6))
- return gcry_error(GPG_ERR_INV_VALUE);
+ if (otrl_sm_check_equal_coords(msg3[2], msg3[3], msg3[4], msg3[0], msg3[1],
+ bstate, 6)) {
+ otrl_sm_msg_free(&msg3, SM_MSG3_LEN);
+ otrl_sm_msg_free(&msg4, SM_MSG4_LEN);
+ return gcry_error(GPG_ERR_INV_VALUE);
+ }
/* Find Pa/Pb and Qa/Qb */
inv = gcry_mpi_new(SM_MOD_LEN_BITS);
@@ -858,8 +919,12 @@ gcry_error_t otrl_sm_step4(OtrlSMBobState *bstate, const unsigned char* input, c
gcry_mpi_mulm(bstate->qab, msg3[1], inv, SM_MODULUS);
/* Verify Alice's log equality proof */
- if (otrl_sm_check_equal_logs(msg3[6], msg3[7], msg3[5], bstate, 7))
- return gcry_error(GPG_ERR_INV_VALUE);
+ if (otrl_sm_check_equal_logs(msg3[6], msg3[7], msg3[5], bstate, 7)) {
+ otrl_sm_msg_free(&msg3, SM_MSG3_LEN);
+ otrl_sm_msg_free(&msg4, SM_MSG4_LEN);
+ gcry_mpi_release(inv);
+ return gcry_error(GPG_ERR_INV_VALUE);
+ }
/* Calculate Rb and proof */
gcry_mpi_powm(msg4[0], bstate->qab, bstate->x3, SM_MODULUS);
@@ -882,16 +947,17 @@ gcry_error_t otrl_sm_step4(OtrlSMBobState *bstate, const unsigned char* input, c
OTRL_SMP_PROG_SUCCEEDED;
if (comp)
- return gcry_error(GPG_ERR_INV_VALUE);
+ return gcry_error(GPG_ERR_INV_VALUE);
else
- return gcry_error(GPG_ERR_NO_ERROR);
+ return gcry_error(GPG_ERR_NO_ERROR);
}
/* Receives the final SMP message, which was generated in otrl_sm_step.
* This method checks if Alice and Bob's secrets were the same. If
* so, it returns NO_ERROR. If the secrets differ, an INV_VALUE error is
* returned instead. */
-gcry_error_t otrl_sm_step5(OtrlSMAliceState *astate, const unsigned char* input, const int inputlen)
+gcry_error_t otrl_sm_step5(OtrlSMAliceState *astate, const unsigned char* input,
+ const int inputlen)
{
/* Read from input to find the mpis */
int comp;
@@ -900,16 +966,19 @@ gcry_error_t otrl_sm_step5(OtrlSMAliceState *astate, const unsigned char* input,
gcry_error_t err;
err = unserialize_mpi_array(&msg4, SM_MSG4_LEN, input, inputlen);
astate->sm_prog_state = OTRL_SMP_PROG_CHEATED;
-
+
if (err != gcry_error(GPG_ERR_NO_ERROR)) return err;
if (check_group_elem(msg4[0]) || check_expon(msg4[2])) {
- return gcry_error(GPG_ERR_INV_VALUE);
+ otrl_sm_msg_free(&msg4, SM_MSG4_LEN);
+ return gcry_error(GPG_ERR_INV_VALUE);
}
/* Verify Bob's log equality proof */
- if (otrl_sm_check_equal_logs(msg4[1], msg4[2], msg4[0], astate, 8))
- return gcry_error(GPG_ERR_INV_VALUE);
+ if (otrl_sm_check_equal_logs(msg4[1], msg4[2], msg4[0], astate, 8)) {
+ otrl_sm_msg_free(&msg4, SM_MSG4_LEN);
+ return gcry_error(GPG_ERR_INV_VALUE);
+ }
/* Calculate Rab and verify that secrets match */
rab = gcry_mpi_new(SM_MOD_LEN_BITS);
@@ -923,7 +992,7 @@ gcry_error_t otrl_sm_step5(OtrlSMAliceState *astate, const unsigned char* input,
OTRL_SMP_PROG_SUCCEEDED;
if (comp)
- return gcry_error(GPG_ERR_INV_VALUE);
+ return gcry_error(GPG_ERR_INV_VALUE);
else
- return gcry_error(GPG_ERR_NO_ERROR);
+ return gcry_error(GPG_ERR_NO_ERROR);
}