Skip to content

Commit

Permalink
Adding EDDSA files and test suite.
Browse files Browse the repository at this point in the history
  • Loading branch information
Rishabh-Kumar-07 committed Aug 20, 2021
1 parent 5c2d018 commit 48a8dc0
Show file tree
Hide file tree
Showing 15 changed files with 417 additions and 1 deletion.
2 changes: 2 additions & 0 deletions include/crypt_hash.h
Expand Up @@ -63,6 +63,8 @@ void crypt_hash_final_bytes(struct crypt_hash **hashp,

struct crypt_mac crypt_hash_final_mac(struct crypt_hash **hashp);

void crypt_mac_load(struct crypt_mac *container, chunk_t packet);



/*
Expand Down
2 changes: 1 addition & 1 deletion include/crypt_mac.h
Expand Up @@ -36,7 +36,7 @@ struct crypt_mac {
/* size of the mac in bytes */
size_t len;
/* XXX: see note above about why this is called .ptr */
uint8_t ptr[64/*see ike_alg_init() for size check*/];
uint8_t ptr[2048/*see ike_alg_init() for size check*/];
};

extern const struct crypt_mac empty_mac;
Expand Down
8 changes: 8 additions & 0 deletions lib/libswan/crypt_hash.c
Expand Up @@ -105,6 +105,14 @@ void crypt_hash_final_bytes(struct crypt_hash **hashp,
*hashp = hash = NULL;
}

void crypt_mac_load(struct crypt_mac *container, chunk_t packet){
for(size_t i = 0; i < packet.len; i++){
(container->y)[i + container->len] = (packet.ptr)[i];
}
container->len += packet.len;
}


struct crypt_mac crypt_hash_final_mac(struct crypt_hash **hashp)
{
struct crypt_hash *hash = *hashp;
Expand Down
16 changes: 16 additions & 0 deletions programs/pluto/ikev2_auth.c
Expand Up @@ -109,6 +109,22 @@ struct crypt_mac v2_calculate_sighash(const struct ike_sa *ike,
}
}

if(streq(hasher->common.fqn, "IDENTITY_HASH")){
int size_hash = firstpacket.len + (*nonce).len;
if (ike->sa.st_v2_ike_intermediate_used) {
size_hash += (ia1.len + ia2.len);
}
struct crypt_mac calc_hash;
calc_hash.len = 0;
crypt_mac_load(&calc_hash, firstpacket);
crypt_mac_load(&calc_hash, *nonce);
if (ike->sa.st_v2_ike_intermediate_used) {
crypt_mac_load(&calc_hash, ia1);
crypt_mac_load(&calc_hash, ia2);
}
return calc_hash;
}

struct crypt_hash *ctx = crypt_hash_init("sighash", hasher,
ike->sa.st_logger);
crypt_hash_digest_hunk(ctx, "first packet", firstpacket);
Expand Down
186 changes: 186 additions & 0 deletions programs/pluto/ikev2_eddsa.c
@@ -0,0 +1,186 @@
/* do EDDSA operations for IKEv2
*
* Copyright (C) 2018 Sahana Prasad <sahana.prasad07@gmail.com>
* Copyright (C) 2018 Paul Wouters <pwouters@redhat.com>
* Copyright (C) 2019 Andrew Cagney <cagney@gnu.org>
* Copyright (C) 2019 D. Hugh Redelmeier <hugh@mimosa.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <https://www.gnu.org/licenses/gpl2.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
*/

#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "secitem.h"
#include "cryptohi.h"
#include "keyhi.h"


#include "sysdep.h"
#include "constants.h"

#include "defs.h"
#include "id.h"
#include "x509.h"
#include "certs.h"
#include "connections.h" /* needs id.h */
#include "state.h"
#include "packet.h"
#include "crypto.h"
#include "ike_alg.h"
#include "ike_alg_hash.h"
#include "log.h"
#include "demux.h" /* needs packet.h */
#include "ikev2.h"
#include "server.h"
#include "vendor.h"
#include "keys.h"
#include "secrets.h"
#include "crypt_hash.h"
#include "ietf_constants.h"
#include "asn1.h"
#include "lswnss.h"
#include "ikev2_auth.h"

static authsig_using_pubkey_fn authsig_using_EDDSA_ikev2_pubkey; /* type assert */

bool authsig_using_EDDSA_ikev2_pubkey(const struct crypt_mac *hash, shunk_t signature,
struct pubkey *kr,
const struct hash_desc *unused_hash_algo UNUSED,
diag_t *fatal_diag,
struct logger *logger)
{
PRArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) {
*fatal_diag = diag_nss_error("allocating EDDSA arena");
return false;
}

/*
* convert K(R) into a public key
*/

/* allocate the pubkey */
const struct EC_public_key *k = &kr->u.ecPub;
SECKEYPublicKey *publicKey = (SECKEYPublicKey *)
PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey));
if (publicKey == NULL) {
*fatal_diag = diag_nss_error("allocating EDDSA pubkey arena");
PORT_FreeArena(arena, PR_FALSE);
return false;
}

publicKey->arena = arena;
publicKey->keyType = ecKey;
publicKey->pkcs11Slot = NULL;
publicKey->pkcs11ID = CK_INVALID_HANDLE;

/*
* Copy k and ec params into the arena / publicKey.
*/

SECItem k_pub = same_chunk_as_secitem(k->pub, siBuffer);
if (SECITEM_CopyItem(arena, &publicKey->u.ec.publicValue, &k_pub) != SECSuccess) {
*fatal_diag = diag_nss_error("copying 'k' to EDDSA public key");
PORT_FreeArena(arena, PR_FALSE);
return false;
}

SECItem k_ecParams = same_chunk_as_secitem(k->ecParams, siBuffer);
if (SECITEM_CopyItem(arena, &publicKey->u.ec.DEREncodedParams, &k_ecParams) != SECSuccess) {
*fatal_diag = diag_nss_error("copying ecParams to EDDSA public key");
PORT_FreeArena(arena, PR_FALSE);
return false;
}

/*
* Convert the signature into raw form (NSS doesn't do const).
*/
SECItem der_signature = {
.type = siBuffer,
.data = DISCARD_CONST(unsigned char *, signature.ptr),/*NSS doesn't do const*/
.len = signature.len
};
LSWDBGP(DBG_BASE, buf) {
jam(buf, "%d-byte DER encoded EDDSA signature: ",
der_signature.len);
jam_nss_secitem(buf, &der_signature);
}

SECItem *raw_signature = DSAU_DecodeDerSigToLen(&der_signature,
SECKEY_SignatureLen(publicKey));
if (raw_signature == NULL) {
/* not fatal as dependent on key being tried */
llog_nss_error(DEBUG_STREAM, logger,
"unpacking DER encoded EDDSA signature using DSAU_DecodeDerSigToLen()");
PORT_FreeArena(arena, PR_FALSE);
*fatal_diag = NULL;
return false;
}

LSWDBGP(DBG_BASE, buf) {
jam(buf, "%d-byte raw EDDSA signature: ",
raw_signature->len);
jam_nss_secitem(buf, raw_signature);
}

/*
* put the hash somewhere writable; so it can later be logged?
*
* XXX: cast away const?
*/
struct crypt_mac hash_data = *hash;
SECItem hash_item = {
.type = siBuffer,
.data = hash_data.ptr,
.len = hash_data.len,
};

if (PK11_Verify(publicKey, raw_signature, &hash_item,
lsw_nss_get_password_context(logger)) != SECSuccess) {
llog_nss_error(DEBUG_STREAM, logger,
"verifying AUTH hash using PK11_Verify() failed:");
PORT_FreeArena(arena, PR_FALSE);
SECITEM_FreeItem(raw_signature, PR_TRUE);
*fatal_diag = NULL;
return false;
}

dbg("NSS: verified signature");
SECITEM_FreeItem(raw_signature, PR_TRUE);

*fatal_diag = NULL;
return true;
}

diag_t v2_authsig_and_log_using_EDDSA_pubkey(struct ike_sa *ike,
const struct crypt_mac *idhash,
shunk_t signature,
const struct hash_desc *hash_algo)
{
statetime_t start = statetime_start(&ike->sa);

if (hash_algo->common.ikev2_alg_id < 0) {
return diag("authentication failed: unknown or unsupported hash algorithm");
}

struct crypt_mac calc_hash = v2_calculate_sighash(ike, idhash, hash_algo,
REMOTE_PERSPECTIVE);
diag_t d = authsig_and_log_using_pubkey(ike, &calc_hash, signature, hash_algo,
&pubkey_type_eddsa,
authsig_using_EDDSA_ikev2_pubkey);
statetime_stop(&start, "%s()", __func__);
return d;
}
4 changes: 4 additions & 0 deletions testing/pluto/ikev2-x509-eddsa-01/description.txt
@@ -0,0 +1,4 @@
IKEv2 EDDSA certificate based authentication

Test for leaks as well

21 changes: 21 additions & 0 deletions testing/pluto/ikev2-x509-eddsa-01/east.conf
@@ -0,0 +1,21 @@
# /etc/ipsec.conf - Libreswan IPsec configuration file

config setup
# put the logs in /tmp for the UMLs, so that we can operate
# without syslogd, which seems to break on UMLs
logfile=/tmp/pluto.log
logtime=no
logappend=no
plutodebug=all
dumpdir=/tmp

conn westnet-eastnet-ikev2
left=192.1.2.45
leftid="C=CH, O=strongSwan, CN=strongWest"
leftsubnet=192.0.1.0/24
right=192.1.2.23
rightcert=strongEastEd25519
rightid="C=CH, O=strongSwan, CN=strongEast"
rightsubnet=192.0.2.0/24
authby=eddsa
rightsendcert=always
28 changes: 28 additions & 0 deletions testing/pluto/ikev2-x509-eddsa-01/east.console.txt
@@ -0,0 +1,28 @@
/testing/guestbin/swan-prep
east #
PATH/bin/pk12util -i /testing/x509/strongswan/strongEast.p12 -d sql:/etc/ipsec.d -w /testing/x509/nss-pw
pk12util: PKCS12 IMPORT SUCCESSFUL
east #
# Tuomo: why doesn't ipsec checknss --settrust work here?
east #
certutil -M -d sql:/etc/ipsec.d -n "strongSwan CA - strongSwan" -t CT,,
east #
#ipsec start
east #
ipsec _stackmanager start
east #
ipsec pluto --config /etc/ipsec.conf --leak-detective
east #
../../guestbin/wait-until-pluto-started
east #
ipsec auto --add westnet-eastnet-ikev2
002 "westnet-eastnet-ikev2": added IKEv2 connection
east #
ipsec whack --impair suppress-retransmits
east #
echo "initdone"
initdone
east #
ipsec whack --shutdown
east #

11 changes: 11 additions & 0 deletions testing/pluto/ikev2-x509-eddsa-01/eastinit.sh
@@ -0,0 +1,11 @@
/testing/guestbin/swan-prep
/usr/bin/pk12util -i /testing/x509/strongswan/strongEastEd25519.p12 -d sql:/etc/ipsec.d -w /testing/x509/nss-pw
# Tuomo: why doesn't ipsec checknss --settrust work here?
certutil -M -d sql:/etc/ipsec.d -n "strongSwan CA - strongSwan" -t CT,,
#ipsec start
ipsec _stackmanager start
ipsec pluto --config /etc/ipsec.conf --leak-detective
../../guestbin/wait-until-pluto-started
ipsec auto --add westnet-eastnet-ikev2
ipsec whack --impair suppress-retransmits
echo "initdone"
1 change: 1 addition & 0 deletions testing/pluto/ikev2-x509-eddsa-01/final.sh
@@ -0,0 +1 @@
ipsec whack --shutdown
21 changes: 21 additions & 0 deletions testing/pluto/ikev2-x509-eddsa-01/west.conf
@@ -0,0 +1,21 @@
# /etc/ipsec.conf - Libreswan IPsec configuration file

config setup
# put the logs in /tmp for the UMLs, so that we can operate
# without syslogd, which seems to break on UMLs
logfile=/tmp/pluto.log
logtime=no
logappend=no
plutodebug=all
dumpdir=/tmp

conn westnet-eastnet-ikev2
left=192.1.2.45
leftsubnet=192.0.1.0/24
leftid="C=CH, O=strongSwan, CN=strongWest"
leftcert=strongWestEd25519
leftsendcert=always
right=192.1.2.23
rightsubnet=192.0.2.0/24
rightid="C=CH, O=strongSwan, CN=strongEast"
authby=ecdsa-sha2_384

0 comments on commit 48a8dc0

Please sign in to comment.