aboutsummaryrefslogtreecommitdiff
path: root/src/util/crypto_ecc.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2018-05-17 11:29:41 +0200
committerChristian Grothoff <christian@grothoff.org>2018-05-17 11:29:41 +0200
commit3175cde841a8a7836fcf74a3e1b804c71a3aa153 (patch)
tree9995eed6c318b9b6fe1833b5e30bd37111668250 /src/util/crypto_ecc.c
parent20fe42aac530cadfd88e5e409184b361a7f14f8f (diff)
downloadgnunet-3175cde841a8a7836fcf74a3e1b804c71a3aa153.tar.gz
gnunet-3175cde841a8a7836fcf74a3e1b804c71a3aa153.zip
deduplicate code in crypto_ecc
Diffstat (limited to 'src/util/crypto_ecc.c')
-rw-r--r--src/util/crypto_ecc.c137
1 files changed, 58 insertions, 79 deletions
diff --git a/src/util/crypto_ecc.c b/src/util/crypto_ecc.c
index 5d5e8a9ce..8cc6c18cb 100644
--- a/src/util/crypto_ecc.c
+++ b/src/util/crypto_ecc.c
@@ -1279,6 +1279,48 @@ eddsa_d_to_a (gcry_mpi_t d)
1279 1279
1280 1280
1281/** 1281/**
1282 * Take point from ECDH and convert it to key material.
1283 *
1284 * @param result point from ECDH
1285 * @param ctx ECC context
1286 * @param key_material[out] set to derived key material
1287 * @return #GNUNET_OK on success
1288 */
1289static int
1290point_to_hash (gcry_mpi_point_t result,
1291 gcry_ctx_t ctx,
1292 struct GNUNET_HashCode *key_material)
1293{
1294 gcry_mpi_t result_x;
1295 unsigned char xbuf[256 / 8];
1296 size_t rsize;
1297
1298 /* finally, convert point to string for hashing */
1299 result_x = gcry_mpi_new (256);
1300 if (gcry_mpi_ec_get_affine (result_x, NULL, result, ctx))
1301 {
1302 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "get_affine failed", 0);
1303 return GNUNET_SYSERR;
1304 }
1305
1306 rsize = sizeof (xbuf);
1307 GNUNET_assert (! gcry_mpi_get_flag (result_x, GCRYMPI_FLAG_OPAQUE));
1308 /* result_x can be negative here, so we do not use 'GNUNET_CRYPTO_mpi_print_unsigned'
1309 as that does not include the sign bit; x should be a 255-bit
1310 value, so with the sign it should fit snugly into the 256-bit
1311 xbuf */
1312 GNUNET_assert (0 ==
1313 gcry_mpi_print (GCRYMPI_FMT_STD, xbuf, rsize, &rsize,
1314 result_x));
1315 GNUNET_CRYPTO_hash (xbuf,
1316 rsize,
1317 key_material);
1318 gcry_mpi_release (result_x);
1319 return GNUNET_OK;
1320}
1321
1322
1323/**
1282 * @ingroup crypto 1324 * @ingroup crypto
1283 * Derive key material from a ECDH public key and a private EdDSA key. 1325 * Derive key material from a ECDH public key and a private EdDSA key.
1284 * Dual to #GNUNET_CRRYPTO_ecdh_eddsa. 1326 * Dual to #GNUNET_CRRYPTO_ecdh_eddsa.
@@ -1299,9 +1341,7 @@ GNUNET_CRYPTO_eddsa_ecdh (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
1299 gcry_mpi_t a; 1341 gcry_mpi_t a;
1300 gcry_ctx_t ctx; 1342 gcry_ctx_t ctx;
1301 gcry_sexp_t pub_sexpr; 1343 gcry_sexp_t pub_sexpr;
1302 gcry_mpi_t result_x; 1344 int ret;
1303 unsigned char xbuf[256 / 8];
1304 size_t rsize;
1305 1345
1306 /* first, extract the q = dP value from the public key */ 1346 /* first, extract the q = dP value from the public key */
1307 if (0 != gcry_sexp_build (&pub_sexpr, NULL, 1347 if (0 != gcry_sexp_build (&pub_sexpr, NULL,
@@ -1325,34 +1365,15 @@ GNUNET_CRYPTO_eddsa_ecdh (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
1325 gcry_mpi_point_release (q); 1365 gcry_mpi_point_release (q);
1326 gcry_mpi_release (a); 1366 gcry_mpi_release (a);
1327 1367
1328 /* finally, convert point to string for hashing */ 1368 ret = point_to_hash (result,
1329 result_x = gcry_mpi_new (256); 1369 ctx,
1330 if (gcry_mpi_ec_get_affine (result_x, NULL, result, ctx)) 1370 key_material);
1331 {
1332 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "get_affine failed", 0);
1333 gcry_mpi_point_release (result);
1334 gcry_ctx_release (ctx);
1335 return GNUNET_SYSERR;
1336 }
1337 gcry_mpi_point_release (result); 1371 gcry_mpi_point_release (result);
1338 gcry_ctx_release (ctx); 1372 gcry_ctx_release (ctx);
1339 1373 return ret;
1340 rsize = sizeof (xbuf);
1341 GNUNET_assert (! gcry_mpi_get_flag (result_x, GCRYMPI_FLAG_OPAQUE));
1342 /* result_x can be negative here, so we do not use 'GNUNET_CRYPTO_mpi_print_unsigned'
1343 as that does not include the sign bit; x should be a 255-bit
1344 value, so with the sign it should fit snugly into the 256-bit
1345 xbuf */
1346 GNUNET_assert (0 ==
1347 gcry_mpi_print (GCRYMPI_FMT_STD, xbuf, rsize, &rsize,
1348 result_x));
1349 GNUNET_CRYPTO_hash (xbuf,
1350 rsize,
1351 key_material);
1352 gcry_mpi_release (result_x);
1353 return GNUNET_OK;
1354} 1374}
1355 1375
1376
1356/** 1377/**
1357 * @ingroup crypto 1378 * @ingroup crypto
1358 * Derive key material from a ECDH public key and a private ECDSA key. 1379 * Derive key material from a ECDH public key and a private ECDSA key.
@@ -1373,9 +1394,7 @@ GNUNET_CRYPTO_ecdsa_ecdh (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
1373 gcry_mpi_t d; 1394 gcry_mpi_t d;
1374 gcry_ctx_t ctx; 1395 gcry_ctx_t ctx;
1375 gcry_sexp_t pub_sexpr; 1396 gcry_sexp_t pub_sexpr;
1376 gcry_mpi_t result_x; 1397 int ret;
1377 unsigned char xbuf[256 / 8];
1378 size_t rsize;
1379 1398
1380 /* first, extract the q = dP value from the public key */ 1399 /* first, extract the q = dP value from the public key */
1381 if (0 != gcry_sexp_build (&pub_sexpr, NULL, 1400 if (0 != gcry_sexp_build (&pub_sexpr, NULL,
@@ -1396,31 +1415,12 @@ GNUNET_CRYPTO_ecdsa_ecdh (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
1396 gcry_mpi_release (d); 1415 gcry_mpi_release (d);
1397 1416
1398 /* finally, convert point to string for hashing */ 1417 /* finally, convert point to string for hashing */
1399 result_x = gcry_mpi_new (256); 1418 ret = point_to_hash (result,
1400 if (gcry_mpi_ec_get_affine (result_x, NULL, result, ctx)) 1419 ctx,
1401 { 1420 key_material);
1402 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "get_affine failed", 0);
1403 gcry_mpi_point_release (result);
1404 gcry_ctx_release (ctx);
1405 return GNUNET_SYSERR;
1406 }
1407 gcry_mpi_point_release (result); 1421 gcry_mpi_point_release (result);
1408 gcry_ctx_release (ctx); 1422 gcry_ctx_release (ctx);
1409 1423 return ret;
1410 rsize = sizeof (xbuf);
1411 GNUNET_assert (! gcry_mpi_get_flag (result_x, GCRYMPI_FLAG_OPAQUE));
1412 /* result_x can be negative here, so we do not use 'GNUNET_CRYPTO_mpi_print_unsigned'
1413 as that does not include the sign bit; x should be a 255-bit
1414 value, so with the sign it should fit snugly into the 256-bit
1415 xbuf */
1416 GNUNET_assert (0 ==
1417 gcry_mpi_print (GCRYMPI_FMT_STD, xbuf, rsize, &rsize,
1418 result_x));
1419 GNUNET_CRYPTO_hash (xbuf,
1420 rsize,
1421 key_material);
1422 gcry_mpi_release (result_x);
1423 return GNUNET_OK;
1424} 1424}
1425 1425
1426 1426
@@ -1445,9 +1445,7 @@ GNUNET_CRYPTO_ecdh_eddsa (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
1445 gcry_mpi_t d; 1445 gcry_mpi_t d;
1446 gcry_ctx_t ctx; 1446 gcry_ctx_t ctx;
1447 gcry_sexp_t pub_sexpr; 1447 gcry_sexp_t pub_sexpr;
1448 gcry_mpi_t result_x; 1448 int ret;
1449 unsigned char xbuf[256 / 8];
1450 size_t rsize;
1451 1449
1452 /* first, extract the q = dP value from the public key */ 1450 /* first, extract the q = dP value from the public key */
1453 if (0 != gcry_sexp_build (&pub_sexpr, NULL, 1451 if (0 != gcry_sexp_build (&pub_sexpr, NULL,
@@ -1468,31 +1466,12 @@ GNUNET_CRYPTO_ecdh_eddsa (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
1468 gcry_mpi_release (d); 1466 gcry_mpi_release (d);
1469 1467
1470 /* finally, convert point to string for hashing */ 1468 /* finally, convert point to string for hashing */
1471 result_x = gcry_mpi_new (256); 1469 ret = point_to_hash (result,
1472 if (gcry_mpi_ec_get_affine (result_x, NULL, result, ctx)) 1470 ctx,
1473 { 1471 key_material);
1474 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "get_affine failed", 0);
1475 gcry_mpi_point_release (result);
1476 gcry_ctx_release (ctx);
1477 return GNUNET_SYSERR;
1478 }
1479 gcry_mpi_point_release (result); 1472 gcry_mpi_point_release (result);
1480 gcry_ctx_release (ctx); 1473 gcry_ctx_release (ctx);
1481 1474 return ret;
1482 rsize = sizeof (xbuf);
1483 GNUNET_assert (! gcry_mpi_get_flag (result_x, GCRYMPI_FLAG_OPAQUE));
1484 /* result_x can be negative here, so we do not use 'GNUNET_CRYPTO_mpi_print_unsigned'
1485 as that does not include the sign bit; x should be a 255-bit
1486 value, so with the sign it should fit snugly into the 256-bit
1487 xbuf */
1488 GNUNET_assert (0 ==
1489 gcry_mpi_print (GCRYMPI_FMT_STD, xbuf, rsize, &rsize,
1490 result_x));
1491 GNUNET_CRYPTO_hash (xbuf,
1492 rsize,
1493 key_material);
1494 gcry_mpi_release (result_x);
1495 return GNUNET_OK;
1496} 1475}
1497 1476
1498/** 1477/**