forked from pool/openssh
e8b9919265
- Fix preauth seccomp separation on mainframes (bsc#1016709) [openssh-7.2p2-s390_hw_crypto_syscalls.patch] [openssh-7.2p2-s390_OpenSSL-ibmpkcs11_syscalls.patch] - enable case-insensitive hostname matching (bsc#1017099) [openssh-7.2p2-ssh_case_insensitive_host_matching.patch] - add CAVS tests [openssh-7.2p2-cavstest-ctr.patch] [openssh-7.2p2-cavstest-kdf.patch] - Adding missing pieces for user matching (bsc#1021626) - Properly verify CIDR masks in configuration (bsc#1005893) [openssh-7.2p2-verify_CIDR_address_ranges.patch] - Remove pre-auth compression support from the server to prevent possible cryptographic attacks. (CVE-2016-10012, bsc#1016370) [openssh-7.2p2-disable_preauth_compression.patch] - limit directories for loading PKCS11 modules (CVE-2016-10009, bsc#1016366) [openssh-7.2p2-restrict_pkcs11-modules.patch] - Prevent possible leaks of host private keys to low-privilege process handling authentication (CVE-2016-10011, bsc#1016369) [openssh-7.2p2-prevent_private_key_leakage.patch] - Do not allow unix socket forwarding when running without privilege separation (CVE-2016-10010, bsc#1016368) [openssh-7.2p2-secure_unix_sockets_forwarding.patch] - prevent resource depletion during key exchange (bsc#1005480, CVE-2016-8858) [openssh-7.2p2-kex_resource_depletion.patch] OBS-URL: https://build.opensuse.org/request/show/500279 OBS-URL: https://build.opensuse.org/package/show/network/openssh?expand=0&rev=117
470 lines
15 KiB
Diff
470 lines
15 KiB
Diff
# HG changeset patch
|
|
# Parent f9ffcfb88e5a9d611a61aee3571050dea67e363e
|
|
CAVS test for KDF implementation in OpenSSH
|
|
|
|
diff --git a/openssh-7.2p2/Makefile.in b/openssh-7.2p2/Makefile.in
|
|
--- a/openssh-7.2p2/Makefile.in
|
|
+++ b/openssh-7.2p2/Makefile.in
|
|
@@ -22,16 +22,17 @@ top_srcdir=@top_srcdir@
|
|
DESTDIR=
|
|
VPATH=@srcdir@
|
|
SSH_PROGRAM=@bindir@/ssh
|
|
ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass
|
|
SFTP_SERVER=$(libexecdir)/sftp-server
|
|
SSH_KEYSIGN=$(libexecdir)/ssh-keysign
|
|
SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper
|
|
CAVSTEST_CTR=$(libexecdir)/cavstest-ctr
|
|
+CAVSTEST_KDF=$(libexecdir)/cavstest-kdf
|
|
PRIVSEP_PATH=@PRIVSEP_PATH@
|
|
SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@
|
|
STRIP_OPT=@STRIP_OPT@
|
|
TEST_SHELL=@TEST_SHELL@
|
|
|
|
PATHS= -DSSHDIR=\"$(sysconfdir)\" \
|
|
-D_PATH_SSH_PROGRAM=\"$(SSH_PROGRAM)\" \
|
|
-D_PATH_SSH_ASKPASS_DEFAULT=\"$(ASKPASS_PROGRAM)\" \
|
|
@@ -60,17 +61,17 @@ SED=@SED@
|
|
ENT=@ENT@
|
|
XAUTH_PATH=@XAUTH_PATH@
|
|
LDFLAGS=-L. -Lopenbsd-compat/ @LDFLAGS@
|
|
EXEEXT=@EXEEXT@
|
|
MANFMT=@MANFMT@
|
|
|
|
TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT)
|
|
|
|
-TARGETS += cavstest-ctr$(EXEEXT)
|
|
+TARGETS += cavstest-ctr$(EXEEXT) cavstest-kdf$(EXEEXT)
|
|
|
|
LIBOPENSSH_OBJS=\
|
|
ssh_api.o \
|
|
ssherr.o \
|
|
sshbuf.o \
|
|
sshkey.o \
|
|
sshbuf-getput-basic.o \
|
|
sshbuf-misc.o \
|
|
@@ -197,16 +198,19 @@ sftp-server$(EXEEXT): $(LIBCOMPAT) libss
|
|
|
|
sftp$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-client.o sftp-common.o sftp-glob.o progressmeter.o
|
|
$(LD) -o $@ progressmeter.o sftp.o sftp-client.o sftp-common.o sftp-glob.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(LIBEDIT)
|
|
|
|
# FIPS tests
|
|
cavstest-ctr$(EXEEXT): $(LIBCOMPAT) libssh.a cavstest-ctr.o
|
|
$(LD) -o $@ cavstest-ctr.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
|
|
|
|
+cavstest-kdf$(EXEEXT): $(LIBCOMPAT) libssh.a cavstest-kdf.o
|
|
+ $(LD) -o $@ cavstest-kdf.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
|
|
+
|
|
# test driver for the loginrec code - not built by default
|
|
logintest: logintest.o $(LIBCOMPAT) libssh.a loginrec.o
|
|
$(LD) -o $@ logintest.o $(LDFLAGS) loginrec.o -lopenbsd-compat -lssh $(LIBS)
|
|
|
|
$(MANPAGES): $(MANPAGES_IN)
|
|
if test "$(MANTYPE)" = "cat"; then \
|
|
manpage=$(srcdir)/`echo $@ | sed 's/\.[1-9]\.out$$/\.0/'`; \
|
|
else \
|
|
@@ -318,16 +322,17 @@ install-files:
|
|
$(INSTALL) -m 0755 $(STRIP_OPT) ssh-keygen$(EXEEXT) $(DESTDIR)$(bindir)/ssh-keygen$(EXEEXT)
|
|
$(INSTALL) -m 0755 $(STRIP_OPT) ssh-keyscan$(EXEEXT) $(DESTDIR)$(bindir)/ssh-keyscan$(EXEEXT)
|
|
$(INSTALL) -m 0755 $(STRIP_OPT) sshd$(EXEEXT) $(DESTDIR)$(sbindir)/sshd$(EXEEXT)
|
|
$(INSTALL) -m 4711 $(STRIP_OPT) ssh-keysign$(EXEEXT) $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT)
|
|
$(INSTALL) -m 0755 $(STRIP_OPT) ssh-pkcs11-helper$(EXEEXT) $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT)
|
|
$(INSTALL) -m 0755 $(STRIP_OPT) sftp$(EXEEXT) $(DESTDIR)$(bindir)/sftp$(EXEEXT)
|
|
$(INSTALL) -m 0755 $(STRIP_OPT) sftp-server$(EXEEXT) $(DESTDIR)$(SFTP_SERVER)$(EXEEXT)
|
|
$(INSTALL) -m 0755 $(STRIP_OPT) cavstest-ctr$(EXEEXT) $(DESTDIR)$(libexecdir)/cavstest-ctr$(EXEEXT)
|
|
+ $(INSTALL) -m 0755 $(STRIP_OPT) cavstest-kdf$(EXEEXT) $(DESTDIR)$(libexecdir)/cavstest-kdf$(EXEEXT)
|
|
$(INSTALL) -m 644 ssh.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1
|
|
$(INSTALL) -m 644 scp.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1
|
|
$(INSTALL) -m 644 ssh-add.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1
|
|
$(INSTALL) -m 644 ssh-agent.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-agent.1
|
|
$(INSTALL) -m 644 ssh-keygen.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keygen.1
|
|
$(INSTALL) -m 644 ssh-keyscan.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keyscan.1
|
|
$(INSTALL) -m 644 moduli.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/moduli.5
|
|
$(INSTALL) -m 644 sshd_config.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/sshd_config.5
|
|
diff --git a/openssh-7.2p2/cavstest-kdf.c b/openssh-7.2p2/cavstest-kdf.c
|
|
new file mode 100644
|
|
--- /dev/null
|
|
+++ b/openssh-7.2p2/cavstest-kdf.c
|
|
@@ -0,0 +1,382 @@
|
|
+/*
|
|
+ * Copyright (C) 2015, Stephan Mueller <smueller@chronox.de>
|
|
+ *
|
|
+ * Redistribution and use in source and binary forms, with or without
|
|
+ * modification, are permitted provided that the following conditions
|
|
+ * are met:
|
|
+ * 1. Redistributions of source code must retain the above copyright
|
|
+ * notice, and the entire permission notice in its entirety,
|
|
+ * including the disclaimer of warranties.
|
|
+ * 2. Redistributions in binary form must reproduce the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer in the
|
|
+ * documentation and/or other materials provided with the distribution.
|
|
+ * 3. The name of the author may not be used to endorse or promote
|
|
+ * products derived from this software without specific prior
|
|
+ * written permission.
|
|
+ *
|
|
+ * ALTERNATIVELY, this product may be distributed under the terms of
|
|
+ * the GNU General Public License, in which case the provisions of the GPL2
|
|
+ * are required INSTEAD OF the above restrictions. (This clause is
|
|
+ * necessary due to a potential bad interaction between the GPL and
|
|
+ * the restrictions contained in a BSD-style copyright.)
|
|
+ *
|
|
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
|
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
|
|
+ * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
|
|
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
|
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
|
+ * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
|
|
+ * DAMAGE.
|
|
+ */
|
|
+
|
|
+#include "includes.h"
|
|
+
|
|
+#include <stdio.h>
|
|
+#include <stdlib.h>
|
|
+#include <errno.h>
|
|
+#include <sys/types.h>
|
|
+#include <string.h>
|
|
+
|
|
+#include <openssl/bn.h>
|
|
+
|
|
+#include "xmalloc.h"
|
|
+#include "buffer.h"
|
|
+#include "key.h"
|
|
+#include "cipher.h"
|
|
+#include "kex.h"
|
|
+#include "packet.h"
|
|
+
|
|
+static int bin_char(unsigned char hex)
|
|
+{
|
|
+ if (48 <= hex && 57 >= hex)
|
|
+ return (hex - 48);
|
|
+ if (65 <= hex && 70 >= hex)
|
|
+ return (hex - 55);
|
|
+ if (97 <= hex && 102 >= hex)
|
|
+ return (hex - 87);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Convert hex representation into binary string
|
|
+ * @hex input buffer with hex representation
|
|
+ * @hexlen length of hex
|
|
+ * @bin output buffer with binary data
|
|
+ * @binlen length of already allocated bin buffer (should be at least
|
|
+ * half of hexlen -- if not, only a fraction of hexlen is converted)
|
|
+ */
|
|
+static void hex2bin(const char *hex, size_t hexlen,
|
|
+ unsigned char *bin, size_t binlen)
|
|
+{
|
|
+ size_t i = 0;
|
|
+ size_t chars = (binlen > (hexlen / 2)) ? (hexlen / 2) : binlen;
|
|
+
|
|
+ for (i = 0; i < chars; i++) {
|
|
+ bin[i] = bin_char(hex[(i*2)]) << 4;
|
|
+ bin[i] |= bin_char(hex[((i*2)+1)]);
|
|
+ }
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Allocate sufficient space for binary representation of hex
|
|
+ * and convert hex into bin
|
|
+ *
|
|
+ * Caller must free bin
|
|
+ * @hex input buffer with hex representation
|
|
+ * @hexlen length of hex
|
|
+ * @bin return value holding the pointer to the newly allocated buffer
|
|
+ * @binlen return value holding the allocated size of bin
|
|
+ *
|
|
+ * return: 0 on success, !0 otherwise
|
|
+ */
|
|
+static int hex2bin_alloc(const char *hex, size_t hexlen,
|
|
+ unsigned char **bin, size_t *binlen)
|
|
+{
|
|
+ unsigned char *out = NULL;
|
|
+ size_t outlen = 0;
|
|
+
|
|
+ if (!hexlen)
|
|
+ return -EINVAL;
|
|
+
|
|
+ outlen = (hexlen + 1) / 2;
|
|
+
|
|
+ out = calloc(1, outlen);
|
|
+ if (!out)
|
|
+ return -errno;
|
|
+
|
|
+ hex2bin(hex, hexlen, out, outlen);
|
|
+ *bin = out;
|
|
+ *binlen = outlen;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static char hex_char_map_l[] = { '0', '1', '2', '3', '4', '5', '6', '7',
|
|
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
|
|
+static char hex_char_map_u[] = { '0', '1', '2', '3', '4', '5', '6', '7',
|
|
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
|
|
+static char hex_char(unsigned int bin, int u)
|
|
+{
|
|
+ if (bin < sizeof(hex_char_map_l))
|
|
+ return (u) ? hex_char_map_u[bin] : hex_char_map_l[bin];
|
|
+ return 'X';
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Convert binary string into hex representation
|
|
+ * @bin input buffer with binary data
|
|
+ * @binlen length of bin
|
|
+ * @hex output buffer to store hex data
|
|
+ * @hexlen length of already allocated hex buffer (should be at least
|
|
+ * twice binlen -- if not, only a fraction of binlen is converted)
|
|
+ * @u case of hex characters (0=>lower case, 1=>upper case)
|
|
+ */
|
|
+static void bin2hex(const unsigned char *bin, size_t binlen,
|
|
+ char *hex, size_t hexlen, int u)
|
|
+{
|
|
+ size_t i = 0;
|
|
+ size_t chars = (binlen > (hexlen / 2)) ? (hexlen / 2) : binlen;
|
|
+
|
|
+ for (i = 0; i < chars; i++) {
|
|
+ hex[(i*2)] = hex_char((bin[i] >> 4), u);
|
|
+ hex[((i*2)+1)] = hex_char((bin[i] & 0x0f), u);
|
|
+ }
|
|
+}
|
|
+
|
|
+struct kdf_cavs {
|
|
+ unsigned char *K;
|
|
+ size_t Klen;
|
|
+ unsigned char *H;
|
|
+ size_t Hlen;
|
|
+ unsigned char *session_id;
|
|
+ size_t session_id_len;
|
|
+
|
|
+ unsigned int iv_len;
|
|
+ unsigned int ek_len;
|
|
+ unsigned int ik_len;
|
|
+};
|
|
+
|
|
+static int sshkdf_cavs(struct kdf_cavs *test)
|
|
+{
|
|
+ int ret = 0;
|
|
+ struct kex kex;
|
|
+ struct ssh ssh;
|
|
+ BIGNUM *Kbn = NULL;
|
|
+ int mode = 0;
|
|
+ struct newkeys *keys_client;
|
|
+ struct newkeys *keys_server;
|
|
+
|
|
+#define HEXOUTLEN 500
|
|
+ char hex[HEXOUTLEN];
|
|
+
|
|
+ memset(&ssh, 0, sizeof(struct ssh));
|
|
+ memset(&kex, 0, sizeof(struct kex));
|
|
+ ssh.kex = &kex;
|
|
+
|
|
+ Kbn = BN_new();
|
|
+ BN_bin2bn(test->K, test->Klen, Kbn);
|
|
+ if (!Kbn) {
|
|
+ printf("cannot convert K into BIGNUM\n");
|
|
+ ret = 1;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ kex.session_id = test->session_id;
|
|
+ kex.session_id_len = test->session_id_len;
|
|
+
|
|
+ /* setup kex */
|
|
+
|
|
+ /* select the right hash based on struct ssh_digest digests */
|
|
+ switch (test->ik_len) {
|
|
+ case 20:
|
|
+ kex.hash_alg = 2;
|
|
+ break;
|
|
+ case 32:
|
|
+ kex.hash_alg = 3;
|
|
+ break;
|
|
+ case 48:
|
|
+ kex.hash_alg = 4;
|
|
+ break;
|
|
+ case 64:
|
|
+ kex.hash_alg = 5;
|
|
+ break;
|
|
+ default:
|
|
+ printf("Wrong hash type %u\n", test->ik_len);
|
|
+ ret = 1;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ /* implement choose_enc */
|
|
+ for (mode = 0; mode < 2; mode++) {
|
|
+ kex.newkeys[mode] = calloc(1, sizeof(struct newkeys));
|
|
+ if (!kex.newkeys[mode]) {
|
|
+ printf("allocation of newkeys failed\n");
|
|
+ ret = 1;
|
|
+ goto out;
|
|
+ }
|
|
+ kex.newkeys[mode]->enc.iv_len = test->iv_len;
|
|
+ kex.newkeys[mode]->enc.key_len = test->ek_len;
|
|
+ kex.newkeys[mode]->enc.block_size = (test->iv_len == 64) ? 8 : 16;
|
|
+ kex.newkeys[mode]->mac.key_len = test->ik_len;
|
|
+ }
|
|
+
|
|
+ /* implement kex_choose_conf */
|
|
+ kex.we_need = kex.newkeys[0]->enc.key_len;
|
|
+ if (kex.we_need < kex.newkeys[0]->enc.block_size)
|
|
+ kex.we_need = kex.newkeys[0]->enc.block_size;
|
|
+ if (kex.we_need < kex.newkeys[0]->enc.iv_len)
|
|
+ kex.we_need = kex.newkeys[0]->enc.iv_len;
|
|
+ if (kex.we_need < kex.newkeys[0]->mac.key_len)
|
|
+ kex.we_need = kex.newkeys[0]->mac.key_len;
|
|
+
|
|
+ /* MODE_OUT (1) -> server to client
|
|
+ * MODE_IN (0) -> client to server */
|
|
+ kex.server = 1;
|
|
+
|
|
+ /* do it */
|
|
+ kex_derive_keys_bn(&ssh, test->H, test->Hlen, Kbn);
|
|
+
|
|
+ keys_client = ssh.kex->newkeys[0];
|
|
+ keys_server = ssh.kex->newkeys[1];
|
|
+
|
|
+ /* get data */
|
|
+ memset(hex, 0, HEXOUTLEN);
|
|
+ bin2hex(keys_client->enc.iv, (size_t)keys_client->enc.iv_len,
|
|
+ hex, HEXOUTLEN, 0);
|
|
+ printf("Initial IV (client to server) = %s\n", hex);
|
|
+
|
|
+ memset(hex, 0, HEXOUTLEN);
|
|
+ bin2hex(keys_server->enc.iv, (size_t)keys_server->enc.iv_len,
|
|
+ hex, HEXOUTLEN, 0);
|
|
+ printf("Initial IV (server to client) = %s\n", hex);
|
|
+
|
|
+ memset(hex, 0, HEXOUTLEN);
|
|
+ bin2hex(keys_client->enc.key, (size_t)keys_client->enc.key_len,
|
|
+ hex, HEXOUTLEN, 0);
|
|
+ printf("Encryption key (client to server) = %s\n", hex);
|
|
+
|
|
+ memset(hex, 0, HEXOUTLEN);
|
|
+ bin2hex(keys_server->enc.key, (size_t)keys_server->enc.key_len,
|
|
+ hex, HEXOUTLEN, 0);
|
|
+ printf("Encryption key (server to client) = %s\n", hex);
|
|
+
|
|
+ memset(hex, 0, HEXOUTLEN);
|
|
+ bin2hex(keys_client->mac.key, (size_t)keys_client->mac.key_len,
|
|
+ hex, HEXOUTLEN, 0);
|
|
+ printf("Integrity key (client to server) = %s\n", hex);
|
|
+
|
|
+ memset(hex, 0, HEXOUTLEN);
|
|
+ bin2hex(keys_server->mac.key, (size_t)keys_server->mac.key_len,
|
|
+ hex, HEXOUTLEN, 0);
|
|
+ printf("Integrity key (server to client) = %s\n", hex);
|
|
+
|
|
+ free(keys_client);
|
|
+ free(keys_server);
|
|
+
|
|
+out:
|
|
+ if (Kbn)
|
|
+ BN_free(Kbn);
|
|
+ if (kex.newkeys[0])
|
|
+ free(kex.newkeys[0]);
|
|
+ if (kex.newkeys[1])
|
|
+ free(kex.newkeys[1]);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static void usage(void)
|
|
+{
|
|
+ fprintf(stderr, "\nOpenSSH KDF CAVS Test\n\n");
|
|
+ fprintf(stderr, "Usage:\n");
|
|
+ fprintf(stderr, "\t-K\tShared secret string\n");
|
|
+ fprintf(stderr, "\t-H\tHash string\n");
|
|
+ fprintf(stderr, "\t-s\tSession ID string\n");
|
|
+ fprintf(stderr, "\t-i\tIV length to be generated\n");
|
|
+ fprintf(stderr, "\t-e\tEncryption key length to be generated\n");
|
|
+ fprintf(stderr, "\t-m\tMAC key length to be generated\n");
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Test command example:
|
|
+ * ./ssh-cavs -K 0055d50f2d163cc07cd8a93cc7c3430c30ce786b572c01ad29fec7597000cf8618d664e2ec3dcbc8bb7a1a7eb7ef67f61cdaf291625da879186ac0a5cb27af571b59612d6a6e0627344d846271959fda61c78354aa498773d59762f8ca2d0215ec590d8633de921f920d41e47b3de6ab9a3d0869e1c826d0e4adebf8e3fb646a15dea20a410b44e969f4b791ed6a67f13f1b74234004d5fa5e87eff7abc32d49bbdf44d7b0107e8f10609233b7e2b7eff74a4daf25641de7553975dac6ac1e5117df6f6dbaa1c263d23a6c3e5a3d7d49ae8a828c1e333ac3f85fbbf57b5c1a45be45e43a7be1a4707eac779b8285522d1f531fe23f890fd38a004339932b93eda4 -H d3ab91a850febb417a25d892ec48ed5952c7a5de -s d3ab91a850febb417a25d892ec48ed5952c7a5de -i 8 -e 24 -m 20
|
|
+ *
|
|
+ * Expected result for example:
|
|
+ * Initial IV (client to server) = 4bb320d1679dfd3a
|
|
+ * Encryption key (client to server) = 13048cc600b9d3cf9095aa6cf8e2ff9cf1c54ca0520c89ed
|
|
+ * Integrity key (client to server) = ecef63a092b0dcc585bdc757e01b2740af57d640
|
|
+ * Initial IV (server to client) = 43dea6fdf263a308
|
|
+ * Encryption key (server to client) = 1e483c5134e901aa11fc4e0a524e7ec7b75556148a222bb0
|
|
+ * Integrity key (server to client) = 7424b05f3c44a72b4ebd281fb71f9cbe7b64d479
|
|
+ */
|
|
+int main(int argc, char *argv[])
|
|
+{
|
|
+ struct kdf_cavs test;
|
|
+ int ret = 1;
|
|
+ int opt = 0;
|
|
+
|
|
+ memset(&test, 0, sizeof(struct kdf_cavs));
|
|
+ while((opt = getopt(argc, argv, "K:H:s:i:e:m:")) != -1)
|
|
+ {
|
|
+ size_t len = 0;
|
|
+ switch(opt)
|
|
+ {
|
|
+ /*
|
|
+ * CAVS K is MPINT
|
|
+ * we want a hex (i.e. the caller must ensure the
|
|
+ * following transformations already happened):
|
|
+ * 1. cut off first four bytes
|
|
+ * 2. if most significant bit of value is
|
|
+ * 1, prepend 0 byte
|
|
+ */
|
|
+ case 'K':
|
|
+ len = strlen(optarg);
|
|
+ ret = hex2bin_alloc(optarg, len,
|
|
+ &test.K, &test.Klen);
|
|
+ if (ret)
|
|
+ goto out;
|
|
+ break;
|
|
+ case 'H':
|
|
+ len = strlen(optarg);
|
|
+ ret = hex2bin_alloc(optarg, len,
|
|
+ &test.H, &test.Hlen);
|
|
+ if (ret)
|
|
+ goto out;
|
|
+ break;
|
|
+ case 's':
|
|
+ len = strlen(optarg);
|
|
+ ret = hex2bin_alloc(optarg, len,
|
|
+ &test.session_id,
|
|
+ &test.session_id_len);
|
|
+ if (ret)
|
|
+ goto out;
|
|
+ break;
|
|
+ case 'i':
|
|
+ test.iv_len = strtoul(optarg, NULL, 10);
|
|
+ break;
|
|
+ case 'e':
|
|
+ test.ek_len = strtoul(optarg, NULL, 10);
|
|
+ break;
|
|
+ case 'm':
|
|
+ test.ik_len = strtoul(optarg, NULL, 10);
|
|
+ break;
|
|
+ default:
|
|
+ usage();
|
|
+ goto out;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ ret = sshkdf_cavs(&test);
|
|
+
|
|
+out:
|
|
+ if (test.session_id)
|
|
+ free(test.session_id);
|
|
+ if (test.K)
|
|
+ free(test.K);
|
|
+ if (test.H)
|
|
+ free(test.H);
|
|
+ return ret;
|
|
+
|
|
+}
|