Copyright year updates
[openssl.git] / crypto / bn / bn_s390x.c
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)
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) {
51         /*-
52          * In this cases, someone (e.g. a sandbox) closed the fd.
53          * Make sure to not further use this hardware acceleration.
54          */
55         OPENSSL_s390xcex = -1;
56     }
57  dealloc:
58     OPENSSL_clear_free(buffer, 4 * size);
59     return res;
60 }
61
62 int s390x_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
63                   const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
64 {
65     if (s390x_mod_exp_hw(r, a, p, m) == 1)
66         return 1;
67     return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx);
68 }
69
70 int s390x_crt(BIGNUM *r, const BIGNUM *i, const BIGNUM *p, const BIGNUM *q,
71               const BIGNUM *dmp, const BIGNUM *dmq, const BIGNUM *iqmp)
72 {
73     struct ica_rsa_modexpo_crt crt;
74     unsigned char *buffer, *part;
75     size_t size, plen, qlen;
76     int res = 0;
77
78     if (OPENSSL_s390xcex == -1)
79         return 0;
80     /*-
81      * Hardware-accelerated CRT can only deal with p>q.  Fall back to
82      * software in the (hopefully rare) other cases.
83      */
84     if (BN_ucmp(p, q) != 1)
85         return 0;
86     plen = BN_num_bytes(p);
87     qlen = BN_num_bytes(q);
88     size = (plen > qlen ? plen : qlen);
89     buffer = OPENSSL_zalloc(9 * size + 24);
90     if (buffer == NULL)
91         return 0;
92     part = buffer;
93     crt.inputdata = part;
94     crt.inputdatalength = 2 * size;
95     part += 2 * size;
96     crt.outputdata = part;
97     crt.outputdatalength = 2 * size;
98     part += 2 * size;
99     crt.bp_key = part;
100     part += size + 8;
101     crt.bq_key = part;
102     part += size;
103     crt.np_prime = part;
104     part += size + 8;
105     crt.nq_prime = part;
106     part += size;
107     crt.u_mult_inv = part;
108     if (BN_bn2binpad(i, crt.inputdata, crt.inputdatalength) == -1
109         || BN_bn2binpad(p, crt.np_prime, size + 8) == -1
110         || BN_bn2binpad(q, crt.nq_prime, size) == -1
111         || BN_bn2binpad(dmp, crt.bp_key, size + 8) == -1
112         || BN_bn2binpad(dmq, crt.bq_key, size) == -1
113         || BN_bn2binpad(iqmp, crt.u_mult_inv, size + 8) == -1)
114         goto dealloc;
115     if (ioctl(OPENSSL_s390xcex, ICARSACRT, &crt) != -1) {
116         if (BN_bin2bn(crt.outputdata, crt.outputdatalength, r) != NULL)
117             res = 1;
118     } else if (errno == EBADF) {
119         /*-
120          * In this cases, someone (e.g. a sandbox) closed the fd.
121          * Make sure to not further use this hardware acceleration.
122          */
123         OPENSSL_s390xcex = -1;
124     }
125  dealloc:
126     OPENSSL_clear_free(buffer, 9 * size + 24);
127     return res;
128 }
129
130 #else
131 int s390x_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
132                   const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
133 {
134     return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx);
135 }
136
137 int s390x_crt(BIGNUM *r, const BIGNUM *i, const BIGNUM *p, const BIGNUM *q,
138               const BIGNUM *dmp, const BIGNUM *dmq, const BIGNUM *iqmp)
139 {
140     return 0;
141 }
142
143 #endif