1 | /*
|
---|
2 | * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
|
---|
3 | *
|
---|
4 | * Licensed under the Apache License 2.0 (the "License"). You may not use
|
---|
5 | * this file except in compliance with the License. You can obtain a copy
|
---|
6 | * in the file LICENSE in the source distribution or at
|
---|
7 | * https://www.openssl.org/source/license.html
|
---|
8 | */
|
---|
9 |
|
---|
10 | #include "crypto/bn.h"
|
---|
11 | #include "crypto/s390x_arch.h"
|
---|
12 |
|
---|
13 | #ifdef S390X_MOD_EXP
|
---|
14 |
|
---|
15 | # include <sys/types.h>
|
---|
16 | # include <sys/stat.h>
|
---|
17 | # include <fcntl.h>
|
---|
18 | # include <asm/zcrypt.h>
|
---|
19 | # include <sys/ioctl.h>
|
---|
20 | # include <unistd.h>
|
---|
21 | # include <errno.h>
|
---|
22 |
|
---|
23 | static int s390x_mod_exp_hw(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
|
---|
24 | const BIGNUM *m)
|
---|
25 | {
|
---|
26 | struct ica_rsa_modexpo me;
|
---|
27 | unsigned char *buffer;
|
---|
28 | size_t size;
|
---|
29 | int res = 0;
|
---|
30 |
|
---|
31 | if (OPENSSL_s390xcex == -1 || OPENSSL_s390xcex_nodev)
|
---|
32 | return 0;
|
---|
33 | size = BN_num_bytes(m);
|
---|
34 | buffer = OPENSSL_zalloc(4 * size);
|
---|
35 | if (buffer == NULL)
|
---|
36 | return 0;
|
---|
37 | me.inputdata = buffer;
|
---|
38 | me.inputdatalength = size;
|
---|
39 | me.outputdata = buffer + size;
|
---|
40 | me.outputdatalength = size;
|
---|
41 | me.b_key = buffer + 2 * size;
|
---|
42 | me.n_modulus = buffer + 3 * size;
|
---|
43 | if (BN_bn2binpad(a, me.inputdata, size) == -1
|
---|
44 | || BN_bn2binpad(p, me.b_key, size) == -1
|
---|
45 | || BN_bn2binpad(m, me.n_modulus, size) == -1)
|
---|
46 | goto dealloc;
|
---|
47 | if (ioctl(OPENSSL_s390xcex, ICARSAMODEXPO, &me) != -1) {
|
---|
48 | if (BN_bin2bn(me.outputdata, size, r) != NULL)
|
---|
49 | res = 1;
|
---|
50 | } else if (errno == EBADF || errno == ENOTTY) {
|
---|
51 | /*
|
---|
52 | * In this cases, someone (e.g. a sandbox) closed the fd.
|
---|
53 | * Make sure to not further use this hardware acceleration.
|
---|
54 | * In case of ENOTTY the file descriptor was already reused for another
|
---|
55 | * file. Do not attempt to use or close that file descriptor anymore.
|
---|
56 | */
|
---|
57 | OPENSSL_s390xcex = -1;
|
---|
58 | } else if (errno == ENODEV) {
|
---|
59 | /*
|
---|
60 | * No crypto card(s) available to handle RSA requests.
|
---|
61 | * Make sure to not further use this hardware acceleration,
|
---|
62 | * but do not close the file descriptor.
|
---|
63 | */
|
---|
64 | OPENSSL_s390xcex_nodev = 1;
|
---|
65 | }
|
---|
66 | dealloc:
|
---|
67 | OPENSSL_clear_free(buffer, 4 * size);
|
---|
68 | return res;
|
---|
69 | }
|
---|
70 |
|
---|
71 | int s390x_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
|
---|
72 | const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
|
---|
73 | {
|
---|
74 | if (s390x_mod_exp_hw(r, a, p, m) == 1)
|
---|
75 | return 1;
|
---|
76 | return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx);
|
---|
77 | }
|
---|
78 |
|
---|
79 | int s390x_crt(BIGNUM *r, const BIGNUM *i, const BIGNUM *p, const BIGNUM *q,
|
---|
80 | const BIGNUM *dmp, const BIGNUM *dmq, const BIGNUM *iqmp)
|
---|
81 | {
|
---|
82 | struct ica_rsa_modexpo_crt crt;
|
---|
83 | unsigned char *buffer, *part;
|
---|
84 | size_t size, plen, qlen;
|
---|
85 | int res = 0;
|
---|
86 |
|
---|
87 | if (OPENSSL_s390xcex == -1 || OPENSSL_s390xcex_nodev)
|
---|
88 | return 0;
|
---|
89 | /*-
|
---|
90 | * Hardware-accelerated CRT can only deal with p>q. Fall back to
|
---|
91 | * software in the (hopefully rare) other cases.
|
---|
92 | */
|
---|
93 | if (BN_ucmp(p, q) != 1)
|
---|
94 | return 0;
|
---|
95 | plen = BN_num_bytes(p);
|
---|
96 | qlen = BN_num_bytes(q);
|
---|
97 | size = (plen > qlen ? plen : qlen);
|
---|
98 | buffer = OPENSSL_zalloc(9 * size + 24);
|
---|
99 | if (buffer == NULL)
|
---|
100 | return 0;
|
---|
101 | part = buffer;
|
---|
102 | crt.inputdata = part;
|
---|
103 | crt.inputdatalength = 2 * size;
|
---|
104 | part += 2 * size;
|
---|
105 | crt.outputdata = part;
|
---|
106 | crt.outputdatalength = 2 * size;
|
---|
107 | part += 2 * size;
|
---|
108 | crt.bp_key = part;
|
---|
109 | part += size + 8;
|
---|
110 | crt.bq_key = part;
|
---|
111 | part += size;
|
---|
112 | crt.np_prime = part;
|
---|
113 | part += size + 8;
|
---|
114 | crt.nq_prime = part;
|
---|
115 | part += size;
|
---|
116 | crt.u_mult_inv = part;
|
---|
117 | if (BN_bn2binpad(i, crt.inputdata, crt.inputdatalength) == -1
|
---|
118 | || BN_bn2binpad(p, crt.np_prime, size + 8) == -1
|
---|
119 | || BN_bn2binpad(q, crt.nq_prime, size) == -1
|
---|
120 | || BN_bn2binpad(dmp, crt.bp_key, size + 8) == -1
|
---|
121 | || BN_bn2binpad(dmq, crt.bq_key, size) == -1
|
---|
122 | || BN_bn2binpad(iqmp, crt.u_mult_inv, size + 8) == -1)
|
---|
123 | goto dealloc;
|
---|
124 | if (ioctl(OPENSSL_s390xcex, ICARSACRT, &crt) != -1) {
|
---|
125 | if (BN_bin2bn(crt.outputdata, crt.outputdatalength, r) != NULL)
|
---|
126 | res = 1;
|
---|
127 | } else if (errno == EBADF || errno == ENOTTY) {
|
---|
128 | /*
|
---|
129 | * In this cases, someone (e.g. a sandbox) closed the fd.
|
---|
130 | * Make sure to not further use this hardware acceleration.
|
---|
131 | * In case of ENOTTY the file descriptor was already reused for another
|
---|
132 | * file. Do not attempt to use or close that file descriptor anymore.
|
---|
133 | */
|
---|
134 | OPENSSL_s390xcex = -1;
|
---|
135 | } else if (errno == ENODEV) {
|
---|
136 | /*
|
---|
137 | * No crypto card(s) available to handle RSA requests.
|
---|
138 | * Make sure to not further use this hardware acceleration,
|
---|
139 | * but do not close the file descriptor.
|
---|
140 | */
|
---|
141 | OPENSSL_s390xcex_nodev = 1;
|
---|
142 | }
|
---|
143 | dealloc:
|
---|
144 | OPENSSL_clear_free(buffer, 9 * size + 24);
|
---|
145 | return res;
|
---|
146 | }
|
---|
147 |
|
---|
148 | #else
|
---|
149 | int s390x_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
|
---|
150 | const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
|
---|
151 | {
|
---|
152 | return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx);
|
---|
153 | }
|
---|
154 |
|
---|
155 | int s390x_crt(BIGNUM *r, const BIGNUM *i, const BIGNUM *p, const BIGNUM *q,
|
---|
156 | const BIGNUM *dmp, const BIGNUM *dmq, const BIGNUM *iqmp)
|
---|
157 | {
|
---|
158 | return 0;
|
---|
159 | }
|
---|
160 |
|
---|
161 | #endif
|
---|