openssl speed: add an '-unaligned n' option
authortb <tb@openbsd.org>
Sat, 20 May 2023 12:03:02 +0000 (12:03 +0000)
committertb <tb@openbsd.org>
Sat, 20 May 2023 12:03:02 +0000 (12:03 +0000)
All hashes and ciphers covered by speed should be able to handle unaligned
input and output. The buffers used in openssl speed are well aligned since
they are large, so will never exercise the more problematic unaligned case.

I wished something like this was available on various occasions. It would
have been useful to point more easily at OpenSSL's broken T4 assembly.
Yesterday there were two independent reasons for wanting it, so I sat down
and did it. It's trivial: make the allocations a bit larger and use buffers
starting at an offset inside these allocations. Despite the trivality, I
managed to have a stupid bug. Thanks miod.

discussed with jsing
ok miod

usr.bin/openssl/openssl.1
usr.bin/openssl/speed.c

index 4c9d15b..f01f71b 100644 (file)
@@ -1,4 +1,4 @@
-.\" $OpenBSD: openssl.1,v 1.144 2023/05/05 18:01:27 tb Exp $
+.\" $OpenBSD: openssl.1,v 1.145 2023/05/20 12:03:02 tb Exp $
 .\" ====================================================================
 .\" Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
 .\"
 .\" copied and put under another distribution licence
 .\" [including the GNU Public Licence.]
 .\"
-.Dd $Mdocdate: May 5 2023 $
+.Dd $Mdocdate: May 20 2023 $
 .Dt OPENSSL 1
 .Os
 .Sh NAME
@@ -5392,6 +5392,7 @@ An error occurred writing certificates.
 .Op Fl evp Ar algorithm
 .Op Fl mr
 .Op Fl multi Ar number
+.Op Fl unaligned Ar number
 .Ek
 .El
 .Pp
@@ -5418,6 +5419,13 @@ Produce machine readable output.
 Run
 .Ar number
 benchmarks in parallel.
+.It Fl unaligned Ar number
+Use allocated buffers with an offset of
+.Ar number
+bytes from the alignment provided by
+.Xr malloc 3 . 
+.Ar number
+should be between 0 and 16.
 .El
 .Tg spkac
 .Sh SPKAC
index 3b78c55..a1a69c2 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: speed.c,v 1.32 2023/05/20 11:44:15 tb Exp $ */
+/* $OpenBSD: speed.c,v 1.33 2023/05/20 12:03:02 tb Exp $ */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -79,6 +79,8 @@
 #define ECDSA_SECONDS   10
 #define ECDH_SECONDS    10
 
+#define MAX_UNALIGN    16
+
 #include <math.h>
 #include <signal.h>
 #include <stdio.h>
@@ -227,7 +229,9 @@ KDF1_SHA1(const void *in, size_t inlen, void *out, size_t * outlen)
 int
 speed_main(int argc, char **argv)
 {
+       unsigned char *real_buf = NULL, *real_buf2 = NULL;
        unsigned char *buf = NULL, *buf2 = NULL;
+       size_t unaligned = 0;
        int mret = 1;
        long count = 0, save_count = 0;
        int i, j, k;
@@ -450,11 +454,11 @@ speed_main(int argc, char **argv)
        for (i = 0; i < RSA_NUM; i++)
                rsa_key[i] = NULL;
 
-       if ((buf = malloc(BUFSIZE)) == NULL) {
+       if ((buf = real_buf = malloc(BUFSIZE + MAX_UNALIGN)) == NULL) {
                BIO_printf(bio_err, "out of memory\n");
                goto end;
        }
-       if ((buf2 = malloc(BUFSIZE)) == NULL) {
+       if ((buf2 = real_buf2 = malloc(BUFSIZE + MAX_UNALIGN)) == NULL) {
                BIO_printf(bio_err, "out of memory\n");
                goto end;
        }
@@ -516,6 +520,23 @@ speed_main(int argc, char **argv)
                        }
                        j--;    /* Otherwise, -multi gets confused with an
                                 * algorithm. */
+               } else if (argc > 0 && strcmp(*argv, "-unaligned") == 0) {
+                       argc--;
+                       argv++;
+                       if (argc == 0) {
+                               BIO_printf(bio_err, "no alignment offset given\n");
+                               goto end;
+                       }
+                       unaligned = strtonum(argv[0], 0, MAX_UNALIGN, &errstr);
+                       if (errstr) {
+                               BIO_printf(bio_err, "bad alignment offset: %s",
+                                   errstr);
+                               goto end;
+                       }
+                       buf = real_buf + unaligned;
+                       buf2 = real_buf2 + unaligned;
+                       j--;    /* Otherwise, -unaligned gets confused with an
+                                * algorithm. */
                } else if (argc > 0 && strcmp(*argv, "-mr") == 0) {
                        mr = 1;
                        j--;    /* Otherwise, -mr gets confused with an
@@ -835,6 +856,7 @@ speed_main(int argc, char **argv)
                        BIO_printf(bio_err, "-decrypt        time decryption instead of encryption (only EVP).\n");
                        BIO_printf(bio_err, "-mr             produce machine readable output.\n");
                        BIO_printf(bio_err, "-multi n        run n benchmarks in parallel.\n");
+                       BIO_printf(bio_err, "-unaligned n    use buffers with offset n from proper alignment.\n");
                        goto end;
                }
                argc--;
@@ -1848,8 +1870,8 @@ show_res:
 
  end:
        ERR_print_errors(bio_err);
-       free(buf);
-       free(buf2);
+       free(real_buf);
+       free(real_buf2);
        for (i = 0; i < RSA_NUM; i++)
                if (rsa_key[i] != NULL)
                        RSA_free(rsa_key[i]);