Please include the commit from fedora for these files. Also, I like how the cavs were packaged. An additional test should be added to the ptest if the cavs are installed.
--Mark On 9/22/19 9:57 AM, Hongxu Jia wrote: > Refer the latest Fedora to add cavs test binary for the aes-ctr [1] > and SSH KDF CAVS test driver [2] > > [1] > http://pkgs.fedoraproject.org/cgit/rpms/openssh.git/plain/openssh-6.6p1-ctr-cavstest.patch > [2] > http://pkgs.fedoraproject.org/cgit/rpms/openssh.git/plain/openssh-6.7p1-kdf-cavs.patch > > Signed-off-by: Hongxu Jia <hongxu....@windriver.com> > --- > .../openssh/openssh-6.6p1-ctr-cavstest.patch | 289 +++++++++ > .../openssh/openssh/openssh-6.7p1-kdf-cavs.patch | 654 > +++++++++++++++++++++ > recipes-connectivity/openssh/openssh_fips.inc | 9 + > 3 files changed, 952 insertions(+) > create mode 100644 > recipes-connectivity/openssh/openssh/openssh-6.6p1-ctr-cavstest.patch > create mode 100644 > recipes-connectivity/openssh/openssh/openssh-6.7p1-kdf-cavs.patch > > diff --git > a/recipes-connectivity/openssh/openssh/openssh-6.6p1-ctr-cavstest.patch > b/recipes-connectivity/openssh/openssh/openssh-6.6p1-ctr-cavstest.patch > new file mode 100644 > index 0000000..038efa0 > --- /dev/null > +++ b/recipes-connectivity/openssh/openssh/openssh-6.6p1-ctr-cavstest.patch > @@ -0,0 +1,289 @@ > +From a94a3d95439018dc7d276ec72de91af369ea413e Mon Sep 17 00:00:00 2001 > +From: Hongxu Jia <hongxu....@windriver.com> > +Date: Sun, 22 Sep 2019 21:32:18 +0800 > +Subject: [PATCH 1/2] add CAVS test driver for the aes-ctr ciphers > + > +Original submission to Fedora, see: > + > https://lists.fedoraproject.org/pipermail/scm-commits/2012-January/715044.html > + > +this version download from: > + > http://pkgs.fedoraproject.org/cgit/rpms/openssh.git/plain/openssh-6.6p1-ctr-cavstest.patch > + (as of commit 991b66246f5151884b63c6d1232610a4569642a5) > + > +Makefile.in slightly modified for integration > + > +This is the makefile.in change for the normal configuration. > + > +Signed-off-by: Mark Hatle <mark.ha...@windriver.com> > + > +Upstream-Status: Inappropriate [oe specific] > +Signed-off-by: Hongxu Jia <hongxu....@windriver.com> > +--- > + Makefile.in | 7 +- > + ctr-cavstest.c | 215 > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > + 2 files changed, 221 insertions(+), 1 deletion(-) > + create mode 100644 ctr-cavstest.c > + > +diff --git a/Makefile.in b/Makefile.in > +index ddd1804..cb34681 100644 > +--- a/Makefile.in > ++++ b/Makefile.in > +@@ -23,6 +23,7 @@ SSH_PROGRAM=@bindir@/ssh > + ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass > + SFTP_SERVER=$(libexecdir)/sftp-server > + SSH_KEYSIGN=$(libexecdir)/ssh-keysign > ++CTR_CAVSTEST=$(libexecdir)/ctr-cavstest > + SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper > + PRIVSEP_PATH=@PRIVSEP_PATH@ > + SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ > +@@ -60,7 +61,7 @@ EXEEXT=@EXEEXT@ > + MANFMT=@MANFMT@ > + MKDIR_P=@MKDIR_P@ > + > +-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=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) > ctr-cavstest$(EXEEXT) > + > + XMSS_OBJS=\ > + ssh-xmss.o \ > +@@ -193,6 +194,9 @@ ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a > ssh-keysign.o readconf.o uidswap.o c > + ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o > ssh-pkcs11.o > + $(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh > -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) > + > ++ctr-cavstest$(EXEEXT): $(LIBCOMPAT) libssh.a ctr-cavstest.o > ++ $(LD) -o $@ ctr-cavstest.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh > -lfipscheck $(LIBS) > ++ > + ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o > + $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh > -lfipscheck $(LIBS) > + > +@@ -343,6 +347,7 @@ install-files: > + $(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) ctr-cavstest$(EXEEXT) > $(DESTDIR)$(libexecdir)/ctr-cavstest$(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) > +diff --git a/ctr-cavstest.c b/ctr-cavstest.c > +new file mode 100644 > +index 0000000..0d4776b > +--- /dev/null > ++++ b/ctr-cavstest.c > +@@ -0,0 +1,215 @@ > ++/* > ++ * > ++ * invocation (all of the following are equal): > ++ * ./ctr-cavstest --algo aes128-ctr --key 987212980144b6a632e864031f52dacc > --mode encrypt --data a6deca405eef2e8e4609abf3c3ccf4a6 > ++ * ./ctr-cavstest --algo aes128-ctr --key 987212980144b6a632e864031f52dacc > --mode encrypt --data a6deca405eef2e8e4609abf3c3ccf4a6 --iv > 00000000000000000000000000000000 > ++ * echo -n a6deca405eef2e8e4609abf3c3ccf4a6 | ./ctr-cavstest --algo > aes128-ctr --key 987212980144b6a632e864031f52dacc --mode encrypt > ++ */ > ++ > ++#include "includes.h" > ++ > ++#include <sys/types.h> > ++#include <sys/param.h> > ++#include <stdarg.h> > ++#include <stdio.h> > ++#include <stdlib.h> > ++#include <string.h> > ++#include <ctype.h> > ++ > ++#include "xmalloc.h" > ++#include "log.h" > ++#include "ssherr.h" > ++#include "cipher.h" > ++ > ++/* compatibility with old or broken OpenSSL versions */ > ++#include "openbsd-compat/openssl-compat.h" > ++ > ++void usage(void) { > ++ fprintf(stderr, "Usage: ctr-cavstest --algo > <ssh-crypto-algorithm>\n" > ++ " --key <hexadecimal-key> --mode > <encrypt|decrypt>\n" > ++ " [--iv <hexadecimal-iv>] --data > <hexadecimal-data>\n\n" > ++ "Hexadecimal output is printed to stdout.\n" > ++ "Hexadecimal input data can be alternatively read > from stdin.\n"); > ++ exit(1); > ++} > ++ > ++void *fromhex(char *hex, size_t *len) > ++{ > ++ unsigned char *bin; > ++ char *p; > ++ size_t n = 0; > ++ int shift = 4; > ++ unsigned char out = 0; > ++ unsigned char *optr; > ++ > ++ bin = xmalloc(strlen(hex)/2); > ++ optr = bin; > ++ > ++ for (p = hex; *p != '\0'; ++p) { > ++ unsigned char c; > ++ > ++ c = *p; > ++ if (isspace(c)) > ++ continue; > ++ > ++ if (c >= '0' && c <= '9') { > ++ c = c - '0'; > ++ } else if (c >= 'A' && c <= 'F') { > ++ c = c - 'A' + 10; > ++ } else if (c >= 'a' && c <= 'f') { > ++ c = c - 'a' + 10; > ++ } else { > ++ /* truncate on nonhex cipher */ > ++ break; > ++ } > ++ > ++ out |= c << shift; > ++ shift = (shift + 4) % 8; > ++ > ++ if (shift) { > ++ *(optr++) = out; > ++ out = 0; > ++ ++n; > ++ } > ++ } > ++ > ++ *len = n; > ++ return bin; > ++} > ++ > ++#define READ_CHUNK 4096 > ++#define MAX_READ_SIZE 1024*1024*100 > ++char *read_stdin(void) > ++{ > ++ char *buf; > ++ size_t n, total = 0; > ++ > ++ buf = xmalloc(READ_CHUNK); > ++ > ++ do { > ++ n = fread(buf + total, 1, READ_CHUNK, stdin); > ++ if (n < READ_CHUNK) /* terminate on short read */ > ++ break; > ++ > ++ total += n; > ++ buf = xreallocarray(buf, total + READ_CHUNK, 1); > ++ } while(total < MAX_READ_SIZE); > ++ return buf; > ++} > ++ > ++int main (int argc, char *argv[]) > ++{ > ++ > ++ const struct sshcipher *c; > ++ struct sshcipher_ctx *cc; > ++ char *algo = "aes128-ctr"; > ++ char *hexkey = NULL; > ++ char *hexiv = "00000000000000000000000000000000"; > ++ char *hexdata = NULL; > ++ char *p; > ++ int i, r; > ++ int encrypt = 1; > ++ void *key; > ++ size_t keylen; > ++ void *iv; > ++ size_t ivlen; > ++ void *data; > ++ size_t datalen; > ++ void *outdata; > ++ > ++ for (i = 1; i < argc; ++i) { > ++ if (strcmp(argv[i], "--algo") == 0) { > ++ algo = argv[++i]; > ++ } else if (strcmp(argv[i], "--key") == 0) { > ++ hexkey = argv[++i]; > ++ } else if (strcmp(argv[i], "--mode") == 0) { > ++ ++i; > ++ if (argv[i] == NULL) { > ++ usage(); > ++ } > ++ if (strncmp(argv[i], "enc", 3) == 0) { > ++ encrypt = 1; > ++ } else if (strncmp(argv[i], "dec", 3) == 0) { > ++ encrypt = 0; > ++ } else { > ++ usage(); > ++ } > ++ } else if (strcmp(argv[i], "--iv") == 0) { > ++ hexiv = argv[++i]; > ++ } else if (strcmp(argv[i], "--data") == 0) { > ++ hexdata = argv[++i]; > ++ } > ++ } > ++ > ++ if (hexkey == NULL || algo == NULL) { > ++ usage(); > ++ } > ++ > ++ OpenSSL_add_all_algorithms(); > ++ > ++ c = cipher_by_name(algo); > ++ if (c == NULL) { > ++ fprintf(stderr, "Error: unknown algorithm\n"); > ++ return 2; > ++ } > ++ > ++ if (hexdata == NULL) { > ++ hexdata = read_stdin(); > ++ } else { > ++ hexdata = xstrdup(hexdata); > ++ } > ++ > ++ key = fromhex(hexkey, &keylen); > ++ > ++ if (keylen != 16 && keylen != 24 && keylen == 32) { > ++ fprintf(stderr, "Error: unsupported key length\n"); > ++ return 2; > ++ } > ++ > ++ iv = fromhex(hexiv, &ivlen); > ++ > ++ if (ivlen != 16) { > ++ fprintf(stderr, "Error: unsupported iv length\n"); > ++ return 2; > ++ } > ++ > ++ data = fromhex(hexdata, &datalen); > ++ > ++ if (data == NULL || datalen == 0) { > ++ fprintf(stderr, "Error: no data to encrypt/decrypt\n"); > ++ return 2; > ++ } > ++ > ++ if ((r = cipher_init(&cc, c, key, keylen, iv, ivlen, encrypt)) != 0) { > ++ fprintf(stderr, "Error: cipher_init failed: %s\n", ssh_err(r)); > ++ return 2; > ++ } > ++ > ++ free(key); > ++ free(iv); > ++ > ++ outdata = malloc(datalen); > ++ if(outdata == NULL) { > ++ fprintf(stderr, "Error: memory allocation failure\n"); > ++ return 2; > ++ } > ++ > ++ if ((r = cipher_crypt(cc, 0, outdata, data, datalen, 0, 0)) != 0) { > ++ fprintf(stderr, "Error: cipher_crypt failed: %s\n", ssh_err(r)); > ++ return 2; > ++ } > ++ > ++ free(data); > ++ > ++ cipher_free(cc); > ++ > ++ for (p = outdata; datalen > 0; ++p, --datalen) { > ++ printf("%02X", (unsigned char)*p); > ++ } > ++ > ++ free(outdata); > ++ > ++ printf("\n"); > ++ return 0; > ++} > ++ > +-- > +2.7.4 > + > diff --git > a/recipes-connectivity/openssh/openssh/openssh-6.7p1-kdf-cavs.patch > b/recipes-connectivity/openssh/openssh/openssh-6.7p1-kdf-cavs.patch > new file mode 100644 > index 0000000..f49821c > --- /dev/null > +++ b/recipes-connectivity/openssh/openssh/openssh-6.7p1-kdf-cavs.patch > @@ -0,0 +1,654 @@ > +From 210d15fd146ff7037f03fff5e0ba6fcf0bfde683 Mon Sep 17 00:00:00 2001 > +From: Hongxu Jia <hongxu....@windriver.com> > +Date: Sun, 22 Sep 2019 21:40:51 +0800 > +Subject: [PATCH 2/2] add KDF CAVS test driver > + > +Original submission to Fedora, see: > + > https://lists.fedoraproject.org/pipermail/scm-commits/Week-of-Mon-20150216/1514788.html > + > +this version download from: > + > http://pkgs.fedoraproject.org/cgit/rpms/openssh.git/plain/openssh-6.7p1-kdf-cavs.patch > + (as of commit 991b66246f5151884b63c6d1232610a4569642a5) > + > +Makefile.in slightly modified for integration > + > +This is the makefile.in change for the normal configuration. > + > +Signed-off-by: Mark Hatle <mark.ha...@windriver.com> > + > +Upstream-Status: Inappropriate [oe specific] > +Signed-off-by: Hongxu Jia <hongxu....@windriver.com> > +--- > + Makefile.in | 8 +- > + ssh-cavs.c | 387 > +++++++++++++++++++++++++++++++++++++++++++++++++++++ > + ssh-cavs_driver.pl | 184 +++++++++++++++++++++++++ > + 3 files changed, 578 insertions(+), 1 deletion(-) > + create mode 100644 ssh-cavs.c > + create mode 100644 ssh-cavs_driver.pl > + > +diff --git a/Makefile.in b/Makefile.in > +index cb34681..368097e 100644 > +--- a/Makefile.in > ++++ b/Makefile.in > +@@ -24,6 +24,7 @@ ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass > + SFTP_SERVER=$(libexecdir)/sftp-server > + SSH_KEYSIGN=$(libexecdir)/ssh-keysign > + CTR_CAVSTEST=$(libexecdir)/ctr-cavstest > ++SSH_CAVS=$(libexecdir)/ssh-cavs > + SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper > + PRIVSEP_PATH=@PRIVSEP_PATH@ > + SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ > +@@ -61,7 +62,7 @@ EXEEXT=@EXEEXT@ > + MANFMT=@MANFMT@ > + MKDIR_P=@MKDIR_P@ > + > +-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) > ctr-cavstest$(EXEEXT) > ++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) > ctr-cavstest$(EXEEXT) ssh-cavs$(EXEEXT) > + > + XMSS_OBJS=\ > + ssh-xmss.o \ > +@@ -197,6 +198,9 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a > ssh-pkcs11-helper.o ssh-pkcs11 > + ctr-cavstest$(EXEEXT): $(LIBCOMPAT) libssh.a ctr-cavstest.o > + $(LD) -o $@ ctr-cavstest.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh > -lfipscheck $(LIBS) > + > ++ssh-cavs$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-cavs.o > ++ $(LD) -o $@ ssh-cavs.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) > ++ > + ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o > + $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh > -lfipscheck $(LIBS) > + > +@@ -348,6 +352,8 @@ install-files: > + $(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) ctr-cavstest$(EXEEXT) > $(DESTDIR)$(libexecdir)/ctr-cavstest$(EXEEXT) > ++ $(INSTALL) -m 0755 $(STRIP_OPT) ssh-cavs$(EXEEXT) > $(DESTDIR)$(libexecdir)/ssh-cavs$(EXEEXT) > ++ $(INSTALL) -m 0755 $(STRIP_OPT) ssh-cavs_driver.pl > $(DESTDIR)$(libexecdir)/ssh-cavs_driver.pl > + $(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) > +diff --git a/ssh-cavs.c b/ssh-cavs.c > +new file mode 100644 > +index 0000000..b74ae7f > +--- /dev/null > ++++ b/ssh-cavs.c > +@@ -0,0 +1,387 @@ > ++/* > ++ * Copyright (C) 2015, Stephan Mueller <smuel...@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 "sshbuf.h" > ++#include "sshkey.h" > ++#include "cipher.h" > ++#include "kex.h" > ++#include "packet.h" > ++#include "digest.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 sshbuf *Kb = NULL; > ++ BIGNUM *Kbn = NULL; > ++ int mode = 0; > ++ struct newkeys *ctoskeys; > ++ struct newkeys *stockeys; > ++ struct ssh *ssh = NULL; > ++ > ++#define HEXOUTLEN 500 > ++ char hex[HEXOUTLEN]; > ++ > ++ memset(&kex, 0, sizeof(struct kex)); > ++ > ++ Kbn = BN_new(); > ++ BN_bin2bn(test->K, test->Klen, Kbn); > ++ if (!Kbn) { > ++ printf("cannot convert K into bignum\n"); > ++ ret = 1; > ++ goto out; > ++ } > ++ Kb = sshbuf_new(); > ++ if (!Kb) { > ++ printf("cannot convert K into sshbuf\n"); > ++ ret = 1; > ++ goto out; > ++ } > ++ sshbuf_put_bignum2(Kb, Kbn); > ++ > ++ 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 = SSH_DIGEST_SHA1; > ++ break; > ++ case 32: > ++ kex.hash_alg = SSH_DIGEST_SHA256; > ++ break; > ++ case 48: > ++ kex.hash_alg = SSH_DIGEST_SHA384; > ++ break; > ++ case 64: > ++ kex.hash_alg = SSH_DIGEST_SHA512; > ++ 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 */ > ++ if ((ssh = ssh_packet_set_connection(NULL, -1, -1)) == NULL){ > ++ printf("Allocation error\n"); > ++ goto out; > ++ } > ++ ssh->kex = &kex; > ++ kex_derive_keys(ssh, test->H, test->Hlen, Kb); > ++ > ++ ctoskeys = kex.newkeys[0]; > ++ stockeys = kex.newkeys[1]; > ++ > ++ /* get data */ > ++ memset(hex, 0, HEXOUTLEN); > ++ bin2hex(ctoskeys->enc.iv, (size_t)ctoskeys->enc.iv_len, > ++ hex, HEXOUTLEN, 0); > ++ printf("Initial IV (client to server) = %s\n", hex); > ++ memset(hex, 0, HEXOUTLEN); > ++ bin2hex(stockeys->enc.iv, (size_t)stockeys->enc.iv_len, > ++ hex, HEXOUTLEN, 0); > ++ printf("Initial IV (server to client) = %s\n", hex); > ++ > ++ memset(hex, 0, HEXOUTLEN); > ++ bin2hex(ctoskeys->enc.key, (size_t)ctoskeys->enc.key_len, > ++ hex, HEXOUTLEN, 0); > ++ printf("Encryption key (client to server) = %s\n", hex); > ++ memset(hex, 0, HEXOUTLEN); > ++ bin2hex(stockeys->enc.key, (size_t)stockeys->enc.key_len, > ++ hex, HEXOUTLEN, 0); > ++ printf("Encryption key (server to client) = %s\n", hex); > ++ > ++ memset(hex, 0, HEXOUTLEN); > ++ bin2hex(ctoskeys->mac.key, (size_t)ctoskeys->mac.key_len, > ++ hex, HEXOUTLEN, 0); > ++ printf("Integrity key (client to server) = %s\n", hex); > ++ memset(hex, 0, HEXOUTLEN); > ++ bin2hex(stockeys->mac.key, (size_t)stockeys->mac.key_len, > ++ hex, HEXOUTLEN, 0); > ++ printf("Integrity key (server to client) = %s\n", hex); > ++ > ++out: > ++ if (Kbn) > ++ BN_free(Kbn); > ++ if (Kb) > ++ sshbuf_free(Kb); > ++ if (ssh) > ++ ssh_packet_close(ssh); > ++ 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 > ++ * > ++ * Initial IV (client to server) = 4bb320d1679dfd3a > ++ * Initial IV (server to client) = 43dea6fdf263a308 > ++ * Encryption key (client to server) = > 13048cc600b9d3cf9095aa6cf8e2ff9cf1c54ca0520c89ed > ++ * Encryption key (server to client) = > 1e483c5134e901aa11fc4e0a524e7ec7b75556148a222bb0 > ++ * Integrity key (client to server) = > ecef63a092b0dcc585bdc757e01b2740af57d640 > ++ * 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; > ++ > ++} > +diff --git a/ssh-cavs_driver.pl b/ssh-cavs_driver.pl > +new file mode 100644 > +index 0000000..6ed8f26 > +--- /dev/null > ++++ b/ssh-cavs_driver.pl > +@@ -0,0 +1,184 @@ > ++#!/usr/bin/env perl > ++# > ++# CAVS test driver for OpenSSH > ++# > ++# Copyright (C) 2015, Stephan Mueller <smuel...@chronox.de> > ++# > ++# Permission is hereby granted, free of charge, to any person obtaining a > copy > ++# of this software and associated documentation files (the "Software"), to > deal > ++# in the Software without restriction, including without limitation the > rights > ++# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell > ++# copies of the Software, and to permit persons to whom the Software is > ++# furnished to do so, subject to the following conditions: > ++# > ++# The above copyright notice and this permission notice shall be included in > ++# all copies or substantial portions of the Software. > ++# > ++# NO WARRANTY > ++# > ++# BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY > ++# FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT > WHEN > ++# OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES > ++# PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER > EXPRESSED > ++# OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF > ++# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK > AS > ++# TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE > ++# PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY > SERVICING, > ++# REPAIR OR CORRECTION. > ++# > ++# IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING > ++# WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR > ++# REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR > DAMAGES, > ++# INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES > ARISING > ++# OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT > LIMITED > ++# TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED > BY > ++# YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY > OTHER > ++# PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE > ++# POSSIBILITY OF SUCH DAMAGES. > ++# > ++use strict; > ++use warnings; > ++use IPC::Open2; > ++ > ++# Executing a program by feeding STDIN and retrieving > ++# STDOUT > ++# $1: data string to be piped to the app on STDIN > ++# rest: program and args > ++# returns: STDOUT of program as string > ++sub pipe_through_program($@) { > ++ my $in = shift; > ++ my @args = @_; > ++ > ++ my ($CO, $CI); > ++ my $pid = open2($CO, $CI, @args); > ++ > ++ my $out = ""; > ++ my $len = length($in); > ++ my $first = 1; > ++ while (1) { > ++ my $rin = ""; > ++ my $win = ""; > ++ # Output of prog is FD that we read > ++ vec($rin,fileno($CO),1) = 1; > ++ # Input of prog is FD that we write > ++ # check for $first is needed because we can have NULL input > ++ # that is to be written to the app > ++ if ( $len > 0 || $first) { > ++ (vec($win,fileno($CI),1) = 1); > ++ $first=0; > ++ } > ++ # Let us wait for 100ms > ++ my $nfound = select(my $rout=$rin, my $wout=$win, undef, 0.1); > ++ if ( $wout ) { > ++ my $written = syswrite($CI, $in, $len); > ++ die "broken pipe" if !defined $written; > ++ $len -= $written; > ++ substr($in, 0, $written) = ""; > ++ if ($len <= 0) { > ++ close $CI or die "broken pipe: $!"; > ++ } > ++ } > ++ if ( $rout ) { > ++ my $tmp_out = ""; > ++ my $bytes_read = sysread($CO, $tmp_out, 4096); > ++ $out .= $tmp_out; > ++ last if ($bytes_read == 0); > ++ } > ++ } > ++ close $CO or die "broken pipe: $!"; > ++ waitpid $pid, 0; > ++ > ++ return $out; > ++} > ++ > ++# Parser of CAVS test vector file > ++# $1: Test vector file > ++# $2: Output file for test results > ++# return: nothing > ++sub parse($$) { > ++ my $infile = shift; > ++ my $outfile = shift; > ++ > ++ my $out = ""; > ++ > ++ my $K = ""; > ++ my $H = ""; > ++ my $session_id = ""; > ++ my $ivlen = 0; > ++ my $eklen = ""; > ++ my $iklen = ""; > ++ > ++ open(IN, "<$infile"); > ++ while(<IN>) { > ++ > ++ my $line = $_; > ++ chomp($line); > ++ $line =~ s/\r//; > ++ > ++ if ($line =~ /\[SHA-1\]/) { > ++ $iklen = 20; > ++ } elsif ($line =~ /\[SHA-256\]/) { > ++ $iklen = 32; > ++ } elsif ($line =~ /\[SHA-384\]/) { > ++ $iklen = 48; > ++ } elsif ($line =~ /\[SHA-512\]/) { > ++ $iklen = 64; > ++ } elsif ($line =~ /^\[IV length\s*=\s*(.*)\]/) { > ++ $ivlen = $1; > ++ $ivlen = $ivlen / 8; > ++ } elsif ($line =~ /^\[encryption key length\s*=\s*(.*)\]/) { > ++ $eklen = $1; > ++ $eklen = $eklen / 8; > ++ } elsif ($line =~ /^K\s*=\s*(.*)/) { > ++ $K = $1; > ++ $K = substr($K, 8); > ++ $K = "00" . $K; > ++ } elsif ($line =~ /^H\s*=\s*(.*)/) { > ++ $H = $1; > ++ } elsif ($line =~ /^session_id\s*=\s*(.*)/) { > ++ $session_id = $1; > ++ } > ++ $out .= $line . "\n"; > ++ > ++ if ($K ne "" && $H ne "" && $session_id ne "" && > ++ $ivlen ne "" && $eklen ne "" && $iklen > 0) { > ++ $out .= pipe_through_program("", "./ssh-cavs -H $H -K > $K -s $session_id -i $ivlen -e $eklen -m $iklen"); > ++ > ++ $K = ""; > ++ $H = ""; > ++ $session_id = ""; > ++ } > ++ } > ++ close IN; > ++ $out =~ s/\n/\r\n/g; # make it a dos file > ++ open(OUT, ">$outfile") or die "Cannot create output file $outfile: $?"; > ++ print OUT $out; > ++ close OUT; > ++} > ++ > ++############################################################ > ++# > ++# let us pretend to be C :-) > ++sub main() { > ++ > ++ my $infile=$ARGV[0]; > ++ die "Error: Test vector file $infile not found" if (! -f $infile); > ++ > ++ my $outfile = $infile; > ++ # let us add .rsp regardless whether we could strip .req > ++ $outfile =~ s/\.req$//; > ++ $outfile .= ".rsp"; > ++ if (-f $outfile) { > ++ die "Output file $outfile could not be removed: $?" > ++ unless unlink($outfile); > ++ } > ++ print STDERR "Performing tests from source file $infile with results > stored in destination file $outfile\n"; > ++ > ++ # Do the job > ++ parse($infile, $outfile); > ++} > ++ > ++########################################### > ++# Call it > ++main(); > ++1; > +-- > +2.7.4 > + > diff --git a/recipes-connectivity/openssh/openssh_fips.inc > b/recipes-connectivity/openssh/openssh_fips.inc > index 33a84c9..5df3106 100644 > --- a/recipes-connectivity/openssh/openssh_fips.inc > +++ b/recipes-connectivity/openssh/openssh_fips.inc > @@ -6,6 +6,8 @@ DEPENDS += " \ > SRC_URI += " \ > file://0001-openssh-8.0p1-fips.patch \ > file://0001-conditional-enable-fips-mode.patch \ > + file://openssh-6.6p1-ctr-cavstest.patch \ > + file://openssh-6.7p1-kdf-cavs.patch \ > " > > do_install_append() { > @@ -32,4 +34,11 @@ pkg_postinst_append_${PN}-sshd () { > fi > } > > +PACKAGES =+ "${PN}-cavs" > +SUMMARY_${PN}-cavs = "CAVS tests for FIPS validation" > +FILES_${PN}-cavs = " \ > + ${libexecdir}/ctr-cavstest \ > + ${libexecdir}/ssh-cavs \ > + ${libexecdir}/ssh-cavs_driver.pl" > + > FILES_${PN} += "${libdir}/fipscheck" > -- _______________________________________________ yocto mailing list yocto@yoctoproject.org https://lists.yoctoproject.org/listinfo/yocto