Compare commits
121 Commits
OpenSSL_1_
...
OpenSSL_1_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
225628f280 | ||
|
|
ca39b261bf | ||
|
|
c1beec0e6d | ||
|
|
b095884a58 | ||
|
|
f7fe3d235a | ||
|
|
b2688c9161 | ||
|
|
bf6fa208b5 | ||
|
|
eb37b6aa41 | ||
|
|
f66f76a24a | ||
|
|
65c63da207 | ||
|
|
9f028e4a78 | ||
|
|
64eec8f898 | ||
|
|
08a88774bd | ||
|
|
802a070bb6 | ||
|
|
31c65a7bc0 | ||
|
|
208a6012be | ||
|
|
d7f8a7cafd | ||
|
|
0f1c30b00d | ||
|
|
c4b969639a | ||
|
|
bfb2e4b280 | ||
|
|
d8c8a718a2 | ||
|
|
40c2812f56 | ||
|
|
2e3e3d278e | ||
|
|
2ececf59de | ||
|
|
a60536348b | ||
|
|
9d410579a7 | ||
|
|
4f90ef0c5b | ||
|
|
eae2bb2f1f | ||
|
|
c313270836 | ||
|
|
af8a66d10d | ||
|
|
ec5c25b3b4 | ||
|
|
38afaa48ec | ||
|
|
954818fe60 | ||
|
|
027381f68c | ||
|
|
a900b3b51c | ||
|
|
82d7247fc5 | ||
|
|
ceb4c684e4 | ||
|
|
a8da754d84 | ||
|
|
8ccb44e6f5 | ||
|
|
bbfdd1f0c9 | ||
|
|
8724f9f9cf | ||
|
|
6d41cbb63a | ||
|
|
04a73c844f | ||
|
|
87ff17a05d | ||
|
|
d93112abc6 | ||
|
|
875a33d7f7 | ||
|
|
cf48a6d7f6 | ||
|
|
7f3490e685 | ||
|
|
dcf7a2dc4a | ||
|
|
6ff76b3347 | ||
|
|
3b12515180 | ||
|
|
4e73dc5b76 | ||
|
|
67eb85d7d4 | ||
|
|
915a3b1c21 | ||
|
|
e1b1d82aab | ||
|
|
c25456633c | ||
|
|
aaf9335970 | ||
|
|
cee17f96f1 | ||
|
|
bd36615973 | ||
|
|
db85611989 | ||
|
|
9e5267fcdd | ||
|
|
0d330ce5cc | ||
|
|
2a303a5834 | ||
|
|
8d81dfd0a6 | ||
|
|
69c163ac81 | ||
|
|
b7eaea7397 | ||
|
|
2d2965d2c1 | ||
|
|
56cee260d8 | ||
|
|
e2e13b8f3a | ||
|
|
13b2a4d06a | ||
|
|
41da9188cc | ||
|
|
e9fe4b1033 | ||
|
|
6469c947f5 | ||
|
|
9bf3ff1ca0 | ||
|
|
74f77d40a9 | ||
|
|
55513f3e48 | ||
|
|
c8dd719095 | ||
|
|
0bfd0bff17 | ||
|
|
eb269523bb | ||
|
|
802feda7fc | ||
|
|
cdad6ad015 | ||
|
|
4eca4cfbc8 | ||
|
|
7e29be228e | ||
|
|
8745c0815c | ||
|
|
68828f167c | ||
|
|
59dcfa21e5 | ||
|
|
13f8ddacbe | ||
|
|
ad8b204386 | ||
|
|
7b7aef9bfd | ||
|
|
93540299fe | ||
|
|
1db72876dc | ||
|
|
b55ff319f8 | ||
|
|
9a6940a349 | ||
|
|
c36ceb0b15 | ||
|
|
904fcce0c6 | ||
|
|
2518a35a51 | ||
|
|
442ca2bd00 | ||
|
|
09e62af4d4 | ||
|
|
88f0c9797e | ||
|
|
74f5307d57 | ||
|
|
da8dd611ae | ||
|
|
43711a589b | ||
|
|
bf63eab048 | ||
|
|
62ca466a54 | ||
|
|
17d3b1ecea | ||
|
|
73729e4cf3 | ||
|
|
05f61fb27e | ||
|
|
10be715b95 | ||
|
|
e87a4a7011 | ||
|
|
f2a57c101f | ||
|
|
b88ffa2bce | ||
|
|
27b0494153 | ||
|
|
d38dcafe95 | ||
|
|
b0873dbb44 | ||
|
|
48ae65be09 | ||
|
|
dd5d7447c1 | ||
|
|
4ff9cbe635 | ||
|
|
e164b34079 | ||
|
|
679d0c8655 | ||
|
|
1d5e58b53c | ||
|
|
118149887b |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -75,3 +75,5 @@
|
||||
lib
|
||||
Makefile.save
|
||||
*.bak
|
||||
tags
|
||||
TAGS
|
||||
|
||||
138
CHANGES
138
CHANGES
@@ -2,6 +2,144 @@
|
||||
OpenSSL CHANGES
|
||||
_______________
|
||||
|
||||
Changes between 1.0.0o and 1.0.0p [8 Jan 2015]
|
||||
|
||||
*) Fix DTLS segmentation fault in dtls1_get_record. A carefully crafted DTLS
|
||||
message can cause a segmentation fault in OpenSSL due to a NULL pointer
|
||||
dereference. This could lead to a Denial Of Service attack. Thanks to
|
||||
Markus Stenberg of Cisco Systems, Inc. for reporting this issue.
|
||||
(CVE-2014-3571)
|
||||
[Steve Henson]
|
||||
|
||||
*) Fix DTLS memory leak in dtls1_buffer_record. A memory leak can occur in the
|
||||
dtls1_buffer_record function under certain conditions. In particular this
|
||||
could occur if an attacker sent repeated DTLS records with the same
|
||||
sequence number but for the next epoch. The memory leak could be exploited
|
||||
by an attacker in a Denial of Service attack through memory exhaustion.
|
||||
Thanks to Chris Mueller for reporting this issue.
|
||||
(CVE-2015-0206)
|
||||
[Matt Caswell]
|
||||
|
||||
*) Fix issue where no-ssl3 configuration sets method to NULL. When openssl is
|
||||
built with the no-ssl3 option and a SSL v3 ClientHello is received the ssl
|
||||
method would be set to NULL which could later result in a NULL pointer
|
||||
dereference. Thanks to Frank Schmirler for reporting this issue.
|
||||
(CVE-2014-3569)
|
||||
[Kurt Roeckx]
|
||||
|
||||
*) Abort handshake if server key exchange message is omitted for ephemeral
|
||||
ECDH ciphersuites.
|
||||
|
||||
Thanks to Karthikeyan Bhargavan of the PROSECCO team at INRIA for
|
||||
reporting this issue.
|
||||
(CVE-2014-3572)
|
||||
[Steve Henson]
|
||||
|
||||
*) Remove non-export ephemeral RSA code on client and server. This code
|
||||
violated the TLS standard by allowing the use of temporary RSA keys in
|
||||
non-export ciphersuites and could be used by a server to effectively
|
||||
downgrade the RSA key length used to a value smaller than the server
|
||||
certificate. Thanks for Karthikeyan Bhargavan of the PROSECCO team at
|
||||
INRIA or reporting this issue.
|
||||
(CVE-2015-0204)
|
||||
[Steve Henson]
|
||||
|
||||
*) Fixed issue where DH client certificates are accepted without verification.
|
||||
An OpenSSL server will accept a DH certificate for client authentication
|
||||
without the certificate verify message. This effectively allows a client to
|
||||
authenticate without the use of a private key. This only affects servers
|
||||
which trust a client certificate authority which issues certificates
|
||||
containing DH keys: these are extremely rare and hardly ever encountered.
|
||||
Thanks for Karthikeyan Bhargavan of the PROSECCO team at INRIA or reporting
|
||||
this issue.
|
||||
(CVE-2015-0205)
|
||||
[Steve Henson]
|
||||
|
||||
*) Correct Bignum squaring. Bignum squaring (BN_sqr) may produce incorrect
|
||||
results on some platforms, including x86_64. This bug occurs at random
|
||||
with a very low probability, and is not known to be exploitable in any
|
||||
way, though its exact impact is difficult to determine. Thanks to Pieter
|
||||
Wuille (Blockstream) who reported this issue and also suggested an initial
|
||||
fix. Further analysis was conducted by the OpenSSL development team and
|
||||
Adam Langley of Google. The final fix was developed by Andy Polyakov of
|
||||
the OpenSSL core team.
|
||||
(CVE-2014-3570)
|
||||
[Andy Polyakov]
|
||||
|
||||
*) Fix various certificate fingerprint issues.
|
||||
|
||||
By using non-DER or invalid encodings outside the signed portion of a
|
||||
certificate the fingerprint can be changed without breaking the signature.
|
||||
Although no details of the signed portion of the certificate can be changed
|
||||
this can cause problems with some applications: e.g. those using the
|
||||
certificate fingerprint for blacklists.
|
||||
|
||||
1. Reject signatures with non zero unused bits.
|
||||
|
||||
If the BIT STRING containing the signature has non zero unused bits reject
|
||||
the signature. All current signature algorithms require zero unused bits.
|
||||
|
||||
2. Check certificate algorithm consistency.
|
||||
|
||||
Check the AlgorithmIdentifier inside TBS matches the one in the
|
||||
certificate signature. NB: this will result in signature failure
|
||||
errors for some broken certificates.
|
||||
|
||||
Thanks to Konrad Kraszewski from Google for reporting this issue.
|
||||
|
||||
3. Check DSA/ECDSA signatures use DER.
|
||||
|
||||
Reencode DSA/ECDSA signatures and compare with the original received
|
||||
signature. Return an error if there is a mismatch.
|
||||
|
||||
This will reject various cases including garbage after signature
|
||||
(thanks to Antti Karjalainen and Tuomo Untinen from the Codenomicon CROSS
|
||||
program for discovering this case) and use of BER or invalid ASN.1 INTEGERs
|
||||
(negative or with leading zeroes).
|
||||
|
||||
Further analysis was conducted and fixes were developed by Stephen Henson
|
||||
of the OpenSSL core team.
|
||||
|
||||
(CVE-2014-8275)
|
||||
[Steve Henson]
|
||||
|
||||
Changes between 1.0.0n and 1.0.0o [15 Oct 2014]
|
||||
|
||||
*) Session Ticket Memory Leak.
|
||||
|
||||
When an OpenSSL SSL/TLS/DTLS server receives a session ticket the
|
||||
integrity of that ticket is first verified. In the event of a session
|
||||
ticket integrity check failing, OpenSSL will fail to free memory
|
||||
causing a memory leak. By sending a large number of invalid session
|
||||
tickets an attacker could exploit this issue in a Denial Of Service
|
||||
attack.
|
||||
(CVE-2014-3567)
|
||||
[Steve Henson]
|
||||
|
||||
*) Build option no-ssl3 is incomplete.
|
||||
|
||||
When OpenSSL is configured with "no-ssl3" as a build option, servers
|
||||
could accept and complete a SSL 3.0 handshake, and clients could be
|
||||
configured to send them.
|
||||
(CVE-2014-3568)
|
||||
[Akamai and the OpenSSL team]
|
||||
|
||||
*) Add support for TLS_FALLBACK_SCSV.
|
||||
Client applications doing fallback retries should call
|
||||
SSL_set_mode(s, SSL_MODE_SEND_FALLBACK_SCSV).
|
||||
(CVE-2014-3566)
|
||||
[Adam Langley, Bodo Moeller]
|
||||
|
||||
*) Add additional DigestInfo checks.
|
||||
|
||||
Reencode DigestInto in DER and check against the original when
|
||||
verifying RSA signature: this will reject any improperly encoded
|
||||
DigestInfo structures.
|
||||
|
||||
Note: this is a precautionary measure and no attacks are currently known.
|
||||
|
||||
[Steve Henson]
|
||||
|
||||
Changes between 1.0.0m and 1.0.0n [6 Aug 2014]
|
||||
|
||||
*) OpenSSL DTLS clients enabling anonymous (EC)DH ciphersuites are subject
|
||||
|
||||
18
NEWS
18
NEWS
@@ -5,6 +5,24 @@
|
||||
This file gives a brief overview of the major changes between each OpenSSL
|
||||
release. For more details please read the CHANGES file.
|
||||
|
||||
Major changes between OpenSSL 1.0.0o and OpenSSL 1.0.0p [8 Jan 2015]
|
||||
|
||||
o Fix for CVE-2014-3571
|
||||
o Fix for CVE-2015-0206
|
||||
o Fix for CVE-2014-3569
|
||||
o Fix for CVE-2014-3572
|
||||
o Fix for CVE-2015-0204
|
||||
o Fix for CVE-2015-0205
|
||||
o Fix for CVE-2014-8275
|
||||
o Fix for CVE-2014-3570
|
||||
|
||||
Major changes between OpenSSL 1.0.0n and OpenSSL 1.0.0o [15 Oct 2014]
|
||||
|
||||
o Fix for CVE-2014-3513
|
||||
o Fix for CVE-2014-3567
|
||||
o Mitigation for CVE-2014-3566 (SSL protocol vulnerability)
|
||||
o Fix for CVE-2014-3568
|
||||
|
||||
Major changes between OpenSSL 1.0.0m and OpenSSL 1.0.0n [6 Aug 2014]
|
||||
|
||||
o Fix for CVE-2014-3510
|
||||
|
||||
2
README
2
README
@@ -1,5 +1,5 @@
|
||||
|
||||
OpenSSL 1.0.0n 6 Aug 2014
|
||||
OpenSSL 1.0.0p 8 Jan 2015
|
||||
|
||||
Copyright (c) 1998-2011 The OpenSSL Project
|
||||
Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
|
||||
|
||||
@@ -773,9 +773,12 @@ $ CCDEFS = "MONOLITH"
|
||||
$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = CCDEFS + "," + USER_CCDEFS
|
||||
$ CCEXTRAFLAGS = ""
|
||||
$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS
|
||||
$ CCDISABLEWARNINGS = "" !!! "LONGLONGTYPE,LONGLONGSUFX,FOUNDCR"
|
||||
$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. "" THEN -
|
||||
CCDISABLEWARNINGS = CCDISABLEWARNINGS + "," + USER_CCDISABLEWARNINGS
|
||||
$ CCDISABLEWARNINGS = "" !!! "MAYLOSEDATA3" !!! "LONGLONGTYPE,LONGLONGSUFX,FOUNDCR"
|
||||
$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. ""
|
||||
$ THEN
|
||||
$ IF CCDISABLEWARNINGS .NES. "" THEN CCDISABLEWARNINGS = CCDISABLEWARNINGS + ","
|
||||
$ CCDISABLEWARNINGS = CCDISABLEWARNINGS + USER_CCDISABLEWARNINGS
|
||||
$ ENDIF
|
||||
$!
|
||||
$! Check To See If We Have A ZLIB Option.
|
||||
$!
|
||||
@@ -1064,6 +1067,18 @@ $! Finish up the definition of CC.
|
||||
$!
|
||||
$ IF COMPILER .EQS. "DECC"
|
||||
$ THEN
|
||||
$! Not all compiler versions support MAYLOSEDATA3.
|
||||
$ OPT_TEST = "MAYLOSEDATA3"
|
||||
$ DEFINE /USER_MODE SYS$ERROR NL:
|
||||
$ DEFINE /USER_MODE SYS$OUTPUT NL:
|
||||
$ 'CC' /NOCROSS_REFERENCE /NOLIST /NOOBJECT -
|
||||
/WARNINGS = DISABLE = ('OPT_TEST', EMPTYFILE) NL:
|
||||
$ IF ($SEVERITY)
|
||||
$ THEN
|
||||
$ IF CCDISABLEWARNINGS .NES. "" THEN -
|
||||
CCDISABLEWARNINGS = CCDISABLEWARNINGS+ ","
|
||||
$ CCDISABLEWARNINGS = CCDISABLEWARNINGS+ OPT_TEST
|
||||
$ ENDIF
|
||||
$ IF CCDISABLEWARNINGS .NES. ""
|
||||
$ THEN
|
||||
$ CCDISABLEWARNINGS = " /WARNING=(DISABLE=(" + CCDISABLEWARNINGS + "))"
|
||||
|
||||
89
apps/ocsp.c
89
apps/ocsp.c
@@ -583,51 +583,52 @@ int MAIN(int argc, char **argv)
|
||||
BIO_printf (bio_err, "OCSP utility\n");
|
||||
BIO_printf (bio_err, "Usage ocsp [options]\n");
|
||||
BIO_printf (bio_err, "where options are\n");
|
||||
BIO_printf (bio_err, "-out file output filename\n");
|
||||
BIO_printf (bio_err, "-issuer file issuer certificate\n");
|
||||
BIO_printf (bio_err, "-cert file certificate to check\n");
|
||||
BIO_printf (bio_err, "-serial n serial number to check\n");
|
||||
BIO_printf (bio_err, "-signer file certificate to sign OCSP request with\n");
|
||||
BIO_printf (bio_err, "-signkey file private key to sign OCSP request with\n");
|
||||
BIO_printf (bio_err, "-sign_other file additional certificates to include in signed request\n");
|
||||
BIO_printf (bio_err, "-no_certs don't include any certificates in signed request\n");
|
||||
BIO_printf (bio_err, "-req_text print text form of request\n");
|
||||
BIO_printf (bio_err, "-resp_text print text form of response\n");
|
||||
BIO_printf (bio_err, "-text print text form of request and response\n");
|
||||
BIO_printf (bio_err, "-reqout file write DER encoded OCSP request to \"file\"\n");
|
||||
BIO_printf (bio_err, "-respout file write DER encoded OCSP reponse to \"file\"\n");
|
||||
BIO_printf (bio_err, "-reqin file read DER encoded OCSP request from \"file\"\n");
|
||||
BIO_printf (bio_err, "-respin file read DER encoded OCSP reponse from \"file\"\n");
|
||||
BIO_printf (bio_err, "-nonce add OCSP nonce to request\n");
|
||||
BIO_printf (bio_err, "-no_nonce don't add OCSP nonce to request\n");
|
||||
BIO_printf (bio_err, "-url URL OCSP responder URL\n");
|
||||
BIO_printf (bio_err, "-host host:n send OCSP request to host on port n\n");
|
||||
BIO_printf (bio_err, "-path path to use in OCSP request\n");
|
||||
BIO_printf (bio_err, "-CApath dir trusted certificates directory\n");
|
||||
BIO_printf (bio_err, "-CAfile file trusted certificates file\n");
|
||||
BIO_printf (bio_err, "-VAfile file validator certificates file\n");
|
||||
BIO_printf (bio_err, "-validity_period n maximum validity discrepancy in seconds\n");
|
||||
BIO_printf (bio_err, "-status_age n maximum status age in seconds\n");
|
||||
BIO_printf (bio_err, "-noverify don't verify response at all\n");
|
||||
BIO_printf (bio_err, "-verify_other file additional certificates to search for signer\n");
|
||||
BIO_printf (bio_err, "-trust_other don't verify additional certificates\n");
|
||||
BIO_printf (bio_err, "-no_intern don't search certificates contained in response for signer\n");
|
||||
BIO_printf (bio_err, "-out file output filename\n");
|
||||
BIO_printf (bio_err, "-issuer file issuer certificate\n");
|
||||
BIO_printf (bio_err, "-cert file certificate to check\n");
|
||||
BIO_printf (bio_err, "-serial n serial number to check\n");
|
||||
BIO_printf (bio_err, "-signer file certificate to sign OCSP request with\n");
|
||||
BIO_printf (bio_err, "-signkey file private key to sign OCSP request with\n");
|
||||
BIO_printf (bio_err, "-sign_other file additional certificates to include in signed request\n");
|
||||
BIO_printf (bio_err, "-no_certs don't include any certificates in signed request\n");
|
||||
BIO_printf (bio_err, "-req_text print text form of request\n");
|
||||
BIO_printf (bio_err, "-resp_text print text form of response\n");
|
||||
BIO_printf (bio_err, "-text print text form of request and response\n");
|
||||
BIO_printf (bio_err, "-reqout file write DER encoded OCSP request to \"file\"\n");
|
||||
BIO_printf (bio_err, "-respout file write DER encoded OCSP reponse to \"file\"\n");
|
||||
BIO_printf (bio_err, "-reqin file read DER encoded OCSP request from \"file\"\n");
|
||||
BIO_printf (bio_err, "-respin file read DER encoded OCSP reponse from \"file\"\n");
|
||||
BIO_printf (bio_err, "-nonce add OCSP nonce to request\n");
|
||||
BIO_printf (bio_err, "-no_nonce don't add OCSP nonce to request\n");
|
||||
BIO_printf (bio_err, "-url URL OCSP responder URL\n");
|
||||
BIO_printf (bio_err, "-host host:n send OCSP request to host on port n\n");
|
||||
BIO_printf (bio_err, "-path path to use in OCSP request\n");
|
||||
BIO_printf (bio_err, "-CApath dir trusted certificates directory\n");
|
||||
BIO_printf (bio_err, "-CAfile file trusted certificates file\n");
|
||||
BIO_printf (bio_err, "-VAfile file validator certificates file\n");
|
||||
BIO_printf (bio_err, "-validity_period n maximum validity discrepancy in seconds\n");
|
||||
BIO_printf (bio_err, "-status_age n maximum status age in seconds\n");
|
||||
BIO_printf (bio_err, "-noverify don't verify response at all\n");
|
||||
BIO_printf (bio_err, "-verify_other file additional certificates to search for signer\n");
|
||||
BIO_printf (bio_err, "-trust_other don't verify additional certificates\n");
|
||||
BIO_printf (bio_err, "-no_intern don't search certificates contained in response for signer\n");
|
||||
BIO_printf (bio_err, "-no_signature_verify don't check signature on response\n");
|
||||
BIO_printf (bio_err, "-no_cert_verify don't check signing certificate\n");
|
||||
BIO_printf (bio_err, "-no_chain don't chain verify response\n");
|
||||
BIO_printf (bio_err, "-no_cert_checks don't do additional checks on signing certificate\n");
|
||||
BIO_printf (bio_err, "-port num port to run responder on\n");
|
||||
BIO_printf (bio_err, "-index file certificate status index file\n");
|
||||
BIO_printf (bio_err, "-CA file CA certificate\n");
|
||||
BIO_printf (bio_err, "-rsigner file responder certificate to sign responses with\n");
|
||||
BIO_printf (bio_err, "-rkey file responder key to sign responses with\n");
|
||||
BIO_printf (bio_err, "-rother file other certificates to include in response\n");
|
||||
BIO_printf (bio_err, "-resp_no_certs don't include any certificates in response\n");
|
||||
BIO_printf (bio_err, "-nmin n number of minutes before next update\n");
|
||||
BIO_printf (bio_err, "-ndays n number of days before next update\n");
|
||||
BIO_printf (bio_err, "-resp_key_id identify reponse by signing certificate key ID\n");
|
||||
BIO_printf (bio_err, "-nrequest n number of requests to accept (default unlimited)\n");
|
||||
BIO_printf (bio_err, "-<dgst alg> use specified digest in the request\n");
|
||||
BIO_printf (bio_err, "-no_cert_verify don't check signing certificate\n");
|
||||
BIO_printf (bio_err, "-no_chain don't chain verify response\n");
|
||||
BIO_printf (bio_err, "-no_cert_checks don't do additional checks on signing certificate\n");
|
||||
BIO_printf (bio_err, "-port num port to run responder on\n");
|
||||
BIO_printf (bio_err, "-index file certificate status index file\n");
|
||||
BIO_printf (bio_err, "-CA file CA certificate\n");
|
||||
BIO_printf (bio_err, "-rsigner file responder certificate to sign responses with\n");
|
||||
BIO_printf (bio_err, "-rkey file responder key to sign responses with\n");
|
||||
BIO_printf (bio_err, "-rother file other certificates to include in response\n");
|
||||
BIO_printf (bio_err, "-resp_no_certs don't include any certificates in response\n");
|
||||
BIO_printf (bio_err, "-nmin n number of minutes before next update\n");
|
||||
BIO_printf (bio_err, "-ndays n number of days before next update\n");
|
||||
BIO_printf (bio_err, "-resp_key_id identify reponse by signing certificate key ID\n");
|
||||
BIO_printf (bio_err, "-nrequest n number of requests to accept (default unlimited)\n");
|
||||
BIO_printf (bio_err, "-<dgst alg> use specified digest in the request\n");
|
||||
BIO_printf (bio_err, "-timeout n timeout connection to OCSP responder after n seconds\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
||||
@@ -322,6 +322,7 @@ static void sc_usage(void)
|
||||
BIO_printf(bio_err," -ssl3 - just use SSLv3\n");
|
||||
BIO_printf(bio_err," -tls1 - just use TLSv1\n");
|
||||
BIO_printf(bio_err," -dtls1 - just use DTLSv1\n");
|
||||
BIO_printf(bio_err," -fallback_scsv - send TLS_FALLBACK_SCSV\n");
|
||||
BIO_printf(bio_err," -mtu - set the link layer MTU\n");
|
||||
BIO_printf(bio_err," -no_tls1/-no_ssl3/-no_ssl2 - turn off that protocol\n");
|
||||
BIO_printf(bio_err," -bugs - Switch on all SSL implementation bug workarounds\n");
|
||||
@@ -436,6 +437,7 @@ int MAIN(int argc, char **argv)
|
||||
char *sess_out = NULL;
|
||||
struct sockaddr peer;
|
||||
int peerlen = sizeof(peer);
|
||||
int fallback_scsv = 0;
|
||||
int enable_timeouts = 0 ;
|
||||
long socket_mtu = 0;
|
||||
#ifndef OPENSSL_NO_JPAKE
|
||||
@@ -610,6 +612,10 @@ int MAIN(int argc, char **argv)
|
||||
socket_mtu = atol(*(++argv));
|
||||
}
|
||||
#endif
|
||||
else if (strcmp(*argv,"-fallback_scsv") == 0)
|
||||
{
|
||||
fallback_scsv = 1;
|
||||
}
|
||||
else if (strcmp(*argv,"-bugs") == 0)
|
||||
bugs=1;
|
||||
else if (strcmp(*argv,"-keyform") == 0)
|
||||
@@ -935,6 +941,10 @@ bad:
|
||||
SSL_set_session(con, sess);
|
||||
SSL_SESSION_free(sess);
|
||||
}
|
||||
|
||||
if (fallback_scsv)
|
||||
SSL_set_mode(con, SSL_MODE_SEND_FALLBACK_SCSV);
|
||||
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
if (servername != NULL)
|
||||
{
|
||||
@@ -1008,10 +1018,22 @@ re_start:
|
||||
BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
|
||||
}
|
||||
|
||||
if (socket_mtu > 28)
|
||||
if (socket_mtu)
|
||||
{
|
||||
if(socket_mtu < DTLS_get_link_min_mtu(con))
|
||||
{
|
||||
BIO_printf(bio_err,"MTU too small. Must be at least %ld\n",
|
||||
DTLS_get_link_min_mtu(con));
|
||||
BIO_free(sbio);
|
||||
goto shut;
|
||||
}
|
||||
SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
|
||||
SSL_set_mtu(con, socket_mtu - 28);
|
||||
if(!DTLS_set_link_mtu(con, socket_mtu))
|
||||
{
|
||||
BIO_printf(bio_err, "Failed to set MTU\n");
|
||||
BIO_free(sbio);
|
||||
goto shut;
|
||||
}
|
||||
}
|
||||
else
|
||||
/* want to do MTU discovery */
|
||||
|
||||
@@ -1856,10 +1856,24 @@ static int sv_body(char *hostname, int s, unsigned char *context)
|
||||
BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
|
||||
}
|
||||
|
||||
if (socket_mtu > 28)
|
||||
if (socket_mtu)
|
||||
{
|
||||
if(socket_mtu < DTLS_get_link_min_mtu(con))
|
||||
{
|
||||
BIO_printf(bio_err,"MTU too small. Must be at least %ld\n",
|
||||
DTLS_get_link_min_mtu(con));
|
||||
ret = -1;
|
||||
BIO_free(sbio);
|
||||
goto err;
|
||||
}
|
||||
SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
|
||||
SSL_set_mtu(con, socket_mtu - 28);
|
||||
if(!DTLS_set_link_mtu(con, socket_mtu))
|
||||
{
|
||||
BIO_printf(bio_err, "Failed to set MTU\n");
|
||||
ret = -1;
|
||||
BIO_free(sbio);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
else
|
||||
/* want to do MTU discovery */
|
||||
|
||||
21
apps/speed.c
21
apps/speed.c
@@ -2678,27 +2678,6 @@ static int do_multi(int multi)
|
||||
k=atoi(sstrsep(&p,sep));
|
||||
sstrsep(&p,sep);
|
||||
|
||||
d=atof(sstrsep(&p,sep));
|
||||
if(n)
|
||||
rsa_results[k][0]=1/(1/rsa_results[k][0]+1/d);
|
||||
else
|
||||
rsa_results[k][0]=d;
|
||||
|
||||
d=atof(sstrsep(&p,sep));
|
||||
if(n)
|
||||
rsa_results[k][1]=1/(1/rsa_results[k][1]+1/d);
|
||||
else
|
||||
rsa_results[k][1]=d;
|
||||
}
|
||||
else if(!strncmp(buf,"+F2:",4))
|
||||
{
|
||||
int k;
|
||||
double d;
|
||||
|
||||
p=buf+4;
|
||||
k=atoi(sstrsep(&p,sep));
|
||||
sstrsep(&p,sep);
|
||||
|
||||
d=atof(sstrsep(&p,sep));
|
||||
if(n)
|
||||
rsa_results[k][0]=1/(1/rsa_results[k][0]+1/d);
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* $LP: LPlib/source/LPdir_vms.c,v 1.20 2004/08/26 13:36:05 _cvs_levitte Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2004, Richard Levitte <richard@levitte.org>
|
||||
* All rights reserved.
|
||||
@@ -88,6 +87,12 @@ const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
|
||||
size_t filespeclen = strlen(directory);
|
||||
char *filespec = NULL;
|
||||
|
||||
if (filespeclen == 0)
|
||||
{
|
||||
errno = ENOENT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* MUST be a VMS directory specification! Let's estimate if it is. */
|
||||
if (directory[filespeclen-1] != ']'
|
||||
&& directory[filespeclen-1] != '>'
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* $LP: LPlib/source/LPdir_win.c,v 1.10 2004/08/26 13:36:05 _cvs_levitte Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2004, Richard Levitte <richard@levitte.org>
|
||||
* All rights reserved.
|
||||
@@ -37,7 +36,7 @@
|
||||
#if defined(LP_SYS_WINCE) && !defined(FindFirstFile)
|
||||
# define FindFirstFile FindFirstFileW
|
||||
#endif
|
||||
#if defined(LP_SYS_WINCE) && !defined(FindFirstFile)
|
||||
#if defined(LP_SYS_WINCE) && !defined(FindNextFile)
|
||||
# define FindNextFile FindNextFileW
|
||||
#endif
|
||||
|
||||
@@ -63,6 +62,16 @@ const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
|
||||
errno = 0;
|
||||
if (*ctx == NULL)
|
||||
{
|
||||
const char *extdir = directory;
|
||||
char *extdirbuf = NULL;
|
||||
size_t dirlen = strlen (directory);
|
||||
|
||||
if (dirlen == 0)
|
||||
{
|
||||
errno = ENOENT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*ctx = (LP_DIR_CTX *)malloc(sizeof(LP_DIR_CTX));
|
||||
if (*ctx == NULL)
|
||||
{
|
||||
@@ -71,15 +80,35 @@ const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
|
||||
}
|
||||
memset(*ctx, '\0', sizeof(LP_DIR_CTX));
|
||||
|
||||
if (directory[dirlen-1] != '*')
|
||||
{
|
||||
extdirbuf = (char *)malloc(dirlen + 3);
|
||||
if (extdirbuf == NULL)
|
||||
{
|
||||
free(*ctx);
|
||||
*ctx = NULL;
|
||||
errno = ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
if (directory[dirlen-1] != '/' && directory[dirlen-1] != '\\')
|
||||
extdir = strcat(strcpy (extdirbuf,directory),"/*");
|
||||
else
|
||||
extdir = strcat(strcpy (extdirbuf,directory),"*");
|
||||
}
|
||||
|
||||
if (sizeof(TCHAR) != sizeof(char))
|
||||
{
|
||||
TCHAR *wdir = NULL;
|
||||
/* len_0 denotes string length *with* trailing 0 */
|
||||
size_t index = 0,len_0 = strlen(directory) + 1;
|
||||
size_t index = 0,len_0 = strlen(extdir) + 1;
|
||||
|
||||
wdir = (TCHAR *)malloc(len_0 * sizeof(TCHAR));
|
||||
wdir = (TCHAR *)calloc(len_0, sizeof(TCHAR));
|
||||
if (wdir == NULL)
|
||||
{
|
||||
if (extdirbuf != NULL)
|
||||
{
|
||||
free (extdirbuf);
|
||||
}
|
||||
free(*ctx);
|
||||
*ctx = NULL;
|
||||
errno = ENOMEM;
|
||||
@@ -87,17 +116,23 @@ const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
|
||||
}
|
||||
|
||||
#ifdef LP_MULTIBYTE_AVAILABLE
|
||||
if (!MultiByteToWideChar(CP_ACP, 0, directory, len_0, (WCHAR *)wdir, len_0))
|
||||
if (!MultiByteToWideChar(CP_ACP, 0, extdir, len_0, (WCHAR *)wdir, len_0))
|
||||
#endif
|
||||
for (index = 0; index < len_0; index++)
|
||||
wdir[index] = (TCHAR)directory[index];
|
||||
wdir[index] = (TCHAR)extdir[index];
|
||||
|
||||
(*ctx)->handle = FindFirstFile(wdir, &(*ctx)->ctx);
|
||||
|
||||
free(wdir);
|
||||
}
|
||||
else
|
||||
(*ctx)->handle = FindFirstFile((TCHAR *)directory, &(*ctx)->ctx);
|
||||
{
|
||||
(*ctx)->handle = FindFirstFile((TCHAR *)extdir, &(*ctx)->ctx);
|
||||
}
|
||||
if (extdirbuf != NULL)
|
||||
{
|
||||
free (extdirbuf);
|
||||
}
|
||||
|
||||
if ((*ctx)->handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
@@ -114,7 +149,6 @@ const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (sizeof(TCHAR) != sizeof(char))
|
||||
{
|
||||
TCHAR *wdir = (*ctx)->ctx.cFileName;
|
||||
|
||||
@@ -31,6 +31,7 @@ CPUID_OBJ=mem_clr.o
|
||||
LIBS=
|
||||
|
||||
GENERAL=Makefile README crypto-lib.com install.com
|
||||
TEST=constant_time_test.c
|
||||
|
||||
LIB= $(TOP)/libcrypto.a
|
||||
SHARED_LIB= libcrypto$(SHLIB_EXT)
|
||||
@@ -41,7 +42,8 @@ SRC= $(LIBSRC)
|
||||
|
||||
EXHEADER= crypto.h opensslv.h opensslconf.h ebcdic.h symhacks.h \
|
||||
ossl_typ.h
|
||||
HEADER= cryptlib.h buildinf.h md32_common.h o_time.h o_str.h o_dir.h $(EXHEADER)
|
||||
HEADER= cryptlib.h buildinf.h md32_common.h o_time.h o_str.h o_dir.h \
|
||||
constant_time_locl.h $(EXHEADER)
|
||||
|
||||
ALL= $(GENERAL) $(SRC) $(HEADER)
|
||||
|
||||
@@ -51,12 +53,7 @@ top:
|
||||
all: shared
|
||||
|
||||
buildinf.h: ../Makefile
|
||||
( echo "#ifndef MK1MF_BUILD"; \
|
||||
echo ' /* auto-generated by crypto/Makefile for crypto/cversion.c */'; \
|
||||
echo ' #define CFLAGS "$(CC) $(CFLAG)"'; \
|
||||
echo ' #define PLATFORM "$(PLATFORM)"'; \
|
||||
echo " #define DATE \"`LC_ALL=C LC_TIME=C date`\""; \
|
||||
echo '#endif' ) >buildinf.h
|
||||
$(PERL) $(TOP)/util/mkbuildinf.pl "$(CFLAGS)" "$(PLATFORM)" >buildinf.h
|
||||
|
||||
x86cpuid.s: x86cpuid.pl perlasm/x86asm.pl
|
||||
$(PERL) x86cpuid.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@
|
||||
|
||||
@@ -136,11 +136,16 @@ ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
|
||||
|
||||
p= *pp;
|
||||
i= *(p++);
|
||||
if (i > 7)
|
||||
{
|
||||
i=ASN1_R_INVALID_BIT_STRING_BITS_LEFT;
|
||||
goto err;
|
||||
}
|
||||
/* We do this to preserve the settings. If we modify
|
||||
* the settings, via the _set_bit function, we will recalculate
|
||||
* on output */
|
||||
ret->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */
|
||||
ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|(i&0x07)); /* set */
|
||||
ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|i); /* set */
|
||||
|
||||
if (len-- > 1) /* using one because of the bits left byte */
|
||||
{
|
||||
|
||||
@@ -113,7 +113,7 @@ IMPLEMENT_STACK_OF(ASN1_TYPE)
|
||||
IMPLEMENT_ASN1_SET_OF(ASN1_TYPE)
|
||||
|
||||
/* Returns 0 if they are equal, != 0 otherwise. */
|
||||
int ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b)
|
||||
int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b)
|
||||
{
|
||||
int result = -1;
|
||||
|
||||
|
||||
@@ -90,6 +90,12 @@ int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature,
|
||||
ASN1err(ASN1_F_ASN1_VERIFY,ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
|
||||
goto err;
|
||||
}
|
||||
|
||||
inl=i2d(data,NULL);
|
||||
buf_in=OPENSSL_malloc((unsigned int)inl);
|
||||
@@ -142,6 +148,12 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, ASN1_BIT_STRING *signat
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
EVP_MD_CTX_init(&ctx);
|
||||
|
||||
/* Convert signature OID into digest and public key OIDs */
|
||||
|
||||
@@ -777,7 +777,7 @@ DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE)
|
||||
int ASN1_TYPE_get(ASN1_TYPE *a);
|
||||
void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value);
|
||||
int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value);
|
||||
int ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b);
|
||||
int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b);
|
||||
|
||||
ASN1_OBJECT * ASN1_OBJECT_new(void );
|
||||
void ASN1_OBJECT_free(ASN1_OBJECT *a);
|
||||
@@ -1327,6 +1327,7 @@ void ERR_load_ASN1_strings(void);
|
||||
#define ASN1_R_ILLEGAL_TIME_VALUE 184
|
||||
#define ASN1_R_INTEGER_NOT_ASCII_FORMAT 185
|
||||
#define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 128
|
||||
#define ASN1_R_INVALID_BIT_STRING_BITS_LEFT 220
|
||||
#define ASN1_R_INVALID_BMPSTRING_LENGTH 129
|
||||
#define ASN1_R_INVALID_DIGIT 130
|
||||
#define ASN1_R_INVALID_MIME_TYPE 205
|
||||
@@ -1376,6 +1377,7 @@ void ERR_load_ASN1_strings(void);
|
||||
#define ASN1_R_TIME_NOT_ASCII_FORMAT 193
|
||||
#define ASN1_R_TOO_LONG 155
|
||||
#define ASN1_R_TYPE_NOT_CONSTRUCTED 156
|
||||
#define ASN1_R_TYPE_NOT_PRIMITIVE 218
|
||||
#define ASN1_R_UNABLE_TO_DECODE_RSA_KEY 157
|
||||
#define ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY 158
|
||||
#define ASN1_R_UNEXPECTED_EOC 159
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* crypto/asn1/asn1_err.c */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999-2009 The OpenSSL Project. All rights reserved.
|
||||
* Copyright (c) 1999-2014 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@@ -243,6 +243,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
|
||||
{ERR_REASON(ASN1_R_ILLEGAL_TIME_VALUE) ,"illegal time value"},
|
||||
{ERR_REASON(ASN1_R_INTEGER_NOT_ASCII_FORMAT),"integer not ascii format"},
|
||||
{ERR_REASON(ASN1_R_INTEGER_TOO_LARGE_FOR_LONG),"integer too large for long"},
|
||||
{ERR_REASON(ASN1_R_INVALID_BIT_STRING_BITS_LEFT),"invalid bit string bits left"},
|
||||
{ERR_REASON(ASN1_R_INVALID_BMPSTRING_LENGTH),"invalid bmpstring length"},
|
||||
{ERR_REASON(ASN1_R_INVALID_DIGIT) ,"invalid digit"},
|
||||
{ERR_REASON(ASN1_R_INVALID_MIME_TYPE) ,"invalid mime type"},
|
||||
@@ -292,6 +293,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
|
||||
{ERR_REASON(ASN1_R_TIME_NOT_ASCII_FORMAT),"time not ascii format"},
|
||||
{ERR_REASON(ASN1_R_TOO_LONG) ,"too long"},
|
||||
{ERR_REASON(ASN1_R_TYPE_NOT_CONSTRUCTED) ,"type not constructed"},
|
||||
{ERR_REASON(ASN1_R_TYPE_NOT_PRIMITIVE) ,"type not primitive"},
|
||||
{ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_KEY),"unable to decode rsa key"},
|
||||
{ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY),"unable to decode rsa private key"},
|
||||
{ERR_REASON(ASN1_R_UNEXPECTED_EOC) ,"unexpected eoc"},
|
||||
|
||||
@@ -870,6 +870,14 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
|
||||
}
|
||||
else if (cst)
|
||||
{
|
||||
if (utype == V_ASN1_NULL || utype == V_ASN1_BOOLEAN
|
||||
|| utype == V_ASN1_OBJECT || utype == V_ASN1_INTEGER
|
||||
|| utype == V_ASN1_ENUMERATED)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
|
||||
ASN1_R_TYPE_NOT_PRIMITIVE);
|
||||
return 0;
|
||||
}
|
||||
buf.length = 0;
|
||||
buf.max = 0;
|
||||
buf.data = NULL;
|
||||
|
||||
@@ -128,3 +128,13 @@ void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
|
||||
}
|
||||
}
|
||||
|
||||
int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b)
|
||||
{
|
||||
int rv;
|
||||
rv = OBJ_cmp(a->algorithm, b->algorithm);
|
||||
if (rv)
|
||||
return rv;
|
||||
if (!a->parameter && !b->parameter)
|
||||
return 0;
|
||||
return ASN1_TYPE_cmp(a->parameter, b->parameter);
|
||||
}
|
||||
|
||||
@@ -162,7 +162,8 @@ extern "C" {
|
||||
#define BIO_CTRL_DGRAM_SET_PEER 44 /* Destination for the data */
|
||||
|
||||
#define BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT 45 /* Next DTLS handshake timeout to
|
||||
* adjust socket timeouts */
|
||||
* adjust socket timeouts */
|
||||
#define BIO_CTRL_DGRAM_GET_MTU_OVERHEAD 49
|
||||
|
||||
/* modifiers */
|
||||
#define BIO_FP_READ 0x02
|
||||
@@ -553,6 +554,8 @@ int BIO_ctrl_reset_read_request(BIO *b);
|
||||
(int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_PEER, 0, (char *)peer)
|
||||
#define BIO_dgram_set_peer(b,peer) \
|
||||
(int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, (char *)peer)
|
||||
#define BIO_dgram_get_mtu_overhead(b) \
|
||||
(unsigned int)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_MTU_OVERHEAD, 0, NULL)
|
||||
|
||||
/* These two aren't currently implemented */
|
||||
/* int BIO_get_ex_num(BIO *bio); */
|
||||
|
||||
@@ -375,6 +375,36 @@ static int dgram_write(BIO *b, const char *in, int inl)
|
||||
return(ret);
|
||||
}
|
||||
|
||||
static long dgram_get_mtu_overhead(bio_dgram_data *data)
|
||||
{
|
||||
long ret;
|
||||
|
||||
switch (data->peer.sa.sa_family)
|
||||
{
|
||||
case AF_INET:
|
||||
/* Assume this is UDP - 20 bytes for IP, 8 bytes for UDP */
|
||||
ret = 28;
|
||||
break;
|
||||
#if OPENSSL_USE_IPV6
|
||||
case AF_INET6:
|
||||
#ifdef IN6_IS_ADDR_V4MAPPED
|
||||
if (IN6_IS_ADDR_V4MAPPED(&data->peer.sa_in6.sin6_addr))
|
||||
/* Assume this is UDP - 20 bytes for IP, 8 bytes for UDP */
|
||||
ret = 28;
|
||||
else
|
||||
#endif
|
||||
/* Assume this is UDP - 40 bytes for IP, 8 bytes for UDP */
|
||||
ret = 48;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
/* We don't know. Go with the historical default */
|
||||
ret = 28;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
|
||||
{
|
||||
long ret=1;
|
||||
@@ -551,23 +581,24 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
|
||||
#endif
|
||||
break;
|
||||
case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
|
||||
ret = -dgram_get_mtu_overhead(data);
|
||||
switch (data->peer.sa.sa_family)
|
||||
{
|
||||
case AF_INET:
|
||||
ret = 576 - 20 - 8;
|
||||
ret += 576;
|
||||
break;
|
||||
#if OPENSSL_USE_IPV6
|
||||
case AF_INET6:
|
||||
#ifdef IN6_IS_ADDR_V4MAPPED
|
||||
if (IN6_IS_ADDR_V4MAPPED(&data->peer.sa_in6.sin6_addr))
|
||||
ret = 576 - 20 - 8;
|
||||
ret += 576;
|
||||
else
|
||||
#endif
|
||||
ret = 1280 - 40 - 8;
|
||||
ret += 1280;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ret = 576 - 20 - 8;
|
||||
ret += 576;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -768,6 +799,9 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
|
||||
ret = 0;
|
||||
break;
|
||||
#endif
|
||||
case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
|
||||
ret = dgram_get_mtu_overhead(data);
|
||||
break;
|
||||
default:
|
||||
ret=0;
|
||||
break;
|
||||
|
||||
@@ -1584,17 +1584,17 @@ LEAF(bn_sqr_comba8)
|
||||
dmultu a_2,a_0 /* mul_add_c2(a[2],b[0],c3,c1,c2); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
slt c_2,t_2,zero
|
||||
dsll t_2,1
|
||||
slt a2,t_1,zero
|
||||
daddu t_2,a2
|
||||
dsll t_1,1
|
||||
daddu c_3,t_1
|
||||
sltu AT,c_3,t_1
|
||||
daddu t_2,AT
|
||||
daddu c_3,t_1
|
||||
daddu AT,t_2
|
||||
sltu t_1,c_3,t_1
|
||||
daddu c_1,AT
|
||||
daddu t_2,t_1
|
||||
sltu c_2,c_1,AT
|
||||
daddu c_1,t_2
|
||||
sltu AT,c_1,t_2
|
||||
daddu c_2,AT
|
||||
sltu t_2,c_1,t_2
|
||||
daddu c_2,t_2
|
||||
dmultu a_1,a_1 /* mul_add_c(a[1],b[1],c3,c1,c2); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
@@ -1609,63 +1609,63 @@ LEAF(bn_sqr_comba8)
|
||||
dmultu a_0,a_3 /* mul_add_c2(a[0],b[3],c1,c2,c3); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
slt c_3,t_2,zero
|
||||
dsll t_2,1
|
||||
slt a2,t_1,zero
|
||||
daddu t_2,a2
|
||||
dsll t_1,1
|
||||
daddu c_1,t_1
|
||||
sltu AT,c_1,t_1
|
||||
daddu t_2,AT
|
||||
daddu c_1,t_1
|
||||
daddu AT,t_2
|
||||
sltu t_1,c_1,t_1
|
||||
daddu c_2,AT
|
||||
daddu t_2,t_1
|
||||
sltu c_3,c_2,AT
|
||||
daddu c_2,t_2
|
||||
sltu AT,c_2,t_2
|
||||
daddu c_3,AT
|
||||
sltu t_2,c_2,t_2
|
||||
daddu c_3,t_2
|
||||
dmultu a_1,a_2 /* mul_add_c2(a[1],b[2],c1,c2,c3); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
slt AT,t_2,zero
|
||||
daddu c_3,AT
|
||||
dsll t_2,1
|
||||
slt a2,t_1,zero
|
||||
daddu t_2,a2
|
||||
dsll t_1,1
|
||||
daddu c_1,t_1
|
||||
sltu AT,c_1,t_1
|
||||
daddu t_2,AT
|
||||
daddu c_1,t_1
|
||||
daddu AT,t_2
|
||||
sltu t_1,c_1,t_1
|
||||
daddu c_2,AT
|
||||
daddu t_2,t_1
|
||||
sltu AT,c_2,AT
|
||||
daddu c_2,t_2
|
||||
sltu AT,c_2,t_2
|
||||
daddu c_3,AT
|
||||
sltu t_2,c_2,t_2
|
||||
daddu c_3,t_2
|
||||
sd c_1,24(a0)
|
||||
|
||||
dmultu a_4,a_0 /* mul_add_c2(a[4],b[0],c2,c3,c1); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
slt c_1,t_2,zero
|
||||
dsll t_2,1
|
||||
slt a2,t_1,zero
|
||||
daddu t_2,a2
|
||||
dsll t_1,1
|
||||
daddu c_2,t_1
|
||||
sltu AT,c_2,t_1
|
||||
daddu t_2,AT
|
||||
daddu c_2,t_1
|
||||
daddu AT,t_2
|
||||
sltu t_1,c_2,t_1
|
||||
daddu c_3,AT
|
||||
daddu t_2,t_1
|
||||
sltu c_1,c_3,AT
|
||||
daddu c_3,t_2
|
||||
sltu AT,c_3,t_2
|
||||
daddu c_1,AT
|
||||
sltu t_2,c_3,t_2
|
||||
daddu c_1,t_2
|
||||
dmultu a_3,a_1 /* mul_add_c2(a[3],b[1],c2,c3,c1); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
slt AT,t_2,zero
|
||||
daddu c_1,AT
|
||||
dsll t_2,1
|
||||
slt a2,t_1,zero
|
||||
daddu t_2,a2
|
||||
dsll t_1,1
|
||||
daddu c_2,t_1
|
||||
sltu AT,c_2,t_1
|
||||
daddu t_2,AT
|
||||
daddu c_2,t_1
|
||||
daddu AT,t_2
|
||||
sltu t_1,c_2,t_1
|
||||
daddu c_3,AT
|
||||
daddu t_2,t_1
|
||||
sltu AT,c_3,AT
|
||||
daddu c_3,t_2
|
||||
sltu AT,c_3,t_2
|
||||
daddu c_1,AT
|
||||
sltu t_2,c_3,t_2
|
||||
daddu c_1,t_2
|
||||
dmultu a_2,a_2 /* mul_add_c(a[2],b[2],c2,c3,c1); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
@@ -1680,93 +1680,93 @@ LEAF(bn_sqr_comba8)
|
||||
dmultu a_0,a_5 /* mul_add_c2(a[0],b[5],c3,c1,c2); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
slt c_2,t_2,zero
|
||||
dsll t_2,1
|
||||
slt a2,t_1,zero
|
||||
daddu t_2,a2
|
||||
dsll t_1,1
|
||||
daddu c_3,t_1
|
||||
sltu AT,c_3,t_1
|
||||
daddu t_2,AT
|
||||
daddu c_3,t_1
|
||||
daddu AT,t_2
|
||||
sltu t_1,c_3,t_1
|
||||
daddu c_1,AT
|
||||
daddu t_2,t_1
|
||||
sltu c_2,c_1,AT
|
||||
daddu c_1,t_2
|
||||
sltu AT,c_1,t_2
|
||||
daddu c_2,AT
|
||||
sltu t_2,c_1,t_2
|
||||
daddu c_2,t_2
|
||||
dmultu a_1,a_4 /* mul_add_c2(a[1],b[4],c3,c1,c2); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
slt AT,t_2,zero
|
||||
daddu c_2,AT
|
||||
dsll t_2,1
|
||||
slt a2,t_1,zero
|
||||
daddu t_2,a2
|
||||
dsll t_1,1
|
||||
daddu c_3,t_1
|
||||
sltu AT,c_3,t_1
|
||||
daddu t_2,AT
|
||||
daddu c_3,t_1
|
||||
daddu AT,t_2
|
||||
sltu t_1,c_3,t_1
|
||||
daddu c_1,AT
|
||||
daddu t_2,t_1
|
||||
sltu AT,c_1,AT
|
||||
daddu c_1,t_2
|
||||
sltu AT,c_1,t_2
|
||||
daddu c_2,AT
|
||||
sltu t_2,c_1,t_2
|
||||
daddu c_2,t_2
|
||||
dmultu a_2,a_3 /* mul_add_c2(a[2],b[3],c3,c1,c2); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
slt AT,t_2,zero
|
||||
daddu c_2,AT
|
||||
dsll t_2,1
|
||||
slt a2,t_1,zero
|
||||
daddu t_2,a2
|
||||
dsll t_1,1
|
||||
daddu c_3,t_1
|
||||
sltu AT,c_3,t_1
|
||||
daddu t_2,AT
|
||||
daddu c_3,t_1
|
||||
daddu AT,t_2
|
||||
sltu t_1,c_3,t_1
|
||||
daddu c_1,AT
|
||||
daddu t_2,t_1
|
||||
sltu AT,c_1,AT
|
||||
daddu c_1,t_2
|
||||
sltu AT,c_1,t_2
|
||||
daddu c_2,AT
|
||||
sltu t_2,c_1,t_2
|
||||
daddu c_2,t_2
|
||||
sd c_3,40(a0)
|
||||
|
||||
dmultu a_6,a_0 /* mul_add_c2(a[6],b[0],c1,c2,c3); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
slt c_3,t_2,zero
|
||||
dsll t_2,1
|
||||
slt a2,t_1,zero
|
||||
daddu t_2,a2
|
||||
dsll t_1,1
|
||||
daddu c_1,t_1
|
||||
sltu AT,c_1,t_1
|
||||
daddu t_2,AT
|
||||
daddu c_1,t_1
|
||||
daddu AT,t_2
|
||||
sltu t_1,c_1,t_1
|
||||
daddu c_2,AT
|
||||
daddu t_2,t_1
|
||||
sltu c_3,c_2,AT
|
||||
daddu c_2,t_2
|
||||
sltu AT,c_2,t_2
|
||||
daddu c_3,AT
|
||||
sltu t_2,c_2,t_2
|
||||
daddu c_3,t_2
|
||||
dmultu a_5,a_1 /* mul_add_c2(a[5],b[1],c1,c2,c3); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
slt AT,t_2,zero
|
||||
daddu c_3,AT
|
||||
dsll t_2,1
|
||||
slt a2,t_1,zero
|
||||
daddu t_2,a2
|
||||
dsll t_1,1
|
||||
daddu c_1,t_1
|
||||
sltu AT,c_1,t_1
|
||||
daddu t_2,AT
|
||||
daddu c_1,t_1
|
||||
daddu AT,t_2
|
||||
sltu t_1,c_1,t_1
|
||||
daddu c_2,AT
|
||||
daddu t_2,t_1
|
||||
sltu AT,c_2,AT
|
||||
daddu c_2,t_2
|
||||
sltu AT,c_2,t_2
|
||||
daddu c_3,AT
|
||||
sltu t_2,c_2,t_2
|
||||
daddu c_3,t_2
|
||||
dmultu a_4,a_2 /* mul_add_c2(a[4],b[2],c1,c2,c3); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
slt AT,t_2,zero
|
||||
daddu c_3,AT
|
||||
dsll t_2,1
|
||||
slt a2,t_1,zero
|
||||
daddu t_2,a2
|
||||
dsll t_1,1
|
||||
daddu c_1,t_1
|
||||
sltu AT,c_1,t_1
|
||||
daddu t_2,AT
|
||||
daddu c_1,t_1
|
||||
daddu AT,t_2
|
||||
sltu t_1,c_1,t_1
|
||||
daddu c_2,AT
|
||||
daddu t_2,t_1
|
||||
sltu AT,c_2,AT
|
||||
daddu c_2,t_2
|
||||
sltu AT,c_2,t_2
|
||||
daddu c_3,AT
|
||||
sltu t_2,c_2,t_2
|
||||
daddu c_3,t_2
|
||||
dmultu a_3,a_3 /* mul_add_c(a[3],b[3],c1,c2,c3); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
@@ -1781,108 +1781,108 @@ LEAF(bn_sqr_comba8)
|
||||
dmultu a_0,a_7 /* mul_add_c2(a[0],b[7],c2,c3,c1); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
slt c_1,t_2,zero
|
||||
dsll t_2,1
|
||||
slt a2,t_1,zero
|
||||
daddu t_2,a2
|
||||
dsll t_1,1
|
||||
daddu c_2,t_1
|
||||
sltu AT,c_2,t_1
|
||||
daddu t_2,AT
|
||||
daddu c_2,t_1
|
||||
daddu AT,t_2
|
||||
sltu t_1,c_2,t_1
|
||||
daddu c_3,AT
|
||||
daddu t_2,t_1
|
||||
sltu c_1,c_3,AT
|
||||
daddu c_3,t_2
|
||||
sltu AT,c_3,t_2
|
||||
daddu c_1,AT
|
||||
sltu t_2,c_3,t_2
|
||||
daddu c_1,t_2
|
||||
dmultu a_1,a_6 /* mul_add_c2(a[1],b[6],c2,c3,c1); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
slt AT,t_2,zero
|
||||
daddu c_1,AT
|
||||
dsll t_2,1
|
||||
slt a2,t_1,zero
|
||||
daddu t_2,a2
|
||||
dsll t_1,1
|
||||
daddu c_2,t_1
|
||||
sltu AT,c_2,t_1
|
||||
daddu t_2,AT
|
||||
daddu c_2,t_1
|
||||
daddu AT,t_2
|
||||
sltu t_1,c_2,t_1
|
||||
daddu c_3,AT
|
||||
daddu t_2,t_1
|
||||
sltu AT,c_3,AT
|
||||
daddu c_3,t_2
|
||||
sltu AT,c_3,t_2
|
||||
daddu c_1,AT
|
||||
sltu t_2,c_3,t_2
|
||||
daddu c_1,t_2
|
||||
dmultu a_2,a_5 /* mul_add_c2(a[2],b[5],c2,c3,c1); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
slt AT,t_2,zero
|
||||
daddu c_1,AT
|
||||
dsll t_2,1
|
||||
slt a2,t_1,zero
|
||||
daddu t_2,a2
|
||||
dsll t_1,1
|
||||
daddu c_2,t_1
|
||||
sltu AT,c_2,t_1
|
||||
daddu t_2,AT
|
||||
daddu c_2,t_1
|
||||
daddu AT,t_2
|
||||
sltu t_1,c_2,t_1
|
||||
daddu c_3,AT
|
||||
daddu t_2,t_1
|
||||
sltu AT,c_3,AT
|
||||
daddu c_3,t_2
|
||||
sltu AT,c_3,t_2
|
||||
daddu c_1,AT
|
||||
sltu t_2,c_3,t_2
|
||||
daddu c_1,t_2
|
||||
dmultu a_3,a_4 /* mul_add_c2(a[3],b[4],c2,c3,c1); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
slt AT,t_2,zero
|
||||
daddu c_1,AT
|
||||
dsll t_2,1
|
||||
slt a2,t_1,zero
|
||||
daddu t_2,a2
|
||||
dsll t_1,1
|
||||
daddu c_2,t_1
|
||||
sltu AT,c_2,t_1
|
||||
daddu t_2,AT
|
||||
daddu c_2,t_1
|
||||
daddu AT,t_2
|
||||
sltu t_1,c_2,t_1
|
||||
daddu c_3,AT
|
||||
daddu t_2,t_1
|
||||
sltu AT,c_3,AT
|
||||
daddu c_3,t_2
|
||||
sltu AT,c_3,t_2
|
||||
daddu c_1,AT
|
||||
sltu t_2,c_3,t_2
|
||||
daddu c_1,t_2
|
||||
sd c_2,56(a0)
|
||||
|
||||
dmultu a_7,a_1 /* mul_add_c2(a[7],b[1],c3,c1,c2); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
slt c_2,t_2,zero
|
||||
dsll t_2,1
|
||||
slt a2,t_1,zero
|
||||
daddu t_2,a2
|
||||
dsll t_1,1
|
||||
daddu c_3,t_1
|
||||
sltu AT,c_3,t_1
|
||||
daddu t_2,AT
|
||||
daddu c_3,t_1
|
||||
daddu AT,t_2
|
||||
sltu t_1,c_3,t_1
|
||||
daddu c_1,AT
|
||||
daddu t_2,t_1
|
||||
sltu c_2,c_1,AT
|
||||
daddu c_1,t_2
|
||||
sltu AT,c_1,t_2
|
||||
daddu c_2,AT
|
||||
sltu t_2,c_1,t_2
|
||||
daddu c_2,t_2
|
||||
dmultu a_6,a_2 /* mul_add_c2(a[6],b[2],c3,c1,c2); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
slt AT,t_2,zero
|
||||
daddu c_2,AT
|
||||
dsll t_2,1
|
||||
slt a2,t_1,zero
|
||||
daddu t_2,a2
|
||||
dsll t_1,1
|
||||
daddu c_3,t_1
|
||||
sltu AT,c_3,t_1
|
||||
daddu t_2,AT
|
||||
daddu c_3,t_1
|
||||
daddu AT,t_2
|
||||
sltu t_1,c_3,t_1
|
||||
daddu c_1,AT
|
||||
daddu t_2,t_1
|
||||
sltu AT,c_1,AT
|
||||
daddu c_1,t_2
|
||||
sltu AT,c_1,t_2
|
||||
daddu c_2,AT
|
||||
sltu t_2,c_1,t_2
|
||||
daddu c_2,t_2
|
||||
dmultu a_5,a_3 /* mul_add_c2(a[5],b[3],c3,c1,c2); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
slt AT,t_2,zero
|
||||
daddu c_2,AT
|
||||
dsll t_2,1
|
||||
slt a2,t_1,zero
|
||||
daddu t_2,a2
|
||||
dsll t_1,1
|
||||
daddu c_3,t_1
|
||||
sltu AT,c_3,t_1
|
||||
daddu t_2,AT
|
||||
daddu c_3,t_1
|
||||
daddu AT,t_2
|
||||
sltu t_1,c_3,t_1
|
||||
daddu c_1,AT
|
||||
daddu t_2,t_1
|
||||
sltu AT,c_1,AT
|
||||
daddu c_1,t_2
|
||||
sltu AT,c_1,t_2
|
||||
daddu c_2,AT
|
||||
sltu t_2,c_1,t_2
|
||||
daddu c_2,t_2
|
||||
dmultu a_4,a_4 /* mul_add_c(a[4],b[4],c3,c1,c2); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
@@ -1897,78 +1897,78 @@ LEAF(bn_sqr_comba8)
|
||||
dmultu a_2,a_7 /* mul_add_c2(a[2],b[7],c1,c2,c3); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
slt c_3,t_2,zero
|
||||
dsll t_2,1
|
||||
slt a2,t_1,zero
|
||||
daddu t_2,a2
|
||||
dsll t_1,1
|
||||
daddu c_1,t_1
|
||||
sltu AT,c_1,t_1
|
||||
daddu t_2,AT
|
||||
daddu c_1,t_1
|
||||
daddu AT,t_2
|
||||
sltu t_1,c_1,t_1
|
||||
daddu c_2,AT
|
||||
daddu t_2,t_1
|
||||
sltu c_3,c_2,AT
|
||||
daddu c_2,t_2
|
||||
sltu AT,c_2,t_2
|
||||
daddu c_3,AT
|
||||
sltu t_2,c_2,t_2
|
||||
daddu c_3,t_2
|
||||
dmultu a_3,a_6 /* mul_add_c2(a[3],b[6],c1,c2,c3); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
slt AT,t_2,zero
|
||||
daddu c_3,AT
|
||||
dsll t_2,1
|
||||
slt a2,t_1,zero
|
||||
daddu t_2,a2
|
||||
dsll t_1,1
|
||||
daddu c_1,t_1
|
||||
sltu AT,c_1,t_1
|
||||
daddu t_2,AT
|
||||
daddu c_1,t_1
|
||||
daddu AT,t_2
|
||||
sltu t_1,c_1,t_1
|
||||
daddu c_2,AT
|
||||
daddu t_2,t_1
|
||||
sltu AT,c_2,AT
|
||||
daddu c_2,t_2
|
||||
sltu AT,c_2,t_2
|
||||
daddu c_3,AT
|
||||
sltu t_2,c_2,t_2
|
||||
daddu c_3,t_2
|
||||
dmultu a_4,a_5 /* mul_add_c2(a[4],b[5],c1,c2,c3); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
slt AT,t_2,zero
|
||||
daddu c_3,AT
|
||||
dsll t_2,1
|
||||
slt a2,t_1,zero
|
||||
daddu t_2,a2
|
||||
dsll t_1,1
|
||||
daddu c_1,t_1
|
||||
sltu AT,c_1,t_1
|
||||
daddu t_2,AT
|
||||
daddu c_1,t_1
|
||||
daddu AT,t_2
|
||||
sltu t_1,c_1,t_1
|
||||
daddu c_2,AT
|
||||
daddu t_2,t_1
|
||||
sltu AT,c_2,AT
|
||||
daddu c_2,t_2
|
||||
sltu AT,c_2,t_2
|
||||
daddu c_3,AT
|
||||
sltu t_2,c_2,t_2
|
||||
daddu c_3,t_2
|
||||
sd c_1,72(a0)
|
||||
|
||||
dmultu a_7,a_3 /* mul_add_c2(a[7],b[3],c2,c3,c1); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
slt c_1,t_2,zero
|
||||
dsll t_2,1
|
||||
slt a2,t_1,zero
|
||||
daddu t_2,a2
|
||||
dsll t_1,1
|
||||
daddu c_2,t_1
|
||||
sltu AT,c_2,t_1
|
||||
daddu t_2,AT
|
||||
daddu c_2,t_1
|
||||
daddu AT,t_2
|
||||
sltu t_1,c_2,t_1
|
||||
daddu c_3,AT
|
||||
daddu t_2,t_1
|
||||
sltu c_1,c_3,AT
|
||||
daddu c_3,t_2
|
||||
sltu AT,c_3,t_2
|
||||
daddu c_1,AT
|
||||
sltu t_2,c_3,t_2
|
||||
daddu c_1,t_2
|
||||
dmultu a_6,a_4 /* mul_add_c2(a[6],b[4],c2,c3,c1); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
slt AT,t_2,zero
|
||||
daddu c_1,AT
|
||||
dsll t_2,1
|
||||
slt a2,t_1,zero
|
||||
daddu t_2,a2
|
||||
dsll t_1,1
|
||||
daddu c_2,t_1
|
||||
sltu AT,c_2,t_1
|
||||
daddu t_2,AT
|
||||
daddu c_2,t_1
|
||||
daddu AT,t_2
|
||||
sltu t_1,c_2,t_1
|
||||
daddu c_3,AT
|
||||
daddu t_2,t_1
|
||||
sltu AT,c_3,AT
|
||||
daddu c_3,t_2
|
||||
sltu AT,c_3,t_2
|
||||
daddu c_1,AT
|
||||
sltu t_2,c_3,t_2
|
||||
daddu c_1,t_2
|
||||
dmultu a_5,a_5 /* mul_add_c(a[5],b[5],c2,c3,c1); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
@@ -1983,48 +1983,48 @@ LEAF(bn_sqr_comba8)
|
||||
dmultu a_4,a_7 /* mul_add_c2(a[4],b[7],c3,c1,c2); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
slt c_2,t_2,zero
|
||||
dsll t_2,1
|
||||
slt a2,t_1,zero
|
||||
daddu t_2,a2
|
||||
dsll t_1,1
|
||||
daddu c_3,t_1
|
||||
sltu AT,c_3,t_1
|
||||
daddu t_2,AT
|
||||
daddu c_3,t_1
|
||||
daddu AT,t_2
|
||||
sltu t_1,c_3,t_1
|
||||
daddu c_1,AT
|
||||
daddu t_2,t_1
|
||||
sltu c_2,c_1,AT
|
||||
daddu c_1,t_2
|
||||
sltu AT,c_1,t_2
|
||||
daddu c_2,AT
|
||||
sltu t_2,c_1,t_2
|
||||
daddu c_2,t_2
|
||||
dmultu a_5,a_6 /* mul_add_c2(a[5],b[6],c3,c1,c2); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
slt AT,t_2,zero
|
||||
daddu c_2,AT
|
||||
dsll t_2,1
|
||||
slt a2,t_1,zero
|
||||
daddu t_2,a2
|
||||
dsll t_1,1
|
||||
daddu c_3,t_1
|
||||
sltu AT,c_3,t_1
|
||||
daddu t_2,AT
|
||||
daddu c_3,t_1
|
||||
daddu AT,t_2
|
||||
sltu t_1,c_3,t_1
|
||||
daddu c_1,AT
|
||||
daddu t_2,t_1
|
||||
sltu AT,c_1,AT
|
||||
daddu c_1,t_2
|
||||
sltu AT,c_1,t_2
|
||||
daddu c_2,AT
|
||||
sltu t_2,c_1,t_2
|
||||
daddu c_2,t_2
|
||||
sd c_3,88(a0)
|
||||
|
||||
dmultu a_7,a_5 /* mul_add_c2(a[7],b[5],c1,c2,c3); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
slt c_3,t_2,zero
|
||||
dsll t_2,1
|
||||
slt a2,t_1,zero
|
||||
daddu t_2,a2
|
||||
dsll t_1,1
|
||||
daddu c_1,t_1
|
||||
sltu AT,c_1,t_1
|
||||
daddu t_2,AT
|
||||
daddu c_1,t_1
|
||||
daddu AT,t_2
|
||||
sltu t_1,c_1,t_1
|
||||
daddu c_2,AT
|
||||
daddu t_2,t_1
|
||||
sltu c_3,c_2,AT
|
||||
daddu c_2,t_2
|
||||
sltu AT,c_2,t_2
|
||||
daddu c_3,AT
|
||||
sltu t_2,c_2,t_2
|
||||
daddu c_3,t_2
|
||||
dmultu a_6,a_6 /* mul_add_c(a[6],b[6],c1,c2,c3); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
@@ -2039,17 +2039,17 @@ LEAF(bn_sqr_comba8)
|
||||
dmultu a_6,a_7 /* mul_add_c2(a[6],b[7],c2,c3,c1); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
slt c_1,t_2,zero
|
||||
dsll t_2,1
|
||||
slt a2,t_1,zero
|
||||
daddu t_2,a2
|
||||
dsll t_1,1
|
||||
daddu c_2,t_1
|
||||
sltu AT,c_2,t_1
|
||||
daddu t_2,AT
|
||||
daddu c_2,t_1
|
||||
daddu AT,t_2
|
||||
sltu t_1,c_2,t_1
|
||||
daddu c_3,AT
|
||||
daddu t_2,t_1
|
||||
sltu c_1,c_3,AT
|
||||
daddu c_3,t_2
|
||||
sltu AT,c_3,t_2
|
||||
daddu c_1,AT
|
||||
sltu t_2,c_3,t_2
|
||||
daddu c_1,t_2
|
||||
sd c_2,104(a0)
|
||||
|
||||
dmultu a_7,a_7 /* mul_add_c(a[7],b[7],c3,c1,c2); */
|
||||
@@ -2070,9 +2070,9 @@ LEAF(bn_sqr_comba4)
|
||||
.set reorder
|
||||
ld a_0,0(a1)
|
||||
ld a_1,8(a1)
|
||||
dmultu a_0,a_0 /* mul_add_c(a[0],b[0],c1,c2,c3); */
|
||||
ld a_2,16(a1)
|
||||
ld a_3,24(a1)
|
||||
dmultu a_0,a_0 /* mul_add_c(a[0],b[0],c1,c2,c3); */
|
||||
mflo c_1
|
||||
mfhi c_2
|
||||
sd c_1,0(a0)
|
||||
@@ -2093,17 +2093,17 @@ LEAF(bn_sqr_comba4)
|
||||
dmultu a_2,a_0 /* mul_add_c2(a[2],b[0],c3,c1,c2); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
slt c_2,t_2,zero
|
||||
dsll t_2,1
|
||||
slt a2,t_1,zero
|
||||
daddu t_2,a2
|
||||
dsll t_1,1
|
||||
daddu c_3,t_1
|
||||
sltu AT,c_3,t_1
|
||||
daddu t_2,AT
|
||||
daddu c_3,t_1
|
||||
daddu AT,t_2
|
||||
sltu t_1,c_3,t_1
|
||||
daddu c_1,AT
|
||||
daddu t_2,t_1
|
||||
sltu c_2,c_1,AT
|
||||
daddu c_1,t_2
|
||||
sltu AT,c_1,t_2
|
||||
daddu c_2,AT
|
||||
sltu t_2,c_1,t_2
|
||||
daddu c_2,t_2
|
||||
dmultu a_1,a_1 /* mul_add_c(a[1],b[1],c3,c1,c2); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
@@ -2118,48 +2118,48 @@ LEAF(bn_sqr_comba4)
|
||||
dmultu a_0,a_3 /* mul_add_c2(a[0],b[3],c1,c2,c3); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
slt c_3,t_2,zero
|
||||
dsll t_2,1
|
||||
slt a2,t_1,zero
|
||||
daddu t_2,a2
|
||||
dsll t_1,1
|
||||
daddu c_1,t_1
|
||||
sltu AT,c_1,t_1
|
||||
daddu t_2,AT
|
||||
daddu c_1,t_1
|
||||
daddu AT,t_2
|
||||
sltu t_1,c_1,t_1
|
||||
daddu c_2,AT
|
||||
daddu t_2,t_1
|
||||
sltu c_3,c_2,AT
|
||||
daddu c_2,t_2
|
||||
sltu AT,c_2,t_2
|
||||
daddu c_3,AT
|
||||
sltu t_2,c_2,t_2
|
||||
daddu c_3,t_2
|
||||
dmultu a_1,a_2 /* mul_add_c(a2[1],b[2],c1,c2,c3); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
slt AT,t_2,zero
|
||||
daddu c_3,AT
|
||||
dsll t_2,1
|
||||
slt a2,t_1,zero
|
||||
daddu t_2,a2
|
||||
dsll t_1,1
|
||||
daddu c_1,t_1
|
||||
sltu AT,c_1,t_1
|
||||
daddu t_2,AT
|
||||
daddu c_1,t_1
|
||||
daddu AT,t_2
|
||||
sltu t_1,c_1,t_1
|
||||
daddu c_2,AT
|
||||
daddu t_2,t_1
|
||||
sltu AT,c_2,AT
|
||||
daddu c_2,t_2
|
||||
sltu AT,c_2,t_2
|
||||
daddu c_3,AT
|
||||
sltu t_2,c_2,t_2
|
||||
daddu c_3,t_2
|
||||
sd c_1,24(a0)
|
||||
|
||||
dmultu a_3,a_1 /* mul_add_c2(a[3],b[1],c2,c3,c1); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
slt c_1,t_2,zero
|
||||
dsll t_2,1
|
||||
slt a2,t_1,zero
|
||||
daddu t_2,a2
|
||||
dsll t_1,1
|
||||
daddu c_2,t_1
|
||||
sltu AT,c_2,t_1
|
||||
daddu t_2,AT
|
||||
daddu c_2,t_1
|
||||
daddu AT,t_2
|
||||
sltu t_1,c_2,t_1
|
||||
daddu c_3,AT
|
||||
daddu t_2,t_1
|
||||
sltu c_1,c_3,AT
|
||||
daddu c_3,t_2
|
||||
sltu AT,c_3,t_2
|
||||
daddu c_1,AT
|
||||
sltu t_2,c_3,t_2
|
||||
daddu c_1,t_2
|
||||
dmultu a_2,a_2 /* mul_add_c(a[2],b[2],c2,c3,c1); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
@@ -2174,17 +2174,17 @@ LEAF(bn_sqr_comba4)
|
||||
dmultu a_2,a_3 /* mul_add_c2(a[2],b[3],c3,c1,c2); */
|
||||
mflo t_1
|
||||
mfhi t_2
|
||||
slt c_2,t_2,zero
|
||||
dsll t_2,1
|
||||
slt a2,t_1,zero
|
||||
daddu t_2,a2
|
||||
dsll t_1,1
|
||||
daddu c_3,t_1
|
||||
sltu AT,c_3,t_1
|
||||
daddu t_2,AT
|
||||
daddu c_3,t_1
|
||||
daddu AT,t_2
|
||||
sltu t_1,c_3,t_1
|
||||
daddu c_1,AT
|
||||
daddu t_2,t_1
|
||||
sltu c_2,c_1,AT
|
||||
daddu c_1,t_2
|
||||
sltu AT,c_1,t_2
|
||||
daddu c_2,AT
|
||||
sltu t_2,c_1,t_2
|
||||
daddu c_2,t_2
|
||||
sd c_3,40(a0)
|
||||
|
||||
dmultu a_3,a_3 /* mul_add_c(a[3],b[3],c1,c2,c3); */
|
||||
|
||||
@@ -189,7 +189,7 @@ BN_ULONG bn_add_words (BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int
|
||||
|
||||
if (n <= 0) return 0;
|
||||
|
||||
asm (
|
||||
asm volatile (
|
||||
" subq %2,%2 \n"
|
||||
".p2align 4 \n"
|
||||
"1: movq (%4,%2,8),%0 \n"
|
||||
@@ -200,7 +200,7 @@ BN_ULONG bn_add_words (BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int
|
||||
" sbbq %0,%0 \n"
|
||||
: "=&a"(ret),"+c"(n),"=&r"(i)
|
||||
: "r"(rp),"r"(ap),"r"(bp)
|
||||
: "cc"
|
||||
: "cc", "memory"
|
||||
);
|
||||
|
||||
return ret&1;
|
||||
@@ -212,7 +212,7 @@ BN_ULONG bn_sub_words (BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int
|
||||
|
||||
if (n <= 0) return 0;
|
||||
|
||||
asm (
|
||||
asm volatile (
|
||||
" subq %2,%2 \n"
|
||||
".p2align 4 \n"
|
||||
"1: movq (%4,%2,8),%0 \n"
|
||||
@@ -223,7 +223,7 @@ BN_ULONG bn_sub_words (BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int
|
||||
" sbbq %0,%0 \n"
|
||||
: "=&a"(ret),"+c"(n),"=&r"(i)
|
||||
: "r"(rp),"r"(ap),"r"(bp)
|
||||
: "cc"
|
||||
: "cc", "memory"
|
||||
);
|
||||
|
||||
return ret&1;
|
||||
@@ -273,6 +273,10 @@ BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
|
||||
/* sqr_add_c(a,i,c0,c1,c2) -- c+=a[i]^2 for three word number c=(c2,c1,c0) */
|
||||
/* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) */
|
||||
|
||||
/*
|
||||
* Keep in mind that carrying into high part of multiplication result
|
||||
* can not overflow, because it cannot be all-ones.
|
||||
*/
|
||||
#if 0
|
||||
/* original macros are kept for reference purposes */
|
||||
#define mul_add_c(a,b,c0,c1,c2) { \
|
||||
@@ -287,10 +291,10 @@ BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
|
||||
BN_ULONG ta=(a),tb=(b),t0; \
|
||||
t1 = BN_UMULT_HIGH(ta,tb); \
|
||||
t0 = ta * tb; \
|
||||
t2 = t1+t1; c2 += (t2<t1)?1:0; \
|
||||
t1 = t0+t0; t2 += (t1<t0)?1:0; \
|
||||
c0 += t1; t2 += (c0<t1)?1:0; \
|
||||
c0 += t0; t2 = t1+((c0<t0)?1:0);\
|
||||
c1 += t2; c2 += (c1<t2)?1:0; \
|
||||
c0 += t0; t1 += (c0<t0)?1:0; \
|
||||
c1 += t1; c2 += (c1<t1)?1:0; \
|
||||
}
|
||||
#else
|
||||
#define mul_add_c(a,b,c0,c1,c2) do { \
|
||||
@@ -328,22 +332,14 @@ BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
|
||||
: "=a"(t1),"=d"(t2) \
|
||||
: "a"(a),"m"(b) \
|
||||
: "cc"); \
|
||||
asm ("addq %0,%0; adcq %2,%1" \
|
||||
: "+d"(t2),"+r"(c2) \
|
||||
: "g"(0) \
|
||||
: "cc"); \
|
||||
asm ("addq %0,%0; adcq %2,%1" \
|
||||
: "+a"(t1),"+d"(t2) \
|
||||
: "g"(0) \
|
||||
: "cc"); \
|
||||
asm ("addq %2,%0; adcq %3,%1" \
|
||||
: "+r"(c0),"+d"(t2) \
|
||||
: "a"(t1),"g"(0) \
|
||||
: "cc"); \
|
||||
asm ("addq %2,%0; adcq %3,%1" \
|
||||
: "+r"(c1),"+r"(c2) \
|
||||
: "d"(t2),"g"(0) \
|
||||
: "cc"); \
|
||||
asm ("addq %3,%0; adcq %4,%1; adcq %5,%2" \
|
||||
: "+r"(c0),"+r"(c1),"+r"(c2) \
|
||||
: "r"(t1),"r"(t2),"g"(0) \
|
||||
: "cc"); \
|
||||
asm ("addq %3,%0; adcq %4,%1; adcq %5,%2" \
|
||||
: "+r"(c0),"+r"(c1),"+r"(c2) \
|
||||
: "r"(t1),"r"(t2),"g"(0) \
|
||||
: "cc"); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
|
||||
@@ -438,6 +438,10 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
|
||||
/* sqr_add_c(a,i,c0,c1,c2) -- c+=a[i]^2 for three word number c=(c2,c1,c0) */
|
||||
/* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) */
|
||||
|
||||
/*
|
||||
* Keep in mind that carrying into high part of multiplication result
|
||||
* can not overflow, because it cannot be all-ones.
|
||||
*/
|
||||
#ifdef BN_LLONG
|
||||
#define mul_add_c(a,b,c0,c1,c2) \
|
||||
t=(BN_ULLONG)a*b; \
|
||||
@@ -478,10 +482,10 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
|
||||
#define mul_add_c2(a,b,c0,c1,c2) { \
|
||||
BN_ULONG ta=(a),tb=(b),t0; \
|
||||
BN_UMULT_LOHI(t0,t1,ta,tb); \
|
||||
t2 = t1+t1; c2 += (t2<t1)?1:0; \
|
||||
t1 = t0+t0; t2 += (t1<t0)?1:0; \
|
||||
c0 += t1; t2 += (c0<t1)?1:0; \
|
||||
c0 += t0; t2 = t1+((c0<t0)?1:0);\
|
||||
c1 += t2; c2 += (c1<t2)?1:0; \
|
||||
c0 += t0; t1 += (c0<t0)?1:0; \
|
||||
c1 += t1; c2 += (c1<t1)?1:0; \
|
||||
}
|
||||
|
||||
#define sqr_add_c(a,i,c0,c1,c2) { \
|
||||
@@ -508,10 +512,10 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
|
||||
BN_ULONG ta=(a),tb=(b),t0; \
|
||||
t1 = BN_UMULT_HIGH(ta,tb); \
|
||||
t0 = ta * tb; \
|
||||
t2 = t1+t1; c2 += (t2<t1)?1:0; \
|
||||
t1 = t0+t0; t2 += (t1<t0)?1:0; \
|
||||
c0 += t1; t2 += (c0<t1)?1:0; \
|
||||
c0 += t0; t2 = t1+((c0<t0)?1:0);\
|
||||
c1 += t2; c2 += (c1<t2)?1:0; \
|
||||
c0 += t0; t1 += (c0<t0)?1:0; \
|
||||
c1 += t1; c2 += (c1<t1)?1:0; \
|
||||
}
|
||||
|
||||
#define sqr_add_c(a,i,c0,c1,c2) { \
|
||||
|
||||
@@ -767,7 +767,14 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
|
||||
bits = BN_num_bits(p);
|
||||
if (bits == 0)
|
||||
{
|
||||
ret = BN_one(rr);
|
||||
/* x**0 mod 1 is still zero. */
|
||||
if (BN_is_one(m))
|
||||
{
|
||||
ret = 1;
|
||||
BN_zero(rr);
|
||||
}
|
||||
else
|
||||
ret = BN_one(rr);
|
||||
return ret;
|
||||
}
|
||||
if (a == 0)
|
||||
|
||||
@@ -824,9 +824,9 @@ int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
|
||||
/* ... and right shift */
|
||||
for (val=t_d[0],i=0; i<BN_NIST_521_TOP-1; i++)
|
||||
{
|
||||
tmp = val>>BN_NIST_521_RSHIFT;
|
||||
val = t_d[i+1];
|
||||
t_d[i] = (tmp | val<<BN_NIST_521_LSHIFT) & BN_MASK2;
|
||||
t_d[i] = ( val>>BN_NIST_521_RSHIFT |
|
||||
(tmp=t_d[i+1])<<BN_NIST_521_LSHIFT ) & BN_MASK2;
|
||||
val=tmp;
|
||||
}
|
||||
t_d[i] = val>>BN_NIST_521_RSHIFT;
|
||||
/* lower 521 bits */
|
||||
|
||||
@@ -676,44 +676,98 @@ int test_mul(BIO *bp)
|
||||
|
||||
int test_sqr(BIO *bp, BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM a,c,d,e;
|
||||
int i;
|
||||
BIGNUM *a,*c,*d,*e;
|
||||
int i, ret = 0;
|
||||
|
||||
BN_init(&a);
|
||||
BN_init(&c);
|
||||
BN_init(&d);
|
||||
BN_init(&e);
|
||||
a = BN_new();
|
||||
c = BN_new();
|
||||
d = BN_new();
|
||||
e = BN_new();
|
||||
if (a == NULL || c == NULL || d == NULL || e == NULL)
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (i=0; i<num0; i++)
|
||||
{
|
||||
BN_bntest_rand(&a,40+i*10,0,0);
|
||||
a.neg=rand_neg();
|
||||
BN_sqr(&c,&a,ctx);
|
||||
BN_bntest_rand(a,40+i*10,0,0);
|
||||
a->neg=rand_neg();
|
||||
BN_sqr(c,a,ctx);
|
||||
if (bp != NULL)
|
||||
{
|
||||
if (!results)
|
||||
{
|
||||
BN_print(bp,&a);
|
||||
BN_print(bp,a);
|
||||
BIO_puts(bp," * ");
|
||||
BN_print(bp,&a);
|
||||
BN_print(bp,a);
|
||||
BIO_puts(bp," - ");
|
||||
}
|
||||
BN_print(bp,&c);
|
||||
BN_print(bp,c);
|
||||
BIO_puts(bp,"\n");
|
||||
}
|
||||
BN_div(&d,&e,&c,&a,ctx);
|
||||
BN_sub(&d,&d,&a);
|
||||
if(!BN_is_zero(&d) || !BN_is_zero(&e))
|
||||
{
|
||||
fprintf(stderr,"Square test failed!\n");
|
||||
return 0;
|
||||
}
|
||||
BN_div(d,e,c,a,ctx);
|
||||
BN_sub(d,d,a);
|
||||
if(!BN_is_zero(d) || !BN_is_zero(e))
|
||||
{
|
||||
fprintf(stderr,"Square test failed!\n");
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
BN_free(&a);
|
||||
BN_free(&c);
|
||||
BN_free(&d);
|
||||
BN_free(&e);
|
||||
return(1);
|
||||
|
||||
/* Regression test for a BN_sqr overflow bug. */
|
||||
BN_hex2bn(&a,
|
||||
"80000000000000008000000000000001FFFFFFFFFFFFFFFE0000000000000000");
|
||||
BN_sqr(c, a, ctx);
|
||||
if (bp != NULL)
|
||||
{
|
||||
if (!results)
|
||||
{
|
||||
BN_print(bp,a);
|
||||
BIO_puts(bp," * ");
|
||||
BN_print(bp,a);
|
||||
BIO_puts(bp," - ");
|
||||
}
|
||||
BN_print(bp,c);
|
||||
BIO_puts(bp,"\n");
|
||||
}
|
||||
BN_mul(d, a, a, ctx);
|
||||
if (BN_cmp(c, d))
|
||||
{
|
||||
fprintf(stderr, "Square test failed: BN_sqr and BN_mul produce "
|
||||
"different results!\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Regression test for a BN_sqr overflow bug. */
|
||||
BN_hex2bn(&a,
|
||||
"80000000000000000000000080000001FFFFFFFE000000000000000000000000");
|
||||
BN_sqr(c, a, ctx);
|
||||
if (bp != NULL)
|
||||
{
|
||||
if (!results)
|
||||
{
|
||||
BN_print(bp,a);
|
||||
BIO_puts(bp," * ");
|
||||
BN_print(bp,a);
|
||||
BIO_puts(bp," - ");
|
||||
}
|
||||
BN_print(bp,c);
|
||||
BIO_puts(bp,"\n");
|
||||
}
|
||||
BN_mul(d, a, a, ctx);
|
||||
if (BN_cmp(c, d))
|
||||
{
|
||||
fprintf(stderr, "Square test failed: BN_sqr and BN_mul produce "
|
||||
"different results!\n");
|
||||
goto err;
|
||||
}
|
||||
ret = 1;
|
||||
err:
|
||||
if (a != NULL) BN_free(a);
|
||||
if (c != NULL) BN_free(c);
|
||||
if (d != NULL) BN_free(d);
|
||||
if (e != NULL) BN_free(e);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int test_mont(BIO *bp, BN_CTX *ctx)
|
||||
|
||||
@@ -71,6 +71,43 @@
|
||||
|
||||
static const char rnd_seed[] = "string to make the random number generator think it has entropy";
|
||||
|
||||
/* test_exp_mod_zero tests that x**0 mod 1 == 0. It returns zero on success. */
|
||||
static int test_exp_mod_zero() {
|
||||
BIGNUM a, p, m;
|
||||
BIGNUM r;
|
||||
BN_CTX *ctx = BN_CTX_new();
|
||||
int ret = 1;
|
||||
|
||||
BN_init(&m);
|
||||
BN_one(&m);
|
||||
|
||||
BN_init(&a);
|
||||
BN_one(&a);
|
||||
|
||||
BN_init(&p);
|
||||
BN_zero(&p);
|
||||
|
||||
BN_init(&r);
|
||||
BN_mod_exp(&r, &a, &p, &m, ctx);
|
||||
BN_CTX_free(ctx);
|
||||
|
||||
if (BN_is_zero(&r))
|
||||
ret = 0;
|
||||
else
|
||||
{
|
||||
printf("1**0 mod 1 = ");
|
||||
BN_print_fp(stdout, &r);
|
||||
printf(", should be 0\n");
|
||||
}
|
||||
|
||||
BN_free(&r);
|
||||
BN_free(&a);
|
||||
BN_free(&p);
|
||||
BN_free(&m);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
BN_CTX *ctx;
|
||||
@@ -190,7 +227,13 @@ int main(int argc, char *argv[])
|
||||
ERR_remove_thread_state(NULL);
|
||||
CRYPTO_mem_leaks(out);
|
||||
BIO_free(out);
|
||||
printf(" done\n");
|
||||
printf("\n");
|
||||
|
||||
if (test_exp_mod_zero() != 0)
|
||||
goto err;
|
||||
|
||||
printf("done\n");
|
||||
|
||||
EXIT(0);
|
||||
err:
|
||||
ERR_load_crypto_strings();
|
||||
|
||||
206
crypto/constant_time_locl.h
Normal file
206
crypto/constant_time_locl.h
Normal file
@@ -0,0 +1,206 @@
|
||||
/* crypto/constant_time_locl.h */
|
||||
/*
|
||||
* Utilities for constant-time cryptography.
|
||||
*
|
||||
* Author: Emilia Kasper (emilia@openssl.org)
|
||||
* Based on previous work by Bodo Moeller, Emilia Kasper, Adam Langley
|
||||
* (Google).
|
||||
* ====================================================================
|
||||
* Copyright (c) 2014 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* 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 copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS 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 ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#ifndef HEADER_CONSTANT_TIME_LOCL_H
|
||||
#define HEADER_CONSTANT_TIME_LOCL_H
|
||||
|
||||
#include "e_os.h" /* For 'inline' */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The boolean methods return a bitmask of all ones (0xff...f) for true
|
||||
* and 0 for false. This is useful for choosing a value based on the result
|
||||
* of a conditional in constant time. For example,
|
||||
*
|
||||
* if (a < b) {
|
||||
* c = a;
|
||||
* } else {
|
||||
* c = b;
|
||||
* }
|
||||
*
|
||||
* can be written as
|
||||
*
|
||||
* unsigned int lt = constant_time_lt(a, b);
|
||||
* c = constant_time_select(lt, a, b);
|
||||
*/
|
||||
|
||||
/*
|
||||
* Returns the given value with the MSB copied to all the other
|
||||
* bits. Uses the fact that arithmetic shift shifts-in the sign bit.
|
||||
* However, this is not ensured by the C standard so you may need to
|
||||
* replace this with something else on odd CPUs.
|
||||
*/
|
||||
static inline unsigned int constant_time_msb(unsigned int a);
|
||||
|
||||
/*
|
||||
* Returns 0xff..f if a < b and 0 otherwise.
|
||||
*/
|
||||
static inline unsigned int constant_time_lt(unsigned int a, unsigned int b);
|
||||
/* Convenience method for getting an 8-bit mask. */
|
||||
static inline unsigned char constant_time_lt_8(unsigned int a, unsigned int b);
|
||||
|
||||
/*
|
||||
* Returns 0xff..f if a >= b and 0 otherwise.
|
||||
*/
|
||||
static inline unsigned int constant_time_ge(unsigned int a, unsigned int b);
|
||||
/* Convenience method for getting an 8-bit mask. */
|
||||
static inline unsigned char constant_time_ge_8(unsigned int a, unsigned int b);
|
||||
|
||||
/*
|
||||
* Returns 0xff..f if a == 0 and 0 otherwise.
|
||||
*/
|
||||
static inline unsigned int constant_time_is_zero(unsigned int a);
|
||||
/* Convenience method for getting an 8-bit mask. */
|
||||
static inline unsigned char constant_time_is_zero_8(unsigned int a);
|
||||
|
||||
|
||||
/*
|
||||
* Returns 0xff..f if a == b and 0 otherwise.
|
||||
*/
|
||||
static inline unsigned int constant_time_eq(unsigned int a, unsigned int b);
|
||||
/* Convenience method for getting an 8-bit mask. */
|
||||
static inline unsigned char constant_time_eq_8(unsigned int a, unsigned int b);
|
||||
/* Signed integers. */
|
||||
static inline unsigned int constant_time_eq_int(int a, int b);
|
||||
/* Convenience method for getting an 8-bit mask. */
|
||||
static inline unsigned char constant_time_eq_int_8(int a, int b);
|
||||
|
||||
|
||||
/*
|
||||
* Returns (mask & a) | (~mask & b).
|
||||
*
|
||||
* When |mask| is all 1s or all 0s (as returned by the methods above),
|
||||
* the select methods return either |a| (if |mask| is nonzero) or |b|
|
||||
* (if |mask| is zero).
|
||||
*/
|
||||
static inline unsigned int constant_time_select(unsigned int mask,
|
||||
unsigned int a, unsigned int b);
|
||||
/* Convenience method for unsigned chars. */
|
||||
static inline unsigned char constant_time_select_8(unsigned char mask,
|
||||
unsigned char a, unsigned char b);
|
||||
/* Convenience method for signed integers. */
|
||||
static inline int constant_time_select_int(unsigned int mask, int a, int b);
|
||||
|
||||
static inline unsigned int constant_time_msb(unsigned int a)
|
||||
{
|
||||
return 0-(a >> (sizeof(a) * 8 - 1));
|
||||
}
|
||||
|
||||
static inline unsigned int constant_time_lt(unsigned int a, unsigned int b)
|
||||
{
|
||||
return constant_time_msb(a^((a^b)|((a-b)^b)));
|
||||
}
|
||||
|
||||
static inline unsigned char constant_time_lt_8(unsigned int a, unsigned int b)
|
||||
{
|
||||
return (unsigned char)(constant_time_lt(a, b));
|
||||
}
|
||||
|
||||
static inline unsigned int constant_time_ge(unsigned int a, unsigned int b)
|
||||
{
|
||||
return ~constant_time_lt(a, b);
|
||||
}
|
||||
|
||||
static inline unsigned char constant_time_ge_8(unsigned int a, unsigned int b)
|
||||
{
|
||||
return (unsigned char)(constant_time_ge(a, b));
|
||||
}
|
||||
|
||||
static inline unsigned int constant_time_is_zero(unsigned int a)
|
||||
{
|
||||
return constant_time_msb(~a & (a - 1));
|
||||
}
|
||||
|
||||
static inline unsigned char constant_time_is_zero_8(unsigned int a)
|
||||
{
|
||||
return (unsigned char)(constant_time_is_zero(a));
|
||||
}
|
||||
|
||||
static inline unsigned int constant_time_eq(unsigned int a, unsigned int b)
|
||||
{
|
||||
return constant_time_is_zero(a ^ b);
|
||||
}
|
||||
|
||||
static inline unsigned char constant_time_eq_8(unsigned int a, unsigned int b)
|
||||
{
|
||||
return (unsigned char)(constant_time_eq(a, b));
|
||||
}
|
||||
|
||||
static inline unsigned int constant_time_eq_int(int a, int b)
|
||||
{
|
||||
return constant_time_eq((unsigned)(a), (unsigned)(b));
|
||||
}
|
||||
|
||||
static inline unsigned char constant_time_eq_int_8(int a, int b)
|
||||
{
|
||||
return constant_time_eq_8((unsigned)(a), (unsigned)(b));
|
||||
}
|
||||
|
||||
static inline unsigned int constant_time_select(unsigned int mask,
|
||||
unsigned int a, unsigned int b)
|
||||
{
|
||||
return (mask & a) | (~mask & b);
|
||||
}
|
||||
|
||||
static inline unsigned char constant_time_select_8(unsigned char mask,
|
||||
unsigned char a, unsigned char b)
|
||||
{
|
||||
return (unsigned char)(constant_time_select(mask, a, b));
|
||||
}
|
||||
|
||||
static inline int constant_time_select_int(unsigned int mask, int a, int b)
|
||||
{
|
||||
return (int)(constant_time_select(mask, (unsigned)(a), (unsigned)(b)));
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CONSTANT_TIME_LOCL_H */
|
||||
330
crypto/constant_time_test.c
Normal file
330
crypto/constant_time_test.c
Normal file
@@ -0,0 +1,330 @@
|
||||
/* crypto/constant_time_test.c */
|
||||
/*
|
||||
* Utilities for constant-time cryptography.
|
||||
*
|
||||
* Author: Emilia Kasper (emilia@openssl.org)
|
||||
* Based on previous work by Bodo Moeller, Emilia Kasper, Adam Langley
|
||||
* (Google).
|
||||
* ====================================================================
|
||||
* Copyright (c) 2014 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* 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 copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS 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 ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include "../crypto/constant_time_locl.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static const unsigned int CONSTTIME_TRUE = (unsigned)(~0);
|
||||
static const unsigned int CONSTTIME_FALSE = 0;
|
||||
static const unsigned char CONSTTIME_TRUE_8 = 0xff;
|
||||
static const unsigned char CONSTTIME_FALSE_8 = 0;
|
||||
|
||||
static int test_binary_op(unsigned int (*op)(unsigned int a, unsigned int b),
|
||||
const char* op_name, unsigned int a, unsigned int b, int is_true)
|
||||
{
|
||||
unsigned c = op(a, b);
|
||||
if (is_true && c != CONSTTIME_TRUE)
|
||||
{
|
||||
fprintf(stderr, "Test failed for %s(%du, %du): expected %du "
|
||||
"(TRUE), got %du\n", op_name, a, b, CONSTTIME_TRUE, c);
|
||||
return 1;
|
||||
}
|
||||
else if (!is_true && c != CONSTTIME_FALSE)
|
||||
{
|
||||
fprintf(stderr, "Test failed for %s(%du, %du): expected %du "
|
||||
"(FALSE), got %du\n", op_name, a, b, CONSTTIME_FALSE,
|
||||
c);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_binary_op_8(unsigned char (*op)(unsigned int a, unsigned int b),
|
||||
const char* op_name, unsigned int a, unsigned int b, int is_true)
|
||||
{
|
||||
unsigned char c = op(a, b);
|
||||
if (is_true && c != CONSTTIME_TRUE_8)
|
||||
{
|
||||
fprintf(stderr, "Test failed for %s(%du, %du): expected %u "
|
||||
"(TRUE), got %u\n", op_name, a, b, CONSTTIME_TRUE_8, c);
|
||||
return 1;
|
||||
}
|
||||
else if (!is_true && c != CONSTTIME_FALSE_8)
|
||||
{
|
||||
fprintf(stderr, "Test failed for %s(%du, %du): expected %u "
|
||||
"(FALSE), got %u\n", op_name, a, b, CONSTTIME_FALSE_8,
|
||||
c);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_is_zero(unsigned int a)
|
||||
{
|
||||
unsigned int c = constant_time_is_zero(a);
|
||||
if (a == 0 && c != CONSTTIME_TRUE)
|
||||
{
|
||||
fprintf(stderr, "Test failed for constant_time_is_zero(%du): "
|
||||
"expected %du (TRUE), got %du\n", a, CONSTTIME_TRUE, c);
|
||||
return 1;
|
||||
}
|
||||
else if (a != 0 && c != CONSTTIME_FALSE)
|
||||
{
|
||||
fprintf(stderr, "Test failed for constant_time_is_zero(%du): "
|
||||
"expected %du (FALSE), got %du\n", a, CONSTTIME_FALSE,
|
||||
c);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_is_zero_8(unsigned int a)
|
||||
{
|
||||
unsigned char c = constant_time_is_zero_8(a);
|
||||
if (a == 0 && c != CONSTTIME_TRUE_8)
|
||||
{
|
||||
fprintf(stderr, "Test failed for constant_time_is_zero(%du): "
|
||||
"expected %u (TRUE), got %u\n", a, CONSTTIME_TRUE_8, c);
|
||||
return 1;
|
||||
}
|
||||
else if (a != 0 && c != CONSTTIME_FALSE)
|
||||
{
|
||||
fprintf(stderr, "Test failed for constant_time_is_zero(%du): "
|
||||
"expected %u (FALSE), got %u\n", a, CONSTTIME_FALSE_8,
|
||||
c);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_select(unsigned int a, unsigned int b)
|
||||
{
|
||||
unsigned int selected = constant_time_select(CONSTTIME_TRUE, a, b);
|
||||
if (selected != a)
|
||||
{
|
||||
fprintf(stderr, "Test failed for constant_time_select(%du, %du,"
|
||||
"%du): expected %du(first value), got %du\n",
|
||||
CONSTTIME_TRUE, a, b, a, selected);
|
||||
return 1;
|
||||
}
|
||||
selected = constant_time_select(CONSTTIME_FALSE, a, b);
|
||||
if (selected != b)
|
||||
{
|
||||
fprintf(stderr, "Test failed for constant_time_select(%du, %du,"
|
||||
"%du): expected %du(second value), got %du\n",
|
||||
CONSTTIME_FALSE, a, b, b, selected);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_select_8(unsigned char a, unsigned char b)
|
||||
{
|
||||
unsigned char selected = constant_time_select_8(CONSTTIME_TRUE_8, a, b);
|
||||
if (selected != a)
|
||||
{
|
||||
fprintf(stderr, "Test failed for constant_time_select(%u, %u,"
|
||||
"%u): expected %u(first value), got %u\n",
|
||||
CONSTTIME_TRUE, a, b, a, selected);
|
||||
return 1;
|
||||
}
|
||||
selected = constant_time_select_8(CONSTTIME_FALSE_8, a, b);
|
||||
if (selected != b)
|
||||
{
|
||||
fprintf(stderr, "Test failed for constant_time_select(%u, %u,"
|
||||
"%u): expected %u(second value), got %u\n",
|
||||
CONSTTIME_FALSE, a, b, b, selected);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_select_int(int a, int b)
|
||||
{
|
||||
int selected = constant_time_select_int(CONSTTIME_TRUE, a, b);
|
||||
if (selected != a)
|
||||
{
|
||||
fprintf(stderr, "Test failed for constant_time_select(%du, %d,"
|
||||
"%d): expected %d(first value), got %d\n",
|
||||
CONSTTIME_TRUE, a, b, a, selected);
|
||||
return 1;
|
||||
}
|
||||
selected = constant_time_select_int(CONSTTIME_FALSE, a, b);
|
||||
if (selected != b)
|
||||
{
|
||||
fprintf(stderr, "Test failed for constant_time_select(%du, %d,"
|
||||
"%d): expected %d(second value), got %d\n",
|
||||
CONSTTIME_FALSE, a, b, b, selected);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_eq_int(int a, int b)
|
||||
{
|
||||
unsigned int equal = constant_time_eq_int(a, b);
|
||||
if (a == b && equal != CONSTTIME_TRUE)
|
||||
{
|
||||
fprintf(stderr, "Test failed for constant_time_eq_int(%d, %d): "
|
||||
"expected %du(TRUE), got %du\n",
|
||||
a, b, CONSTTIME_TRUE, equal);
|
||||
return 1;
|
||||
}
|
||||
else if (a != b && equal != CONSTTIME_FALSE)
|
||||
{
|
||||
fprintf(stderr, "Test failed for constant_time_eq_int(%d, %d): "
|
||||
"expected %du(FALSE), got %du\n",
|
||||
a, b, CONSTTIME_FALSE, equal);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_eq_int_8(int a, int b)
|
||||
{
|
||||
unsigned char equal = constant_time_eq_int_8(a, b);
|
||||
if (a == b && equal != CONSTTIME_TRUE_8)
|
||||
{
|
||||
fprintf(stderr, "Test failed for constant_time_eq_int_8(%d, %d): "
|
||||
"expected %u(TRUE), got %u\n",
|
||||
a, b, CONSTTIME_TRUE_8, equal);
|
||||
return 1;
|
||||
}
|
||||
else if (a != b && equal != CONSTTIME_FALSE_8)
|
||||
{
|
||||
fprintf(stderr, "Test failed for constant_time_eq_int_8(%d, %d): "
|
||||
"expected %u(FALSE), got %u\n",
|
||||
a, b, CONSTTIME_FALSE_8, equal);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int test_values[] = {0, 1, 1024, 12345, 32000, UINT_MAX/2-1,
|
||||
UINT_MAX/2, UINT_MAX/2+1, UINT_MAX-1,
|
||||
UINT_MAX};
|
||||
|
||||
static unsigned char test_values_8[] = {0, 1, 2, 20, 32, 127, 128, 129, 255};
|
||||
|
||||
static int signed_test_values[] = {0, 1, -1, 1024, -1024, 12345, -12345,
|
||||
32000, -32000, INT_MAX, INT_MIN, INT_MAX-1,
|
||||
INT_MIN+1};
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
unsigned int a, b, i, j;
|
||||
int c, d;
|
||||
unsigned char e, f;
|
||||
int num_failed = 0, num_all = 0;
|
||||
fprintf(stdout, "Testing constant time operations...\n");
|
||||
|
||||
for (i = 0; i < sizeof(test_values)/sizeof(int); ++i)
|
||||
{
|
||||
a = test_values[i];
|
||||
num_failed += test_is_zero(a);
|
||||
num_failed += test_is_zero_8(a);
|
||||
num_all += 2;
|
||||
for (j = 0; j < sizeof(test_values)/sizeof(int); ++j)
|
||||
{
|
||||
b = test_values[j];
|
||||
num_failed += test_binary_op(&constant_time_lt,
|
||||
"constant_time_lt", a, b, a < b);
|
||||
num_failed += test_binary_op_8(&constant_time_lt_8,
|
||||
"constant_time_lt_8", a, b, a < b);
|
||||
num_failed += test_binary_op(&constant_time_lt,
|
||||
"constant_time_lt_8", b, a, b < a);
|
||||
num_failed += test_binary_op_8(&constant_time_lt_8,
|
||||
"constant_time_lt_8", b, a, b < a);
|
||||
num_failed += test_binary_op(&constant_time_ge,
|
||||
"constant_time_ge", a, b, a >= b);
|
||||
num_failed += test_binary_op_8(&constant_time_ge_8,
|
||||
"constant_time_ge_8", a, b, a >= b);
|
||||
num_failed += test_binary_op(&constant_time_ge,
|
||||
"constant_time_ge", b, a, b >= a);
|
||||
num_failed += test_binary_op_8(&constant_time_ge_8,
|
||||
"constant_time_ge_8", b, a, b >= a);
|
||||
num_failed += test_binary_op(&constant_time_eq,
|
||||
"constant_time_eq", a, b, a == b);
|
||||
num_failed += test_binary_op_8(&constant_time_eq_8,
|
||||
"constant_time_eq_8", a, b, a == b);
|
||||
num_failed += test_binary_op(&constant_time_eq,
|
||||
"constant_time_eq", b, a, b == a);
|
||||
num_failed += test_binary_op_8(&constant_time_eq_8,
|
||||
"constant_time_eq_8", b, a, b == a);
|
||||
num_failed += test_select(a, b);
|
||||
num_all += 13;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof(signed_test_values)/sizeof(int); ++i)
|
||||
{
|
||||
c = signed_test_values[i];
|
||||
for (j = 0; j < sizeof(signed_test_values)/sizeof(int); ++j)
|
||||
{
|
||||
d = signed_test_values[j];
|
||||
num_failed += test_select_int(c, d);
|
||||
num_failed += test_eq_int(c, d);
|
||||
num_failed += test_eq_int_8(c, d);
|
||||
num_all += 3;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof(test_values_8); ++i)
|
||||
{
|
||||
e = test_values_8[i];
|
||||
for (j = 0; j < sizeof(test_values_8); ++j)
|
||||
{
|
||||
f = test_values_8[j];
|
||||
num_failed += test_select_8(e, f);
|
||||
num_all += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!num_failed)
|
||||
{
|
||||
fprintf(stdout, "ok (ran %d tests)\n", num_all);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stdout, "%d of %d tests failed!\n", num_failed, num_all);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
@@ -111,8 +111,8 @@ $ ET_WHIRLPOOL = "WHRLPOOL"
|
||||
$ IF ARCH .EQS. "VAX" THEN ET_WHIRLPOOL = ""
|
||||
$ ENCRYPT_TYPES = "Basic,"+ -
|
||||
"OBJECTS,"+ -
|
||||
"MD2,MD4,MD5,SHA,MDC2,HMAC,RIPEMD,"+ET_WHIRLPOOL+","+ -
|
||||
"DES,AES,RC2,RC4,RC5,IDEA,BF,CAST,CAMELLIA,SEED,MODES,"+ -
|
||||
"MD4,MD5,SHA,MDC2,HMAC,RIPEMD,"+ET_WHIRLPOOL+","+ -
|
||||
"DES,AES,RC2,RC4,IDEA,BF,CAST,CAMELLIA,SEED,MODES,"+ -
|
||||
"BN,EC,RSA,DSA,ECDSA,DH,ECDH,DSO,ENGINE,"+ -
|
||||
"BUFFER,BIO,STACK,LHASH,RAND,ERR,"+ -
|
||||
"EVP,EVP_2,EVP_3,ASN1,ASN1_2,PEM,X509,X509V3,"+ -
|
||||
@@ -204,10 +204,18 @@ $ GOSUB CHECK_OPT_FILE
|
||||
$!
|
||||
$! Define The Different Encryption "library" Strings.
|
||||
$!
|
||||
$ APPS_DES = "DES/DES,CBC3_ENC"
|
||||
$ APPS_PKCS7 = "ENC/ENC;DEC/DEC;SIGN/SIGN;VERIFY/VERIFY,EXAMPLE"
|
||||
$!!! Test apps disabled, as they aren't supported at all,
|
||||
$!!! not even in the unix build
|
||||
$!!! APPS_DES = "DES/DES,CBC3_ENC"
|
||||
$!!! APPS_PKCS7 = "ENC/ENC;DEC/DEC;SIGN/SIGN;VERIFY/VERIFY,EXAMPLE"
|
||||
$
|
||||
$ LIB_ = "cryptlib,mem,mem_clr,mem_dbg,cversion,ex_data,cpt_err,ebcdic,uid,o_time,o_str,o_dir"
|
||||
$! These variables are ordered as the SDIRS variable from the top Makefile.org
|
||||
$! The contents of these variables are copied from the LIBOBJ variable in the
|
||||
$! corresponding Makefile from each corresponding subdirectory, with .o stripped
|
||||
$! and spaces replaced with commas.
|
||||
$ LIB_ = "cryptlib,mem,mem_dbg,cversion,ex_data,cpt_err,ebcdic,"+ -
|
||||
"uid,o_time,o_str,o_dir,mem_clr"
|
||||
$ LIB_OBJECTS = "o_names,obj_dat,obj_lib,obj_err,obj_xref"
|
||||
$ LIB_MD2 = "md2_dgst,md2_one"
|
||||
$ LIB_MD4 = "md4_dgst,md4_one"
|
||||
$ LIB_MD5 = "md5_dgst,md5_one"
|
||||
@@ -224,13 +232,13 @@ $ LIB_DES = "set_key,ecb_enc,cbc_enc,"+ -
|
||||
"fcrypt,xcbc_enc,rpc_enc,cbc_cksm,"+ -
|
||||
"ede_cbcm_enc,des_old,des_old2,read2pwd"
|
||||
$ LIB_RC2 = "rc2_ecb,rc2_skey,rc2_cbc,rc2cfb64,rc2ofb64"
|
||||
$ LIB_RC4 = "rc4_skey,rc4_enc"
|
||||
$ LIB_RC4 = "rc4_enc,rc4_skey"
|
||||
$ LIB_RC5 = "rc5_skey,rc5_ecb,rc5_enc,rc5cfb64,rc5ofb64"
|
||||
$ LIB_IDEA = "i_cbc,i_cfb64,i_ofb64,i_ecb,i_skey"
|
||||
$ LIB_BF = "bf_skey,bf_ecb,bf_enc,bf_cfb64,bf_ofb64"
|
||||
$ LIB_CAST = "c_skey,c_ecb,c_enc,c_cfb64,c_ofb64"
|
||||
$ LIB_CAMELLIA = "camellia,cmll_misc,cmll_ecb,cmll_cbc,cmll_ofb,"+ -
|
||||
"cmll_cfb,cmll_ctr"
|
||||
$ LIB_CAMELLIA = "cmll_ecb,cmll_ofb,cmll_cfb,cmll_ctr,"+ -
|
||||
"camellia,cmll_misc,cmll_cbc"
|
||||
$ LIB_SEED = "seed,seed_ecb,seed_cbc,seed_cfb,seed_ofb"
|
||||
$ LIB_MODES = "cbc128,ctr128,cts128,cfb128,ofb128"
|
||||
$ LIB_BN_ASM = "[.asm]vms.mar,vms-helper"
|
||||
@@ -261,22 +269,21 @@ $ LIB_ENGINE = "eng_err,eng_lib,eng_list,eng_init,eng_ctrl,"+ -
|
||||
"tb_rsa,tb_dsa,tb_ecdsa,tb_dh,tb_ecdh,tb_rand,tb_store,"+ -
|
||||
"tb_cipher,tb_digest,tb_pkmeth,tb_asnmth,"+ -
|
||||
"eng_openssl,eng_dyn,eng_cnf,eng_cryptodev"
|
||||
$ LIB_AES = "aes_core,aes_misc,aes_ecb,aes_cbc,aes_cfb,aes_ofb,aes_ctr,"+ -
|
||||
"aes_ige,aes_wrap"
|
||||
$ LIB_AES = "aes_misc,aes_ecb,aes_cfb,aes_ofb,aes_ctr,aes_ige,aes_wrap,"+ -
|
||||
"aes_core,aes_cbc"
|
||||
$ LIB_BUFFER = "buffer,buf_err"
|
||||
$ LIB_BIO = "bio_lib,bio_cb,bio_err,"+ -
|
||||
"bss_mem,bss_null,bss_fd,"+ -
|
||||
"bss_file,bss_sock,bss_conn,"+ -
|
||||
"bf_null,bf_buff,b_print,b_dump,"+ -
|
||||
"b_sock,bss_acpt,bf_nbio,bss_rtcp,bss_bio,bss_log,"+ -
|
||||
"b_sock,bss_acpt,bf_nbio,bss_log,bss_bio,"+ -
|
||||
"bss_dgram,"+ -
|
||||
"bf_lbuf"
|
||||
"bf_lbuf,bss_rtcp" ! The last two are VMS specific
|
||||
$ LIB_STACK = "stack"
|
||||
$ LIB_LHASH = "lhash,lh_stats"
|
||||
$ LIB_RAND = "md_rand,randfile,rand_lib,rand_err,rand_egd,"+ -
|
||||
"rand_vms"
|
||||
"rand_vms" ! The last one is VMS specific
|
||||
$ LIB_ERR = "err,err_all,err_prn"
|
||||
$ LIB_OBJECTS = "o_names,obj_dat,obj_lib,obj_err,obj_xref"
|
||||
$ LIB_EVP = "encode,digest,evp_enc,evp_key,evp_acnf,"+ -
|
||||
"e_des,e_bf,e_idea,e_des3,e_camellia,"+ -
|
||||
"e_rc4,e_aes,names,e_seed,"+ -
|
||||
@@ -337,6 +344,7 @@ $ LIB_TS = "ts_err,ts_req_utils,ts_req_print,ts_rsp_utils,ts_rsp_print,"+ -
|
||||
"ts_rsp_sign,ts_rsp_verify,ts_verify_ctx,ts_lib,ts_conf,"+ -
|
||||
"ts_asn1"
|
||||
$ LIB_JPAKE = "jpake,jpake_err"
|
||||
$ LIB_STORE = "str_err,str_lib,str_meth,str_mem"
|
||||
$!
|
||||
$! Setup exceptional compilations
|
||||
$!
|
||||
@@ -372,7 +380,7 @@ $ MODULE_NEXT:
|
||||
$!
|
||||
$! Extract The Module Name From The Encryption List.
|
||||
$!
|
||||
$ MODULE_NAME = F$ELEMENT(MODULE_COUNTER,",",ENCRYPT_TYPES)
|
||||
$ MODULE_NAME = F$EDIT(F$ELEMENT(MODULE_COUNTER,",",ENCRYPT_TYPES),"COLLAPSE")
|
||||
$ IF MODULE_NAME.EQS."Basic" THEN MODULE_NAME = ""
|
||||
$ MODULE_NAME1 = MODULE_NAME
|
||||
$!
|
||||
@@ -456,7 +464,7 @@ $ THEN
|
||||
$!
|
||||
$! O.K, Extract The File Name From The File List.
|
||||
$!
|
||||
$ FILE_NAME = F$ELEMENT(FILE_COUNTER,",",'LIB_MODULE')
|
||||
$ FILE_NAME = F$EDIT(F$ELEMENT(FILE_COUNTER,",",'LIB_MODULE'),"COLLAPSE")
|
||||
$!
|
||||
$! else
|
||||
$!
|
||||
@@ -483,7 +491,7 @@ $! SHOW SYMBOL APPLICATION*
|
||||
$!
|
||||
$ IF APPLICATION .NES. ";"
|
||||
$ THEN
|
||||
$ FILE_NAME = F$ELEMENT(FILE_COUNTER,",",APPLICATION_OBJECTS)
|
||||
$ FILE_NAME = F$EDIT(F$ELEMENT(FILE_COUNTER,",",APPLICATION_OBJECTS),"COLLAPSE")
|
||||
$ IF FILE_NAME .EQS. ","
|
||||
$ THEN
|
||||
$ APPLICATION = ""
|
||||
@@ -1123,9 +1131,12 @@ $ CCDEFS = "TCPIP_TYPE_''P4',DSO_VMS"
|
||||
$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = CCDEFS + "," + USER_CCDEFS
|
||||
$ CCEXTRAFLAGS = ""
|
||||
$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS
|
||||
$ CCDISABLEWARNINGS = "" !!! "LONGLONGTYPE,LONGLONGSUFX,FOUNDCR"
|
||||
$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. "" THEN -
|
||||
CCDISABLEWARNINGS = CCDISABLEWARNINGS + "," + USER_CCDISABLEWARNINGS
|
||||
$ CCDISABLEWARNINGS = "" !!! "MAYLOSEDATA3" !!! "LONGLONGTYPE,LONGLONGSUFX,FOUNDCR"
|
||||
$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. ""
|
||||
$ THEN
|
||||
$ IF CCDISABLEWARNINGS .NES. "" THEN CCDISABLEWARNINGS = CCDISABLEWARNINGS + ","
|
||||
$ CCDISABLEWARNINGS = CCDISABLEWARNINGS + USER_CCDISABLEWARNINGS
|
||||
$ ENDIF
|
||||
$!
|
||||
$! Check To See If We Have A ZLIB Option.
|
||||
$!
|
||||
@@ -1290,6 +1301,18 @@ $! Finish up the definition of CC.
|
||||
$!
|
||||
$ IF COMPILER .EQS. "DECC"
|
||||
$ THEN
|
||||
$! Not all compiler versions support MAYLOSEDATA3.
|
||||
$ OPT_TEST = "MAYLOSEDATA3"
|
||||
$ DEFINE /USER_MODE SYS$ERROR NL:
|
||||
$ DEFINE /USER_MODE SYS$OUTPUT NL:
|
||||
$ 'CC' /NOCROSS_REFERENCE /NOLIST /NOOBJECT -
|
||||
/WARNINGS = DISABLE = ('OPT_TEST', EMPTYFILE) NL:
|
||||
$ IF ($SEVERITY)
|
||||
$ THEN
|
||||
$ IF CCDISABLEWARNINGS .NES. "" THEN -
|
||||
CCDISABLEWARNINGS = CCDISABLEWARNINGS+ ","
|
||||
$ CCDISABLEWARNINGS = CCDISABLEWARNINGS+ OPT_TEST
|
||||
$ ENDIF
|
||||
$ IF CCDISABLEWARNINGS .EQS. ""
|
||||
$ THEN
|
||||
$ CC4DISABLEWARNINGS = "DOLLARID"
|
||||
|
||||
@@ -69,10 +69,7 @@ const char *SSLeay_version(int t)
|
||||
if (t == SSLEAY_BUILT_ON)
|
||||
{
|
||||
#ifdef DATE
|
||||
static char buf[sizeof(DATE)+11];
|
||||
|
||||
BIO_snprintf(buf,sizeof buf,"built on: %s",DATE);
|
||||
return(buf);
|
||||
return(DATE);
|
||||
#else
|
||||
return("built on: date not available");
|
||||
#endif
|
||||
@@ -80,10 +77,7 @@ const char *SSLeay_version(int t)
|
||||
if (t == SSLEAY_CFLAGS)
|
||||
{
|
||||
#ifdef CFLAGS
|
||||
static char buf[sizeof(CFLAGS)+11];
|
||||
|
||||
BIO_snprintf(buf,sizeof buf,"compiler: %s",CFLAGS);
|
||||
return(buf);
|
||||
return(cflags);
|
||||
#else
|
||||
return("compiler: information not available");
|
||||
#endif
|
||||
@@ -91,10 +85,7 @@ const char *SSLeay_version(int t)
|
||||
if (t == SSLEAY_PLATFORM)
|
||||
{
|
||||
#ifdef PLATFORM
|
||||
static char buf[sizeof(PLATFORM)+11];
|
||||
|
||||
BIO_snprintf(buf,sizeof buf,"platform: %s", PLATFORM);
|
||||
return(buf);
|
||||
return(PLATFORM);
|
||||
#else
|
||||
return("platform: information not available");
|
||||
#endif
|
||||
|
||||
@@ -307,6 +307,12 @@ static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
|
||||
unsigned char *dp = NULL;
|
||||
int dplen;
|
||||
|
||||
if (!pkey->pkey.dsa || !pkey->pkey.dsa->priv_key)
|
||||
{
|
||||
DSAerr(DSA_F_DSA_PRIV_ENCODE,DSA_R_MISSING_PARAMETERS);
|
||||
goto err;
|
||||
}
|
||||
|
||||
params = ASN1_STRING_new();
|
||||
|
||||
if (!params)
|
||||
@@ -654,4 +660,3 @@ const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] =
|
||||
old_dsa_priv_encode
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -77,13 +77,25 @@ int DSA_verify(int type, const unsigned char *dgst, int dgst_len,
|
||||
const unsigned char *sigbuf, int siglen, DSA *dsa)
|
||||
{
|
||||
DSA_SIG *s;
|
||||
const unsigned char *p = sigbuf;
|
||||
unsigned char *der = NULL;
|
||||
int derlen = -1;
|
||||
int ret=-1;
|
||||
|
||||
s = DSA_SIG_new();
|
||||
if (s == NULL) return(ret);
|
||||
if (d2i_DSA_SIG(&s,&sigbuf,siglen) == NULL) goto err;
|
||||
if (d2i_DSA_SIG(&s,&p,siglen) == NULL) goto err;
|
||||
/* Ensure signature uses DER and doesn't have trailing garbage */
|
||||
derlen = i2d_DSA_SIG(s, &der);
|
||||
if (derlen != siglen || memcmp(sigbuf, der, derlen))
|
||||
goto err;
|
||||
ret=DSA_do_verify(dgst,dgst_len,s,dsa);
|
||||
err:
|
||||
if (derlen > 0)
|
||||
{
|
||||
OPENSSL_cleanse(der, derlen);
|
||||
OPENSSL_free(der);
|
||||
}
|
||||
DSA_SIG_free(s);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
@@ -609,7 +609,7 @@ int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN
|
||||
int EC_POINT_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
|
||||
int EC_POINTs_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
|
||||
|
||||
/** Computes r = generator * n sum_{i=0}^num p[i] * m[i]
|
||||
/** Computes r = generator * n sum_{i=0}^{num-1} p[i] * m[i]
|
||||
* \param group underlying EC_GROUP object
|
||||
* \param r EC_POINT object for the result
|
||||
* \param n BIGNUM with the multiplier for the group generator (optional)
|
||||
|
||||
@@ -453,14 +453,16 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype)
|
||||
if (ktype > 0)
|
||||
{
|
||||
public_key = EC_KEY_get0_public_key(x);
|
||||
if ((pub_key = EC_POINT_point2bn(group, public_key,
|
||||
EC_KEY_get_conv_form(x), NULL, ctx)) == NULL)
|
||||
if (public_key != NULL)
|
||||
{
|
||||
reason = ERR_R_EC_LIB;
|
||||
goto err;
|
||||
}
|
||||
if (pub_key)
|
||||
if ((pub_key = EC_POINT_point2bn(group, public_key,
|
||||
EC_KEY_get_conv_form(x), NULL, ctx)) == NULL)
|
||||
{
|
||||
reason = ERR_R_EC_LIB;
|
||||
goto err;
|
||||
}
|
||||
buf_len = (size_t)BN_num_bytes(pub_key);
|
||||
}
|
||||
}
|
||||
|
||||
if (ktype == 2)
|
||||
|
||||
@@ -1167,30 +1167,47 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (ret->pub_key)
|
||||
EC_POINT_clear_free(ret->pub_key);
|
||||
ret->pub_key = EC_POINT_new(ret->group);
|
||||
if (ret->pub_key == NULL)
|
||||
{
|
||||
ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (priv_key->publicKey)
|
||||
{
|
||||
const unsigned char *pub_oct;
|
||||
size_t pub_oct_len;
|
||||
int pub_oct_len;
|
||||
|
||||
if (ret->pub_key)
|
||||
EC_POINT_clear_free(ret->pub_key);
|
||||
ret->pub_key = EC_POINT_new(ret->group);
|
||||
if (ret->pub_key == NULL)
|
||||
{
|
||||
ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
pub_oct = M_ASN1_STRING_data(priv_key->publicKey);
|
||||
pub_oct_len = M_ASN1_STRING_length(priv_key->publicKey);
|
||||
/* save the point conversion form */
|
||||
/* The first byte - point conversion form - must be present. */
|
||||
if (pub_oct_len <= 0)
|
||||
{
|
||||
ECerr(EC_F_D2I_ECPRIVATEKEY, EC_R_BUFFER_TOO_SMALL);
|
||||
goto err;
|
||||
}
|
||||
/* Save the point conversion form. */
|
||||
ret->conv_form = (point_conversion_form_t)(pub_oct[0] & ~0x01);
|
||||
if (!EC_POINT_oct2point(ret->group, ret->pub_key,
|
||||
pub_oct, pub_oct_len, NULL))
|
||||
pub_oct, (size_t)(pub_oct_len), NULL))
|
||||
{
|
||||
ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!EC_POINT_mul(ret->group, ret->pub_key, ret->priv_key, NULL, NULL, NULL))
|
||||
{
|
||||
ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
/* Remember the original private-key-only encoding. */
|
||||
ret->enc_flag |= EC_PKEY_NO_PUBKEY;
|
||||
}
|
||||
|
||||
ok = 1;
|
||||
err:
|
||||
@@ -1214,7 +1231,8 @@ int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
|
||||
size_t buf_len=0, tmp_len;
|
||||
EC_PRIVATEKEY *priv_key=NULL;
|
||||
|
||||
if (a == NULL || a->group == NULL || a->priv_key == NULL)
|
||||
if (a == NULL || a->group == NULL || a->priv_key == NULL ||
|
||||
(!(a->enc_flag & EC_PKEY_NO_PUBKEY) && a->pub_key == NULL))
|
||||
{
|
||||
ECerr(EC_F_I2D_ECPRIVATEKEY,
|
||||
ERR_R_PASSED_NULL_PARAMETER);
|
||||
|
||||
@@ -64,7 +64,6 @@
|
||||
#include <string.h>
|
||||
#include "ec_lcl.h"
|
||||
#include <openssl/err.h>
|
||||
#include <string.h>
|
||||
|
||||
EC_KEY *EC_KEY_new(void)
|
||||
{
|
||||
|
||||
@@ -445,15 +445,16 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
wNAF_len = OPENSSL_malloc(totalnum * sizeof wNAF_len[0]);
|
||||
wNAF = OPENSSL_malloc((totalnum + 1) * sizeof wNAF[0]); /* includes space for pivot */
|
||||
val_sub = OPENSSL_malloc(totalnum * sizeof val_sub[0]);
|
||||
|
||||
|
||||
/* Ensure wNAF is initialised in case we end up going to err */
|
||||
if (wNAF) wNAF[0] = NULL; /* preliminary pivot */
|
||||
|
||||
if (!wsize || !wNAF_len || !wNAF || !val_sub)
|
||||
{
|
||||
ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
wNAF[0] = NULL; /* preliminary pivot */
|
||||
|
||||
/* num_val will be the total number of temporarily precomputed points */
|
||||
num_val = 0;
|
||||
|
||||
|
||||
@@ -167,6 +167,7 @@ static int pkey_ec_verify(EVP_PKEY_CTX *ctx,
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_ECDH
|
||||
static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
|
||||
{
|
||||
int ret;
|
||||
@@ -200,6 +201,7 @@ static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
|
||||
*keylen = ret;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
{
|
||||
@@ -332,7 +334,11 @@ const EVP_PKEY_METHOD ec_pkey_meth =
|
||||
0,0,
|
||||
|
||||
0,
|
||||
#ifndef OPENSSL_NO_ECDH
|
||||
pkey_ec_derive,
|
||||
#else
|
||||
0,
|
||||
#endif
|
||||
|
||||
pkey_ec_ctrl,
|
||||
pkey_ec_ctrl_str
|
||||
|
||||
@@ -1676,8 +1676,8 @@ int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT
|
||||
{
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
if (prod_Z[i] != NULL)
|
||||
BN_clear_free(prod_Z[i]);
|
||||
if (prod_Z[i] == NULL) break;
|
||||
BN_clear_free(prod_Z[i]);
|
||||
}
|
||||
OPENSSL_free(prod_Z);
|
||||
}
|
||||
|
||||
@@ -126,15 +126,16 @@ ecs_sign.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
|
||||
ecs_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
|
||||
ecs_sign.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
|
||||
ecs_sign.o: ecs_locl.h ecs_sign.c
|
||||
ecs_vrf.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
|
||||
ecs_vrf.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
|
||||
ecs_vrf.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
|
||||
ecs_vrf.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
|
||||
ecs_vrf.o: ../../include/openssl/engine.h ../../include/openssl/evp.h
|
||||
ecs_vrf.o: ../../e_os.h ../../include/openssl/asn1.h
|
||||
ecs_vrf.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
|
||||
ecs_vrf.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
|
||||
ecs_vrf.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
|
||||
ecs_vrf.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
|
||||
ecs_vrf.o: ../../include/openssl/err.h ../../include/openssl/evp.h
|
||||
ecs_vrf.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
|
||||
ecs_vrf.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
|
||||
ecs_vrf.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
|
||||
ecs_vrf.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
|
||||
ecs_vrf.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
|
||||
ecs_vrf.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
|
||||
ecs_vrf.o: ../../include/openssl/x509_vfy.h ecs_locl.h ecs_vrf.c
|
||||
ecs_vrf.o: ../../include/openssl/x509_vfy.h ../cryptlib.h ecs_locl.h ecs_vrf.c
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
*/
|
||||
|
||||
#include "ecs_locl.h"
|
||||
#include "cryptlib.h"
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
#include <openssl/engine.h>
|
||||
#endif
|
||||
@@ -84,13 +85,25 @@ int ECDSA_verify(int type, const unsigned char *dgst, int dgst_len,
|
||||
const unsigned char *sigbuf, int sig_len, EC_KEY *eckey)
|
||||
{
|
||||
ECDSA_SIG *s;
|
||||
const unsigned char *p = sigbuf;
|
||||
unsigned char *der = NULL;
|
||||
int derlen = -1;
|
||||
int ret=-1;
|
||||
|
||||
s = ECDSA_SIG_new();
|
||||
if (s == NULL) return(ret);
|
||||
if (d2i_ECDSA_SIG(&s, &sigbuf, sig_len) == NULL) goto err;
|
||||
if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL) goto err;
|
||||
/* Ensure signature uses DER and doesn't have trailing garbage */
|
||||
derlen = i2d_ECDSA_SIG(s, &der);
|
||||
if (derlen != sig_len || memcmp(sigbuf, der, derlen))
|
||||
goto err;
|
||||
ret=ECDSA_do_verify(dgst, dgst_len, s, eckey);
|
||||
err:
|
||||
if (derlen > 0)
|
||||
{
|
||||
OPENSSL_cleanse(der, derlen);
|
||||
OPENSSL_free(der);
|
||||
}
|
||||
ECDSA_SIG_free(s);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
@@ -71,6 +71,7 @@ R SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION 1060
|
||||
R SSL_R_TLSV1_ALERT_PROTOCOL_VERSION 1070
|
||||
R SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY 1071
|
||||
R SSL_R_TLSV1_ALERT_INTERNAL_ERROR 1080
|
||||
R SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK 1086
|
||||
R SSL_R_TLSV1_ALERT_USER_CANCELLED 1090
|
||||
R SSL_R_TLSV1_ALERT_NO_RENEGOTIATION 1100
|
||||
R SSL_R_TLSV1_UNSUPPORTED_EXTENSION 1110
|
||||
|
||||
@@ -601,4 +601,3 @@ int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in)
|
||||
return in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, 0, out);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -75,13 +75,13 @@ $!
|
||||
$ sdirs := , -
|
||||
'archd', -
|
||||
objects, -
|
||||
md2, md4, md5, sha, mdc2, hmac, ripemd, whrlpool, -
|
||||
des, aes, rc2, rc4, rc5, idea, bf, cast, camellia, seed, -
|
||||
md4, md5, sha, mdc2, hmac, ripemd, whrlpool, -
|
||||
des, aes, rc2, rc4, idea, bf, cast, camellia, seed, -
|
||||
bn, ec, rsa, dsa, ecdsa, dh, ecdh, dso, engine, -
|
||||
buffer, bio, stack, lhash, rand, err, -
|
||||
evp, asn1, pem, x509, x509v3, conf, txt_db, pkcs7, pkcs12, comp, ocsp, -
|
||||
ui, krb5, -
|
||||
store, cms, pqueue, ts, jpake
|
||||
cms, pqueue, ts, jpake, srp, store, cmac
|
||||
$!
|
||||
$ exheader_ := crypto.h, opensslv.h, ebcdic.h, symhacks.h, ossl_typ.h
|
||||
$ exheader_'archd' := opensslconf.h
|
||||
@@ -139,6 +139,9 @@ $ exheader_cms := cms.h
|
||||
$ exheader_pqueue := pqueue.h
|
||||
$ exheader_ts := ts.h
|
||||
$ exheader_jpake := jpake.h
|
||||
$ exheader_srp := srp.h
|
||||
$ exheader_store := store.h
|
||||
$ exheader_cmac := cmac.h
|
||||
$ libs := ssl_libcrypto
|
||||
$!
|
||||
$ exe_dir := [-.'archd'.exe.crypto]
|
||||
|
||||
@@ -108,6 +108,7 @@ sub round4_step
|
||||
EOF
|
||||
}
|
||||
|
||||
no warnings qw(uninitialized);
|
||||
my $flavour = shift;
|
||||
my $output = shift;
|
||||
if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
|
||||
@@ -119,7 +120,6 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate;
|
||||
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
|
||||
die "can't locate x86_64-xlate.pl";
|
||||
|
||||
no warnings qw(uninitialized);
|
||||
open OUT,"| \"$^X\" $xlate $flavour $output";
|
||||
*STDOUT=*OUT;
|
||||
|
||||
|
||||
@@ -42,8 +42,6 @@ static const nid_triple sigoid_srt[] =
|
||||
|
||||
static const nid_triple * const sigoid_srt_xref[] =
|
||||
{
|
||||
&sigoid_srt[17],
|
||||
&sigoid_srt[18],
|
||||
&sigoid_srt[0],
|
||||
&sigoid_srt[1],
|
||||
&sigoid_srt[7],
|
||||
|
||||
@@ -90,7 +90,10 @@ EOF
|
||||
|
||||
foreach (@srt2)
|
||||
{
|
||||
my $x = $xref_tbl{$_}[2];
|
||||
my ($p1, $p2, $x) = @{$xref_tbl{$_}};
|
||||
# If digest or signature algorithm is "undef" then the algorithm
|
||||
# needs special handling and is excluded from the cross reference table.
|
||||
next if $p1 eq "undef" || $p2 eq "undef";
|
||||
print "\t\&sigoid_srt\[$x\],\n";
|
||||
}
|
||||
|
||||
|
||||
@@ -25,11 +25,11 @@
|
||||
* (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
|
||||
* major minor fix final patch/beta)
|
||||
*/
|
||||
#define OPENSSL_VERSION_NUMBER 0x100000efL
|
||||
#define OPENSSL_VERSION_NUMBER 0x1000010fL
|
||||
#ifdef OPENSSL_FIPS
|
||||
#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.0n-fips 6 Aug 2014"
|
||||
#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.0p-fips 8 Jan 2015"
|
||||
#else
|
||||
#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.0n 6 Aug 2014"
|
||||
#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.0p 8 Jan 2015"
|
||||
#endif
|
||||
#define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT
|
||||
|
||||
|
||||
@@ -233,10 +233,6 @@ DECLARE_PKCS12_STACK_OF(PKCS7)
|
||||
(OBJ_obj2nid((a)->type) == NID_pkcs7_signedAndEnveloped)
|
||||
#define PKCS7_type_is_data(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_data)
|
||||
#define PKCS7_type_is_digest(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_digest)
|
||||
#define PKCS7_type_is_encrypted(a) \
|
||||
(OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted)
|
||||
|
||||
#define PKCS7_type_is_digest(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_digest)
|
||||
|
||||
#define PKCS7_set_detached(p,v) \
|
||||
PKCS7_ctrl(p,PKCS7_OP_SET_DETACHED_SIGNATURE,v,NULL)
|
||||
|
||||
@@ -192,7 +192,7 @@ rsa_oaep.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
|
||||
rsa_oaep.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
|
||||
rsa_oaep.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
|
||||
rsa_oaep.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
|
||||
rsa_oaep.o: ../cryptlib.h rsa_oaep.c
|
||||
rsa_oaep.o: ../constant_time_locl.h ../cryptlib.h rsa_oaep.c
|
||||
rsa_pk1.o: ../../e_os.h ../../include/openssl/asn1.h
|
||||
rsa_pk1.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
|
||||
rsa_pk1.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
|
||||
@@ -201,7 +201,8 @@ rsa_pk1.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
|
||||
rsa_pk1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
|
||||
rsa_pk1.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
|
||||
rsa_pk1.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
|
||||
rsa_pk1.o: ../../include/openssl/symhacks.h ../cryptlib.h rsa_pk1.c
|
||||
rsa_pk1.o: ../../include/openssl/symhacks.h ../constant_time_locl.h
|
||||
rsa_pk1.o: ../cryptlib.h rsa_pk1.c
|
||||
rsa_pmeth.o: ../../e_os.h ../../include/openssl/asn1.h
|
||||
rsa_pmeth.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
|
||||
rsa_pmeth.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
|
||||
|
||||
@@ -485,6 +485,7 @@ void ERR_load_RSA_strings(void);
|
||||
#define RSA_R_OAEP_DECODING_ERROR 121
|
||||
#define RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 148
|
||||
#define RSA_R_PADDING_CHECK_FAILED 114
|
||||
#define RSA_R_PKCS_DECODING_ERROR 159
|
||||
#define RSA_R_P_NOT_PRIME 128
|
||||
#define RSA_R_Q_NOT_PRIME 129
|
||||
#define RSA_R_RSA_OPERATIONS_NOT_SUPPORTED 130
|
||||
|
||||
@@ -161,6 +161,7 @@ static ERR_STRING_DATA RSA_str_reasons[]=
|
||||
{ERR_REASON(RSA_R_OAEP_DECODING_ERROR) ,"oaep decoding error"},
|
||||
{ERR_REASON(RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE),"operation not supported for this keytype"},
|
||||
{ERR_REASON(RSA_R_PADDING_CHECK_FAILED) ,"padding check failed"},
|
||||
{ERR_REASON(RSA_R_PKCS_DECODING_ERROR) ,"pkcs decoding error"},
|
||||
{ERR_REASON(RSA_R_P_NOT_PRIME) ,"p not prime"},
|
||||
{ERR_REASON(RSA_R_Q_NOT_PRIME) ,"q not prime"},
|
||||
{ERR_REASON(RSA_R_RSA_OPERATIONS_NOT_SUPPORTED),"rsa operations not supported"},
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
* an equivalent notion.
|
||||
*/
|
||||
|
||||
#include "constant_time_locl.h"
|
||||
|
||||
#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
|
||||
#include <stdio.h>
|
||||
@@ -94,91 +95,116 @@ int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
|
||||
const unsigned char *from, int flen, int num,
|
||||
const unsigned char *param, int plen)
|
||||
{
|
||||
int i, dblen, mlen = -1;
|
||||
const unsigned char *maskeddb;
|
||||
int lzero;
|
||||
unsigned char *db = NULL, seed[SHA_DIGEST_LENGTH], phash[SHA_DIGEST_LENGTH];
|
||||
unsigned char *padded_from;
|
||||
int bad = 0;
|
||||
int i, dblen, mlen = -1, one_index = 0, msg_index;
|
||||
unsigned int good, found_one_byte;
|
||||
const unsigned char *maskedseed, *maskeddb;
|
||||
/* |em| is the encoded message, zero-padded to exactly |num| bytes:
|
||||
* em = Y || maskedSeed || maskedDB */
|
||||
unsigned char *db = NULL, *em = NULL, seed[EVP_MAX_MD_SIZE],
|
||||
phash[EVP_MAX_MD_SIZE];
|
||||
|
||||
if (--num < 2 * SHA_DIGEST_LENGTH + 1)
|
||||
/* 'num' is the length of the modulus, i.e. does not depend on the
|
||||
* particular ciphertext. */
|
||||
if (tlen <= 0 || flen <= 0)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* |num| is the length of the modulus; |flen| is the length of the
|
||||
* encoded message. Therefore, for any |from| that was obtained by
|
||||
* decrypting a ciphertext, we must have |flen| <= |num|. Similarly,
|
||||
* num < 2 * SHA_DIGEST_LENGTH + 2 must hold for the modulus
|
||||
* irrespective of the ciphertext, see PKCS #1 v2.2, section 7.1.2.
|
||||
* This does not leak any side-channel information.
|
||||
*/
|
||||
if (num < flen || num < 2 * SHA_DIGEST_LENGTH + 2)
|
||||
goto decoding_err;
|
||||
|
||||
lzero = num - flen;
|
||||
if (lzero < 0)
|
||||
{
|
||||
/* signalling this error immediately after detection might allow
|
||||
* for side-channel attacks (e.g. timing if 'plen' is huge
|
||||
* -- cf. James H. Manger, "A Chosen Ciphertext Attack on RSA Optimal
|
||||
* Asymmetric Encryption Padding (OAEP) [...]", CRYPTO 2001),
|
||||
* so we use a 'bad' flag */
|
||||
bad = 1;
|
||||
lzero = 0;
|
||||
flen = num; /* don't overflow the memcpy to padded_from */
|
||||
}
|
||||
|
||||
dblen = num - SHA_DIGEST_LENGTH;
|
||||
db = OPENSSL_malloc(dblen + num);
|
||||
if (db == NULL)
|
||||
dblen = num - SHA_DIGEST_LENGTH - 1;
|
||||
db = OPENSSL_malloc(dblen);
|
||||
em = OPENSSL_malloc(num);
|
||||
if (db == NULL || em == NULL)
|
||||
{
|
||||
RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, ERR_R_MALLOC_FAILURE);
|
||||
return -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Always do this zero-padding copy (even when lzero == 0)
|
||||
* to avoid leaking timing info about the value of lzero. */
|
||||
padded_from = db + dblen;
|
||||
memset(padded_from, 0, lzero);
|
||||
memcpy(padded_from + lzero, from, flen);
|
||||
/*
|
||||
* Always do this zero-padding copy (even when num == flen) to avoid
|
||||
* leaking that information. The copy still leaks some side-channel
|
||||
* information, but it's impossible to have a fixed memory access
|
||||
* pattern since we can't read out of the bounds of |from|.
|
||||
*
|
||||
* TODO(emilia): Consider porting BN_bn2bin_padded from BoringSSL.
|
||||
*/
|
||||
memset(em, 0, num);
|
||||
memcpy(em + num - flen, from, flen);
|
||||
|
||||
maskeddb = padded_from + SHA_DIGEST_LENGTH;
|
||||
/*
|
||||
* The first byte must be zero, however we must not leak if this is
|
||||
* true. See James H. Manger, "A Chosen Ciphertext Attack on RSA
|
||||
* Optimal Asymmetric Encryption Padding (OAEP) [...]", CRYPTO 2001).
|
||||
*/
|
||||
good = constant_time_is_zero(em[0]);
|
||||
|
||||
maskedseed = em + 1;
|
||||
maskeddb = em + 1 + SHA_DIGEST_LENGTH;
|
||||
|
||||
if (MGF1(seed, SHA_DIGEST_LENGTH, maskeddb, dblen))
|
||||
return -1;
|
||||
goto cleanup;
|
||||
for (i = 0; i < SHA_DIGEST_LENGTH; i++)
|
||||
seed[i] ^= padded_from[i];
|
||||
|
||||
seed[i] ^= maskedseed[i];
|
||||
|
||||
if (MGF1(db, dblen, seed, SHA_DIGEST_LENGTH))
|
||||
return -1;
|
||||
goto cleanup;
|
||||
for (i = 0; i < dblen; i++)
|
||||
db[i] ^= maskeddb[i];
|
||||
|
||||
EVP_Digest((void *)param, plen, phash, NULL, EVP_sha1(), NULL);
|
||||
|
||||
if (CRYPTO_memcmp(db, phash, SHA_DIGEST_LENGTH) != 0 || bad)
|
||||
good &= constant_time_is_zero(CRYPTO_memcmp(db, phash, SHA_DIGEST_LENGTH));
|
||||
|
||||
found_one_byte = 0;
|
||||
for (i = SHA_DIGEST_LENGTH; i < dblen; i++)
|
||||
{
|
||||
/* Padding consists of a number of 0-bytes, followed by a 1. */
|
||||
unsigned int equals1 = constant_time_eq(db[i], 1);
|
||||
unsigned int equals0 = constant_time_is_zero(db[i]);
|
||||
one_index = constant_time_select_int(~found_one_byte & equals1,
|
||||
i, one_index);
|
||||
found_one_byte |= equals1;
|
||||
good &= (found_one_byte | equals0);
|
||||
}
|
||||
|
||||
good &= found_one_byte;
|
||||
|
||||
/*
|
||||
* At this point |good| is zero unless the plaintext was valid,
|
||||
* so plaintext-awareness ensures timing side-channels are no longer a
|
||||
* concern.
|
||||
*/
|
||||
if (!good)
|
||||
goto decoding_err;
|
||||
|
||||
msg_index = one_index + 1;
|
||||
mlen = dblen - msg_index;
|
||||
|
||||
if (tlen < mlen)
|
||||
{
|
||||
RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, RSA_R_DATA_TOO_LARGE);
|
||||
mlen = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = SHA_DIGEST_LENGTH; i < dblen; i++)
|
||||
if (db[i] != 0x00)
|
||||
break;
|
||||
if (i == dblen || db[i] != 0x01)
|
||||
goto decoding_err;
|
||||
else
|
||||
{
|
||||
/* everything looks OK */
|
||||
|
||||
mlen = dblen - ++i;
|
||||
if (tlen < mlen)
|
||||
{
|
||||
RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, RSA_R_DATA_TOO_LARGE);
|
||||
mlen = -1;
|
||||
}
|
||||
else
|
||||
memcpy(to, db + i, mlen);
|
||||
}
|
||||
memcpy(to, db + msg_index, mlen);
|
||||
goto cleanup;
|
||||
}
|
||||
OPENSSL_free(db);
|
||||
return mlen;
|
||||
|
||||
decoding_err:
|
||||
/* to avoid chosen ciphertext attacks, the error message should not reveal
|
||||
* which kind of decoding error happened */
|
||||
/* To avoid chosen ciphertext attacks, the error message should not reveal
|
||||
* which kind of decoding error happened. */
|
||||
RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, RSA_R_OAEP_DECODING_ERROR);
|
||||
cleanup:
|
||||
if (db != NULL) OPENSSL_free(db);
|
||||
return -1;
|
||||
if (em != NULL) OPENSSL_free(em);
|
||||
return mlen;
|
||||
}
|
||||
|
||||
int PKCS1_MGF1(unsigned char *mask, long len,
|
||||
|
||||
@@ -56,6 +56,8 @@
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include "constant_time_locl.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include "cryptlib.h"
|
||||
#include <openssl/bn.h>
|
||||
@@ -181,44 +183,87 @@ int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen,
|
||||
int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen,
|
||||
const unsigned char *from, int flen, int num)
|
||||
{
|
||||
int i,j;
|
||||
const unsigned char *p;
|
||||
int i;
|
||||
/* |em| is the encoded message, zero-padded to exactly |num| bytes */
|
||||
unsigned char *em = NULL;
|
||||
unsigned int good, found_zero_byte;
|
||||
int zero_index = 0, msg_index, mlen = -1;
|
||||
|
||||
p=from;
|
||||
if ((num != (flen+1)) || (*(p++) != 02))
|
||||
if (tlen < 0 || flen < 0)
|
||||
return -1;
|
||||
|
||||
/* PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography
|
||||
* Standard", section 7.2.2. */
|
||||
|
||||
if (flen > num)
|
||||
goto err;
|
||||
|
||||
if (num < 11)
|
||||
goto err;
|
||||
|
||||
em = OPENSSL_malloc(num);
|
||||
if (em == NULL)
|
||||
{
|
||||
RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,RSA_R_BLOCK_TYPE_IS_NOT_02);
|
||||
return(-1);
|
||||
RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, ERR_R_MALLOC_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
#ifdef PKCS1_CHECK
|
||||
return(num-11);
|
||||
#endif
|
||||
memset(em, 0, num);
|
||||
/*
|
||||
* Always do this zero-padding copy (even when num == flen) to avoid
|
||||
* leaking that information. The copy still leaks some side-channel
|
||||
* information, but it's impossible to have a fixed memory access
|
||||
* pattern since we can't read out of the bounds of |from|.
|
||||
*
|
||||
* TODO(emilia): Consider porting BN_bn2bin_padded from BoringSSL.
|
||||
*/
|
||||
memcpy(em + num - flen, from, flen);
|
||||
|
||||
/* scan over padding data */
|
||||
j=flen-1; /* one for type. */
|
||||
for (i=0; i<j; i++)
|
||||
if (*(p++) == 0) break;
|
||||
good = constant_time_is_zero(em[0]);
|
||||
good &= constant_time_eq(em[1], 2);
|
||||
|
||||
if (i == j)
|
||||
found_zero_byte = 0;
|
||||
for (i = 2; i < num; i++)
|
||||
{
|
||||
RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,RSA_R_NULL_BEFORE_BLOCK_MISSING);
|
||||
return(-1);
|
||||
unsigned int equals0 = constant_time_is_zero(em[i]);
|
||||
zero_index = constant_time_select_int(~found_zero_byte & equals0, i, zero_index);
|
||||
found_zero_byte |= equals0;
|
||||
}
|
||||
|
||||
if (i < 8)
|
||||
{
|
||||
RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,RSA_R_BAD_PAD_BYTE_COUNT);
|
||||
return(-1);
|
||||
}
|
||||
i++; /* Skip over the '\0' */
|
||||
j-=i;
|
||||
if (j > tlen)
|
||||
{
|
||||
RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,RSA_R_DATA_TOO_LARGE);
|
||||
return(-1);
|
||||
}
|
||||
memcpy(to,p,(unsigned int)j);
|
||||
/*
|
||||
* PS must be at least 8 bytes long, and it starts two bytes into |em|.
|
||||
* If we never found a 0-byte, then |zero_index| is 0 and the check
|
||||
* also fails.
|
||||
*/
|
||||
good &= constant_time_ge((unsigned int)(zero_index), 2 + 8);
|
||||
|
||||
return(j);
|
||||
/* Skip the zero byte. This is incorrect if we never found a zero-byte
|
||||
* but in this case we also do not copy the message out. */
|
||||
msg_index = zero_index + 1;
|
||||
mlen = num - msg_index;
|
||||
|
||||
/* For good measure, do this check in constant time as well; it could
|
||||
* leak something if |tlen| was assuming valid padding. */
|
||||
good &= constant_time_ge((unsigned int)(tlen), (unsigned int)(mlen));
|
||||
|
||||
/*
|
||||
* We can't continue in constant-time because we need to copy the result
|
||||
* and we cannot fake its length. This unavoidably leaks timing
|
||||
* information at the API boundary.
|
||||
* TODO(emilia): this could be addressed at the call site,
|
||||
* see BoringSSL commit 0aa0767340baf925bda4804882aab0cb974b2d26.
|
||||
*/
|
||||
if (!good)
|
||||
{
|
||||
mlen = -1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
memcpy(to, em + msg_index, mlen);
|
||||
|
||||
err:
|
||||
if (em != NULL)
|
||||
OPENSSL_free(em);
|
||||
if (mlen == -1)
|
||||
RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, RSA_R_PKCS_DECODING_ERROR);
|
||||
return mlen;
|
||||
}
|
||||
|
||||
|
||||
@@ -143,6 +143,25 @@ int RSA_sign(int type, const unsigned char *m, unsigned int m_len,
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check DigestInfo structure does not contain extraneous data by reencoding
|
||||
* using DER and checking encoding against original.
|
||||
*/
|
||||
static int rsa_check_digestinfo(X509_SIG *sig, const unsigned char *dinfo, int dinfolen)
|
||||
{
|
||||
unsigned char *der = NULL;
|
||||
int derlen;
|
||||
int ret = 0;
|
||||
derlen = i2d_X509_SIG(sig, &der);
|
||||
if (derlen <= 0)
|
||||
return 0;
|
||||
if (derlen == dinfolen && !memcmp(dinfo, der, derlen))
|
||||
ret = 1;
|
||||
OPENSSL_cleanse(der, derlen);
|
||||
OPENSSL_free(der);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int int_rsa_verify(int dtype, const unsigned char *m,
|
||||
unsigned int m_len,
|
||||
unsigned char *rm, size_t *prm_len,
|
||||
@@ -195,7 +214,7 @@ int int_rsa_verify(int dtype, const unsigned char *m,
|
||||
if (sig == NULL) goto err;
|
||||
|
||||
/* Excess data can be used to create forgeries */
|
||||
if(p != s+i)
|
||||
if(p != s+i || !rsa_check_digestinfo(sig, s, i))
|
||||
{
|
||||
RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
|
||||
goto err;
|
||||
|
||||
@@ -977,7 +977,7 @@ TS_RESP_set_genTime_with_precision(ASN1_GENERALIZEDTIME *asn1_time,
|
||||
if (precision > 0)
|
||||
{
|
||||
/* Add fraction of seconds (leave space for dot and null). */
|
||||
BIO_snprintf(p, 2 + precision, ".%ld", usec);
|
||||
BIO_snprintf(p, 2 + precision, ".%06ld", usec);
|
||||
/* We cannot use the snprintf return value,
|
||||
because it might have been truncated. */
|
||||
p += strlen(p);
|
||||
|
||||
@@ -763,6 +763,7 @@ X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn);
|
||||
int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval);
|
||||
void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
|
||||
X509_ALGOR *algor);
|
||||
int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b);
|
||||
|
||||
X509_NAME *X509_NAME_dup(X509_NAME *xn);
|
||||
X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne);
|
||||
|
||||
@@ -89,6 +89,8 @@ X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void)
|
||||
{
|
||||
X509_VERIFY_PARAM *param;
|
||||
param = OPENSSL_malloc(sizeof(X509_VERIFY_PARAM));
|
||||
if (!param)
|
||||
return NULL;
|
||||
memset(param, 0, sizeof(X509_VERIFY_PARAM));
|
||||
x509_verify_param_zero(param);
|
||||
return param;
|
||||
|
||||
@@ -72,6 +72,8 @@
|
||||
|
||||
int X509_verify(X509 *a, EVP_PKEY *r)
|
||||
{
|
||||
if (X509_ALGOR_cmp(a->sig_alg, a->cert_info->signature))
|
||||
return 0;
|
||||
return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF),a->sig_alg,
|
||||
a->signature,a->cert_info,r));
|
||||
}
|
||||
|
||||
@@ -1,74 +1,69 @@
|
||||
<DRAFT!>
|
||||
HOWTO proxy certificates
|
||||
|
||||
0. WARNING
|
||||
|
||||
NONE OF THE CODE PRESENTED HERE HAVE BEEN CHECKED! They are just an
|
||||
example to show you how things can be done. There may be typos or
|
||||
type conflicts, and you will have to resolve them.
|
||||
NONE OF THE CODE PRESENTED HERE HAS BEEN CHECKED! The code is just examples to
|
||||
show you how things could be done. There might be typos or type conflicts, and
|
||||
you will have to resolve them.
|
||||
|
||||
1. Introduction
|
||||
|
||||
Proxy certificates are defined in RFC 3820. They are really usual
|
||||
certificates with the mandatory extension proxyCertInfo.
|
||||
Proxy certificates are defined in RFC 3820. They are really usual certificates
|
||||
with the mandatory extension proxyCertInfo.
|
||||
|
||||
Proxy certificates are issued by an End Entity (typically a user),
|
||||
either directly with the EE certificate as issuing certificate, or by
|
||||
extension through an already issued proxy certificate.. They are used
|
||||
to extend rights to some other entity (a computer process, typically,
|
||||
or sometimes to the user itself), so it can perform operations in the
|
||||
name of the owner of the EE certificate.
|
||||
Proxy certificates are issued by an End Entity (typically a user), either
|
||||
directly with the EE certificate as issuing certificate, or by extension through
|
||||
an already issued proxy certificate. Proxy certificates are used to extend
|
||||
rights to some other entity (a computer process, typically, or sometimes to the
|
||||
user itself). This allows the entity to perform operations on behalf of the
|
||||
owner of the EE certificate.
|
||||
|
||||
See http://www.ietf.org/rfc/rfc3820.txt for more information.
|
||||
|
||||
|
||||
2. A warning about proxy certificates
|
||||
|
||||
Noone seems to have tested proxy certificates with security in mind.
|
||||
Basically, to this date, it seems that proxy certificates have only
|
||||
been used in a world that's highly aware of them. What would happen
|
||||
if an unsuspecting application is to validate a chain of certificates
|
||||
that contains proxy certificates? It would usually consider the leaf
|
||||
to be the certificate to check for authorisation data, and since proxy
|
||||
certificates are controlled by the EE certificate owner alone, it's
|
||||
would be normal to consider what the EE certificate owner could do
|
||||
with them.
|
||||
No one seems to have tested proxy certificates with security in mind. To this
|
||||
date, it seems that proxy certificates have only been used in a context highly
|
||||
aware of them.
|
||||
|
||||
subjectAltName and issuerAltName are forbidden in proxy certificates,
|
||||
and this is enforced in OpenSSL. The subject must be the same as the
|
||||
issuer, with one commonName added on.
|
||||
Existing applications might misbehave when trying to validate a chain of
|
||||
certificates which use a proxy certificate. They might incorrectly consider the
|
||||
leaf to be the certificate to check for authorisation data, which is controlled
|
||||
by the EE certificate owner.
|
||||
|
||||
Possible threats are, as far as has been imagined so far:
|
||||
subjectAltName and issuerAltName are forbidden in proxy certificates, and this
|
||||
is enforced in OpenSSL. The subject must be the same as the issuer, with one
|
||||
commonName added on.
|
||||
|
||||
Possible threats we can think of at this time include:
|
||||
|
||||
- impersonation through commonName (think server certificates).
|
||||
- use of additional extensions, possibly non-standard ones used in
|
||||
certain environments, that would grant extra or different
|
||||
authorisation rights.
|
||||
- use of additional extensions, possibly non-standard ones used in certain
|
||||
environments, that would grant extra or different authorisation rights.
|
||||
|
||||
For this reason, OpenSSL requires that the use of proxy certificates
|
||||
be explicitely allowed. Currently, this can be done using the
|
||||
following methods:
|
||||
For these reasons, OpenSSL requires that the use of proxy certificates be
|
||||
explicitly allowed. Currently, this can be done using the following methods:
|
||||
|
||||
- if the application calls X509_verify_cert() itself, it can do the
|
||||
following prior to that call (ctx is the pointer passed in the call
|
||||
to X509_verify_cert()):
|
||||
- if the application directly calls X509_verify_cert(), it can first call:
|
||||
|
||||
X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS);
|
||||
X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS);
|
||||
|
||||
- in all other cases, proxy certificate validation can be enabled
|
||||
before starting the application by setting the envirnoment variable
|
||||
OPENSSL_ALLOW_PROXY_CERTS with some non-empty value.
|
||||
Where ctx is the pointer which then gets passed to X509_verify_cert().
|
||||
|
||||
There are thoughts to allow proxy certificates with a line in the
|
||||
default openssl.cnf, but that's still in the future.
|
||||
- proxy certificate validation can be enabled before starting the application
|
||||
by setting the environment variable OPENSSL_ALLOW_PROXY_CERTS.
|
||||
|
||||
In the future, it might be possible to enable proxy certificates by editing
|
||||
openssl.cnf.
|
||||
|
||||
|
||||
3. How to create proxy cerificates
|
||||
3. How to create proxy certificates
|
||||
|
||||
It's quite easy to create proxy certificates, by taking advantage of
|
||||
the lack of checks of the 'openssl x509' application (*ahem*). But
|
||||
first, you need to create a configuration section that contains a
|
||||
definition of the proxyCertInfo extension, a little like this:
|
||||
Creating proxy certificates is quite easy, by taking advantage of a lack of
|
||||
checks in the 'openssl x509' application (*ahem*). You must first create a
|
||||
configuration section that contains a definition of the proxyCertInfo extension,
|
||||
for example:
|
||||
|
||||
[ v3_proxy ]
|
||||
# A proxy certificate MUST NEVER be a CA certificate.
|
||||
@@ -77,10 +72,10 @@ definition of the proxyCertInfo extension, a little like this:
|
||||
# Usual authority key ID
|
||||
authorityKeyIdentifier=keyid,issuer:always
|
||||
|
||||
# Now, for the extension that marks this certificate as a proxy one
|
||||
# The extension which marks this certificate as a proxy
|
||||
proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:1,policy:text:AB
|
||||
|
||||
It's also possible to give the proxy extension in a separate section:
|
||||
It's also possible to specify the proxy extension in a separate section:
|
||||
|
||||
proxyCertInfo=critical,@proxy_ext
|
||||
|
||||
@@ -89,38 +84,32 @@ It's also possible to give the proxy extension in a separate section:
|
||||
pathlen=0
|
||||
policy=text:BC
|
||||
|
||||
The policy value has a specific syntax, {syntag}:{string}, where the
|
||||
syntag determines what will be done with the string. The recognised
|
||||
syntags are as follows:
|
||||
The policy value has a specific syntax, {syntag}:{string}, where the syntag
|
||||
determines what will be done with the string. The following syntags are
|
||||
recognised:
|
||||
|
||||
text indicates that the string is simply the bytes, not
|
||||
encoded in any kind of way:
|
||||
text indicates that the string is simply bytes, without any encoding:
|
||||
|
||||
policy=text:r<EFBFBD>ksm<EFBFBD>rg<EFBFBD>s
|
||||
policy=text:räksmörgås
|
||||
|
||||
Previous versions of this design had a specific tag
|
||||
for UTF-8 text. However, since the bytes are copied
|
||||
as-is anyway, there's no need for it. Instead, use
|
||||
the text: tag, like this:
|
||||
Previous versions of this design had a specific tag for UTF-8 text.
|
||||
However, since the bytes are copied as-is anyway, there is no need for
|
||||
such a specific tag.
|
||||
|
||||
policy=text:räksmörgås
|
||||
hex indicates the string is encoded in hex, with colons between each byte
|
||||
(every second hex digit):
|
||||
|
||||
hex indicates the string is encoded in hex, with colons
|
||||
between each byte (every second hex digit):
|
||||
policy=hex:72:E4:6B:73:6D:F6:72:67:E5:73
|
||||
|
||||
policy=hex:72:E4:6B:73:6D:F6:72:67:E5:73
|
||||
Previous versions of this design had a tag to insert a complete DER
|
||||
blob. However, the only legal use for this would be to surround the
|
||||
bytes that would go with the hex: tag with whatever is needed to
|
||||
construct a correct OCTET STRING. The DER tag therefore felt
|
||||
superfluous, and was removed.
|
||||
|
||||
Previous versions of this design had a tag to insert a
|
||||
complete DER blob. However, the only legal use for
|
||||
this would be to surround the bytes that would go with
|
||||
the hex: tag with what's needed to construct a correct
|
||||
OCTET STRING. Since hex: does that, the DER tag felt
|
||||
superfluous, and was therefore removed.
|
||||
|
||||
file indicates that the text of the policy should really be
|
||||
taken from a file. The string is then really a file
|
||||
name. This is useful for policies that are large
|
||||
(more than a few of lines) XML documents, for example.
|
||||
file indicates that the text of the policy should really be taken from a
|
||||
file. The string is then really a file name. This is useful for
|
||||
policies that are large (more than a few lines, e.g. XML documents).
|
||||
|
||||
The 'policy' setting can be split up in multiple lines like this:
|
||||
|
||||
@@ -128,57 +117,52 @@ The 'policy' setting can be split up in multiple lines like this:
|
||||
1.polisy= a multi-
|
||||
2.policy=line policy.
|
||||
|
||||
NOTE: the proxy policy value is the part that determines the rights
|
||||
granted to the process using the proxy certificate. The value is
|
||||
completely dependent on the application reading and interpretting it!
|
||||
NOTE: the proxy policy value is the part which determines the rights granted to
|
||||
the process using the proxy certificate. The value is completely dependent on
|
||||
the application reading and interpreting it!
|
||||
|
||||
Now that you have created an extension section for your proxy
|
||||
certificate, you can now easily create a proxy certificate like this:
|
||||
Now that you have created an extension section for your proxy certificate, you
|
||||
can easily create a proxy certificate by doing:
|
||||
|
||||
openssl req -new -config openssl.cnf \
|
||||
-out proxy.req -keyout proxy.key
|
||||
openssl x509 -req -CAcreateserial -in proxy.req -days 7 \
|
||||
-out proxy.crt -CA user.crt -CAkey user.key \
|
||||
-extfile openssl.cnf -extensions v3_proxy
|
||||
openssl req -new -config openssl.cnf -out proxy.req -keyout proxy.key
|
||||
openssl x509 -req -CAcreateserial -in proxy.req -days 7 -out proxy.crt \
|
||||
-CA user.crt -CAkey user.key -extfile openssl.cnf -extensions v3_proxy
|
||||
|
||||
It's just as easy to create a proxy certificate using another proxy
|
||||
certificate as issuer (note that I'm using a different configuration
|
||||
section for it):
|
||||
You can also create a proxy certificate using another proxy certificate as
|
||||
issuer (note: I'm using a different configuration section for it):
|
||||
|
||||
openssl req -new -config openssl.cnf \
|
||||
-out proxy2.req -keyout proxy2.key
|
||||
openssl x509 -req -CAcreateserial -in proxy2.req -days 7 \
|
||||
-out proxy2.crt -CA proxy.crt -CAkey proxy.key \
|
||||
-extfile openssl.cnf -extensions v3_proxy2
|
||||
openssl req -new -config openssl.cnf -out proxy2.req -keyout proxy2.key
|
||||
openssl x509 -req -CAcreateserial -in proxy2.req -days 7 -out proxy2.crt \
|
||||
-CA proxy.crt -CAkey proxy.key -extfile openssl.cnf -extensions v3_proxy2
|
||||
|
||||
|
||||
4. How to have your application interpret the policy?
|
||||
|
||||
The basic way to interpret proxy policies is to prepare some default
|
||||
rights, then do a check of the proxy certificate against the a chain
|
||||
of proxy certificates, user certificate and CA certificates, and see
|
||||
what rights came out by the end. Sounds easy, huh? It almost is.
|
||||
The basic way to interpret proxy policies is to start with some default rights,
|
||||
then compute the resulting rights by checking the proxy certificate against
|
||||
the chain of proxy certificates, user certificate and CA certificates. You then
|
||||
use the final computed rights. Sounds easy, huh? It almost is.
|
||||
|
||||
The slightly complicated part is how to pass data between your
|
||||
The slightly complicated part is figuring out how to pass data between your
|
||||
application and the certificate validation procedure.
|
||||
|
||||
You need the following ingredients:
|
||||
|
||||
- a callback routing that will be called for every certificate that's
|
||||
validated. It will be called several times for each certificates,
|
||||
so you must be attentive to when it's a good time to do the proxy
|
||||
policy interpretation and check, as well as to fill in the defaults
|
||||
when the EE certificate is checked.
|
||||
- a callback function that will be called for every certificate being
|
||||
validated. The callback be called several times for each certificate,
|
||||
so you must be careful to do the proxy policy interpretation at the right
|
||||
time. You also need to fill in the defaults when the EE certificate is
|
||||
checked.
|
||||
|
||||
- a structure of data that's shared between your application code and
|
||||
the callback.
|
||||
- a data structure that is shared between your application code and the
|
||||
callback.
|
||||
|
||||
- a wrapper function that sets it all up.
|
||||
|
||||
- an ex_data index function that creates an index into the generic
|
||||
ex_data store that's attached to an X509 validation context.
|
||||
- an ex_data index function that creates an index into the generic ex_data
|
||||
store that is attached to an X509 validation context.
|
||||
|
||||
This is some cookbook code for you to fill in:
|
||||
Here is some skeleton code you can fill in:
|
||||
|
||||
/* In this example, I will use a view of granted rights as a bit
|
||||
array, one bit for each possible right. */
|
||||
@@ -210,7 +194,7 @@ This is some cookbook code for you to fill in:
|
||||
static int verify_callback(int ok, X509_STORE_CTX *ctx)
|
||||
{
|
||||
if (ok == 1) /* It's REALLY important you keep the proxy policy
|
||||
check within this secion. It's important to know
|
||||
check within this section. It's important to know
|
||||
that when ok is 1, the certificates are checked
|
||||
from top to bottom. You get the CA root first,
|
||||
followed by the possible chain of intermediate
|
||||
@@ -221,7 +205,7 @@ This is some cookbook code for you to fill in:
|
||||
|
||||
if (xs->ex_flags & EXFLAG_PROXY)
|
||||
{
|
||||
YOUR_RIGHTS *rights =
|
||||
YOUR_RIGHTS *rights =
|
||||
(YOUR_RIGHTS *)X509_STORE_CTX_get_ex_data(ctx,
|
||||
get_proxy_auth_ex_data_idx());
|
||||
PROXY_CERT_INFO_EXTENSION *pci =
|
||||
@@ -250,12 +234,12 @@ This is some cookbook code for you to fill in:
|
||||
bit array and fill it with the rights granted by
|
||||
the current proxy certificate, then use it as a
|
||||
mask on the accumulated rights bit array, and
|
||||
voil<EFBFBD>, you now have a new accumulated rights bit
|
||||
voilà, you now have a new accumulated rights bit
|
||||
array. */
|
||||
{
|
||||
int i;
|
||||
YOUR_RIGHTS tmp_rights;
|
||||
memset(tmp_rights.rights, 0, sizeof(tmp_rights.rights));
|
||||
memset(tmp_rights.rights, 0, sizeof(tmp_rights.rights));
|
||||
|
||||
/* process_rights() is supposed to be a procedure
|
||||
that takes a string and it's length, interprets
|
||||
@@ -276,7 +260,7 @@ This is some cookbook code for you to fill in:
|
||||
{
|
||||
/* We have a EE certificate, let's use it to set default!
|
||||
*/
|
||||
YOUR_RIGHTS *rights =
|
||||
YOUR_RIGHTS *rights =
|
||||
(YOUR_RIGHTS *)X509_STORE_CTX_get_ex_data(ctx,
|
||||
get_proxy_auth_ex_data_idx());
|
||||
|
||||
|
||||
@@ -133,6 +133,10 @@ if the B<host> option is present then the OCSP request is sent to the host
|
||||
B<hostname> on port B<port>. B<path> specifies the HTTP path name to use
|
||||
or "/" by default.
|
||||
|
||||
=item B<-timeout seconds>
|
||||
|
||||
connection timeout to the OCSP responder in seconds
|
||||
|
||||
=item B<-CAfile file>, B<-CApath pathname>
|
||||
|
||||
file or pathname containing trusted CA certificates. These are used to verify
|
||||
|
||||
@@ -37,6 +37,7 @@ B<openssl> B<s_client>
|
||||
[B<-no_ssl2>]
|
||||
[B<-no_ssl3>]
|
||||
[B<-no_tls1>]
|
||||
[B<-fallback_scsv>]
|
||||
[B<-bugs>]
|
||||
[B<-cipher cipherlist>]
|
||||
[B<-serverpref>]
|
||||
@@ -201,10 +202,13 @@ these options disable the use of certain SSL or TLS protocols. By default
|
||||
the initial handshake uses a method which should be compatible with all
|
||||
servers and permit them to use SSL v3, SSL v2 or TLS as appropriate.
|
||||
|
||||
Unfortunately there are a lot of ancient and broken servers in use which
|
||||
Unfortunately there are still ancient and broken servers in use which
|
||||
cannot handle this technique and will fail to connect. Some servers only
|
||||
work if TLS is turned off with the B<-no_tls> option others will only
|
||||
support SSL v2 and may need the B<-ssl2> option.
|
||||
work if TLS is turned off.
|
||||
|
||||
=item B<-fallback_scsv>
|
||||
|
||||
Send TLS_FALLBACK_SCSV in the ClientHello.
|
||||
|
||||
=item B<-bugs>
|
||||
|
||||
|
||||
@@ -59,8 +59,8 @@ the accept socket. See L<BIO_s_fd(3)|BIO_s_fd(3)>
|
||||
BIO_set_accept_port() uses the string B<name> to set the accept
|
||||
port. The port is represented as a string of the form "host:port",
|
||||
where "host" is the interface to use and "port" is the port.
|
||||
Either or both values can be "*" which is interpreted as meaning
|
||||
any interface or port respectively. "port" has the same syntax
|
||||
The host can be can be "*" which is interpreted as meaning
|
||||
any interface; "port" has the same syntax
|
||||
as the port specified in BIO_set_conn_port() for connect BIOs,
|
||||
that is it can be a numerical port string or a string to lookup
|
||||
using getservbyname() and a string table.
|
||||
|
||||
@@ -2,20 +2,20 @@
|
||||
|
||||
=head1 NAME
|
||||
|
||||
CMS_sign_add1_signer, CMS_SignerInfo_sign - add a signer to a CMS_ContentInfo signed data structure.
|
||||
CMS_add1_signer, CMS_SignerInfo_sign - add a signer to a CMS_ContentInfo signed data structure.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
#include <openssl/cms.h>
|
||||
|
||||
CMS_SignerInfo *CMS_sign_add1_signer(CMS_ContentInfo *cms, X509 *signcert, EVP_PKEY *pkey, const EVP_MD *md, unsigned int flags);
|
||||
CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, X509 *signcert, EVP_PKEY *pkey, const EVP_MD *md, unsigned int flags);
|
||||
|
||||
int CMS_SignerInfo_sign(CMS_SignerInfo *si);
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
CMS_sign_add1_signer() adds a signer with certificate B<signcert> and private
|
||||
CMS_add1_signer() adds a signer with certificate B<signcert> and private
|
||||
key B<pkey> using message digest B<md> to CMS_ContentInfo SignedData
|
||||
structure B<cms>.
|
||||
|
||||
@@ -36,7 +36,7 @@ are both set.
|
||||
|
||||
=head1 NOTES
|
||||
|
||||
The main purpose of CMS_sign_add1_signer() is to provide finer control
|
||||
The main purpose of CMS_add1_signer() is to provide finer control
|
||||
over a CMS signed data structure where the simpler CMS_sign() function defaults
|
||||
are not appropriate. For example if multiple signers or non default digest
|
||||
algorithms are needed. New attributes can also be added using the returned
|
||||
@@ -80,13 +80,13 @@ bit AES, 128 bit AES, triple DES, 128 bit RC2, 64 bit RC2, DES and 40 bit RC2.
|
||||
If any of these algorithms is not available then it will not be included: for example the GOST algorithms will not be included if the GOST ENGINE is
|
||||
not loaded.
|
||||
|
||||
CMS_sign_add1_signer() returns an internal pointer to the CMS_SignerInfo
|
||||
CMS_add1_signer() returns an internal pointer to the CMS_SignerInfo
|
||||
structure just added, this can be used to set additional attributes
|
||||
before it is finalized.
|
||||
|
||||
=head1 RETURN VALUES
|
||||
|
||||
CMS_sign1_add_signers() returns an internal pointer to the CMS_SignerInfo
|
||||
CMS_add1_signer() returns an internal pointer to the CMS_SignerInfo
|
||||
structure just added or NULL if an error occurs.
|
||||
|
||||
=head1 SEE ALSO
|
||||
@@ -96,6 +96,6 @@ L<CMS_final(3)|CMS_final(3)>,
|
||||
|
||||
=head1 HISTORY
|
||||
|
||||
CMS_sign_add1_signer() was added to OpenSSL 0.9.8
|
||||
CMS_add1_signer() was added to OpenSSL 0.9.8
|
||||
|
||||
=cut
|
||||
@@ -26,13 +26,13 @@ EVP digest routines
|
||||
int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx);
|
||||
void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx);
|
||||
|
||||
int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out,const EVP_MD_CTX *in);
|
||||
int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out,const EVP_MD_CTX *in);
|
||||
|
||||
int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type);
|
||||
int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md,
|
||||
unsigned int *s);
|
||||
|
||||
int EVP_MD_CTX_copy(EVP_MD_CTX *out,EVP_MD_CTX *in);
|
||||
int EVP_MD_CTX_copy(EVP_MD_CTX *out,EVP_MD_CTX *in);
|
||||
|
||||
#define EVP_MAX_MD_SIZE 64 /* SHA512 */
|
||||
|
||||
@@ -136,10 +136,10 @@ reasons.
|
||||
EVP_md2(), EVP_md5(), EVP_sha(), EVP_sha1(), EVP_sha224(), EVP_sha256(),
|
||||
EVP_sha384(), EVP_sha512(), EVP_mdc2() and EVP_ripemd160() return B<EVP_MD>
|
||||
structures for the MD2, MD5, SHA, SHA1, SHA224, SHA256, SHA384, SHA512, MDC2
|
||||
and RIPEMD160 digest algorithms respectively.
|
||||
and RIPEMD160 digest algorithms respectively.
|
||||
|
||||
EVP_dss() and EVP_dss1() return B<EVP_MD> structures for SHA and SHA1 digest
|
||||
algorithms but using DSS (DSA) for the signature algorithm. Note: there is
|
||||
algorithms but using DSS (DSA) for the signature algorithm. Note: there is
|
||||
no need to use these pseudo-digests in OpenSSL 1.0.0 and later, they are
|
||||
however retained for compatibility.
|
||||
|
||||
@@ -177,21 +177,21 @@ The B<EVP> interface to message digests should almost always be used in
|
||||
preference to the low level interfaces. This is because the code then becomes
|
||||
transparent to the digest used and much more flexible.
|
||||
|
||||
New applications should use the SHA2 digest algorithms such as SHA256.
|
||||
New applications should use the SHA2 digest algorithms such as SHA256.
|
||||
The other digest algorithms are still in common use.
|
||||
|
||||
For most applications the B<impl> parameter to EVP_DigestInit_ex() will be
|
||||
set to NULL to use the default digest implementation.
|
||||
|
||||
The functions EVP_DigestInit(), EVP_DigestFinal() and EVP_MD_CTX_copy() are
|
||||
The functions EVP_DigestInit(), EVP_DigestFinal() and EVP_MD_CTX_copy() are
|
||||
obsolete but are retained to maintain compatibility with existing code. New
|
||||
applications should use EVP_DigestInit_ex(), EVP_DigestFinal_ex() and
|
||||
applications should use EVP_DigestInit_ex(), EVP_DigestFinal_ex() and
|
||||
EVP_MD_CTX_copy_ex() because they can efficiently reuse a digest context
|
||||
instead of initializing and cleaning it up on each call and allow non default
|
||||
implementations of digests to be specified.
|
||||
|
||||
In OpenSSL 0.9.7 and later if digest contexts are not cleaned up after use
|
||||
memory leaks will occur.
|
||||
memory leaks will occur.
|
||||
|
||||
Stack allocation of EVP_MD_CTX structures is common, for example:
|
||||
|
||||
@@ -245,15 +245,19 @@ digest name passed on the command line.
|
||||
EVP_MD_CTX_destroy(mdctx);
|
||||
|
||||
printf("Digest is: ");
|
||||
for(i = 0; i < md_len; i++) printf("%02x", md_value[i]);
|
||||
for(i = 0; i < md_len; i++)
|
||||
printf("%02x", md_value[i]);
|
||||
printf("\n");
|
||||
|
||||
/* Call this once before exit. */
|
||||
EVP_cleanup();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<evp(3)|evp(3)>, L<hmac(3)|hmac(3)>, L<md2(3)|md2(3)>,
|
||||
L<md5(3)|md5(3)>, L<mdc2(3)|mdc2(3)>, L<ripemd(3)|ripemd(3)>,
|
||||
L<sha(3)|sha(3)>, L<dgst(1)|dgst(1)>
|
||||
L<dgst(1)|dgst(1)>,
|
||||
L<evp(3)|evp(3)>
|
||||
|
||||
=head1 HISTORY
|
||||
|
||||
@@ -269,7 +273,7 @@ EVP_dss(), EVP_dss1(), EVP_mdc2() and EVP_ripemd160() were
|
||||
changed to return truely const EVP_MD * in OpenSSL 0.9.7.
|
||||
|
||||
The link between digests and signing algorithms was fixed in OpenSSL 1.0 and
|
||||
later, so now EVP_sha1() can be used with RSA and DSA, there is no need to
|
||||
later, so now EVP_sha1() can be used with RSA and DSA; there is no need to
|
||||
use EVP_dss1() any more.
|
||||
|
||||
OpenSSL 1.0 and later does not include the MD2 digest algorithm in the
|
||||
|
||||
@@ -38,7 +38,7 @@ or a negative value for failure. In particular a return value of -2 indicates
|
||||
the operation is not supported by the public key algorithm.
|
||||
|
||||
Unlike other functions the return value 0 from EVP_DigestVerifyFinal() only
|
||||
indicates that the signature did not not verify successfully (that is tbs did
|
||||
indicates that the signature did not verify successfully (that is tbs did
|
||||
not match the original data or the signature was of invalid form) it is not an
|
||||
indication of a more serious error.
|
||||
|
||||
@@ -59,7 +59,7 @@ For some key types and parameters the random number generator must be seeded
|
||||
or the operation will fail.
|
||||
|
||||
The call to EVP_DigestVerifyFinal() internally finalizes a copy of the digest
|
||||
context. This means that calls to EVP_VerifyUpdate() and EVP_VerifyFinal() can
|
||||
context. This means that EVP_VerifyUpdate() and EVP_VerifyFinal() can
|
||||
be called later to digest and verify additional data.
|
||||
|
||||
Since only a copy of the digest context is ever finalized the context must
|
||||
|
||||
@@ -115,7 +115,7 @@ writes the encrypted version to B<out>. This function can be called
|
||||
multiple times to encrypt successive blocks of data. The amount
|
||||
of data written depends on the block alignment of the encrypted data:
|
||||
as a result the amount of data written may be anything from zero bytes
|
||||
to (inl + cipher_block_size - 1) so B<outl> should contain sufficient
|
||||
to (inl + cipher_block_size - 1) so B<out> should contain sufficient
|
||||
room. The actual number of bytes written is placed in B<outl>.
|
||||
|
||||
If padding is enabled (the default) then EVP_EncryptFinal_ex() encrypts
|
||||
@@ -384,27 +384,7 @@ for certain common S/MIME ciphers (RC2, DES, triple DES) in CBC mode.
|
||||
|
||||
=head1 EXAMPLES
|
||||
|
||||
Get the number of rounds used in RC5:
|
||||
|
||||
int nrounds;
|
||||
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GET_RC5_ROUNDS, 0, &nrounds);
|
||||
|
||||
Get the RC2 effective key length:
|
||||
|
||||
int key_bits;
|
||||
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GET_RC2_KEY_BITS, 0, &key_bits);
|
||||
|
||||
Set the number of rounds used in RC5:
|
||||
|
||||
int nrounds;
|
||||
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_SET_RC5_ROUNDS, nrounds, NULL);
|
||||
|
||||
Set the effective key length used in RC2:
|
||||
|
||||
int key_bits;
|
||||
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_SET_RC2_KEY_BITS, key_bits, NULL);
|
||||
|
||||
Encrypt a string using blowfish:
|
||||
Encrypt a string using IDEA:
|
||||
|
||||
int do_crypt(char *outfile)
|
||||
{
|
||||
@@ -418,8 +398,9 @@ Encrypt a string using blowfish:
|
||||
char intext[] = "Some Crypto Text";
|
||||
EVP_CIPHER_CTX ctx;
|
||||
FILE *out;
|
||||
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
EVP_EncryptInit_ex(&ctx, EVP_bf_cbc(), NULL, key, iv);
|
||||
EVP_EncryptInit_ex(&ctx, EVP_idea_cbc(), NULL, key, iv);
|
||||
|
||||
if(!EVP_EncryptUpdate(&ctx, outbuf, &outlen, intext, strlen(intext)))
|
||||
{
|
||||
@@ -448,28 +429,34 @@ Encrypt a string using blowfish:
|
||||
}
|
||||
|
||||
The ciphertext from the above example can be decrypted using the B<openssl>
|
||||
utility with the command line:
|
||||
utility with the command line (shown on two lines for clarity):
|
||||
|
||||
S<openssl bf -in cipher.bin -K 000102030405060708090A0B0C0D0E0F -iv 0102030405060708 -d>
|
||||
openssl idea -d <filename
|
||||
-K 000102030405060708090A0B0C0D0E0F -iv 0102030405060708
|
||||
|
||||
General encryption, decryption function example using FILE I/O and RC2 with an
|
||||
80 bit key:
|
||||
General encryption and decryption function example using FILE I/O and AES128
|
||||
with a 128-bit key:
|
||||
|
||||
int do_crypt(FILE *in, FILE *out, int do_encrypt)
|
||||
{
|
||||
/* Allow enough space in output buffer for additional block */
|
||||
inbuf[1024], outbuf[1024 + EVP_MAX_BLOCK_LENGTH];
|
||||
unsigned char inbuf[1024], outbuf[1024 + EVP_MAX_BLOCK_LENGTH];
|
||||
int inlen, outlen;
|
||||
EVP_CIPHER_CTX ctx;
|
||||
/* Bogus key and IV: we'd normally set these from
|
||||
* another source.
|
||||
*/
|
||||
unsigned char key[] = "0123456789";
|
||||
unsigned char iv[] = "12345678";
|
||||
/* Don't set key or IV because we will modify the parameters */
|
||||
unsigned char key[] = "0123456789abcdeF";
|
||||
unsigned char iv[] = "1234567887654321";
|
||||
|
||||
/* Don't set key or IV right away; we want to check lengths */
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
EVP_CipherInit_ex(&ctx, EVP_rc2(), NULL, NULL, NULL, do_encrypt);
|
||||
EVP_CIPHER_CTX_set_key_length(&ctx, 10);
|
||||
/* We finished modifying parameters so now we can set key and IV */
|
||||
EVP_CipherInit_ex(&ctx, EVP_aes_128_cbc(), NULL, NULL, NULL,
|
||||
do_encrypt);
|
||||
OPENSSL_assert(EVP_CIPHER_CTX_key_length(&ctx) == 16);
|
||||
OPENSSL_assert(EVP_CIPHER_CTX_iv_length(&ctx) == 16);
|
||||
|
||||
/* Now we can set key and IV */
|
||||
EVP_CipherInit_ex(&ctx, NULL, NULL, key, iv, do_encrypt);
|
||||
|
||||
for(;;)
|
||||
@@ -508,4 +495,7 @@ EVP_DecryptInit_ex(), EVP_DecryptFinal_ex(), EVP_CipherInit_ex(),
|
||||
EVP_CipherFinal_ex() and EVP_CIPHER_CTX_set_padding() appeared in
|
||||
OpenSSL 0.9.7.
|
||||
|
||||
IDEA appeared in OpenSSL 0.9.7 but was often disabled due to
|
||||
patent concerns; the last patents expired in 2012.
|
||||
|
||||
=cut
|
||||
|
||||
@@ -37,7 +37,7 @@ EVP_PKEY_get1_RSA(), EVP_PKEY_get1_DSA(), EVP_PKEY_get1_DH() and
|
||||
EVP_PKEY_get1_EC_KEY() return the referenced key in B<pkey> or
|
||||
B<NULL> if the key is not of the correct type.
|
||||
|
||||
EVP_PKEY_assign_RSA() EVP_PKEY_assign_DSA(), EVP_PKEY_assign_DH()
|
||||
EVP_PKEY_assign_RSA(), EVP_PKEY_assign_DSA(), EVP_PKEY_assign_DH()
|
||||
and EVP_PKEY_assign_EC_KEY() also set the referenced key to B<key>
|
||||
however these use the supplied B<key> internally and so B<key>
|
||||
will be freed when the parent B<pkey> is freed.
|
||||
@@ -54,8 +54,8 @@ In accordance with the OpenSSL naming convention the key obtained
|
||||
from or assigned to the B<pkey> using the B<1> functions must be
|
||||
freed as well as B<pkey>.
|
||||
|
||||
EVP_PKEY_assign_RSA() EVP_PKEY_assign_DSA(), EVP_PKEY_assign_DH()
|
||||
EVP_PKEY_assign_EC_KEY() are implemented as macros.
|
||||
EVP_PKEY_assign_RSA(), EVP_PKEY_assign_DSA(), EVP_PKEY_assign_DH()
|
||||
and EVP_PKEY_assign_EC_KEY() are implemented as macros.
|
||||
|
||||
=head1 RETURN VALUES
|
||||
|
||||
@@ -66,7 +66,7 @@ EVP_PKEY_get1_RSA(), EVP_PKEY_get1_DSA(), EVP_PKEY_get1_DH() and
|
||||
EVP_PKEY_get1_EC_KEY() return the referenced key or B<NULL> if
|
||||
an error occurred.
|
||||
|
||||
EVP_PKEY_assign_RSA() EVP_PKEY_assign_DSA(), EVP_PKEY_assign_DH()
|
||||
EVP_PKEY_assign_RSA(), EVP_PKEY_assign_DSA(), EVP_PKEY_assign_DH()
|
||||
and EVP_PKEY_assign_EC_KEY() return 1 for success and 0 for failure.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
@@ -28,9 +28,14 @@ B<sig> and the amount of data written to B<siglen>.
|
||||
|
||||
=head1 NOTES
|
||||
|
||||
EVP_PKEY_sign() does not hash the data to be signed, and therefore is
|
||||
normally used to sign digests. For signing arbitrary messages, see the
|
||||
L<EVP_DigestSignInit(3)|EVP_DigestSignInit(3)> and
|
||||
L<EVP_SignInit(3)|EVP_SignInit(3)> signing interfaces instead.
|
||||
|
||||
After the call to EVP_PKEY_sign_init() algorithm specific control
|
||||
operations can be performed to set any appropriate parameters for the
|
||||
operation.
|
||||
operation (see L<EVP_PKEY_CTX_ctrl(3)|EVP_PKEY_CTX_ctrl(3)>).
|
||||
|
||||
The function EVP_PKEY_sign() can be called more than once on the same
|
||||
context if several operations are performed using the same parameters.
|
||||
@@ -49,13 +54,17 @@ Sign data using RSA with PKCS#1 padding and SHA256 digest:
|
||||
#include <openssl/rsa.h>
|
||||
|
||||
EVP_PKEY_CTX *ctx;
|
||||
/* md is a SHA-256 digest in this example. */
|
||||
unsigned char *md, *sig;
|
||||
size_t mdlen, siglen;
|
||||
size_t mdlen = 32, siglen;
|
||||
EVP_PKEY *signing_key;
|
||||
/* NB: assumes signing_key, md and mdlen are already set up
|
||||
* and that signing_key is an RSA private key
|
||||
|
||||
/*
|
||||
* NB: assumes signing_key and md are set up before the next
|
||||
* step. signing_key must be an RSA private key and md must
|
||||
* point to the SHA-256 digest to be signed.
|
||||
*/
|
||||
ctx = EVP_PKEY_CTX_new(signing_key);
|
||||
ctx = EVP_PKEY_CTX_new(signing_key, NULL /* no engine */);
|
||||
if (!ctx)
|
||||
/* Error occurred */
|
||||
if (EVP_PKEY_sign_init(ctx) <= 0)
|
||||
@@ -83,6 +92,7 @@ Sign data using RSA with PKCS#1 padding and SHA256 digest:
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
|
||||
L<EVP_PKEY_CTX_ctrl(3)|EVP_PKEY_CTX_ctrl(3)>,
|
||||
L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
|
||||
L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
|
||||
L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
|
||||
|
||||
@@ -71,6 +71,16 @@ SSL_CTX->freelist_max_len, which defaults to 32. Using this flag can
|
||||
save around 34k per idle SSL connection.
|
||||
This flag has no effect on SSL v2 connections, or on DTLS connections.
|
||||
|
||||
=item SSL_MODE_SEND_FALLBACK_SCSV
|
||||
|
||||
Send TLS_FALLBACK_SCSV in the ClientHello.
|
||||
To be set only by applications that reconnect with a downgraded protocol
|
||||
version; see draft-ietf-tls-downgrade-scsv-00 for details.
|
||||
|
||||
DO NOT ENABLE THIS if your application attempts a normal handshake.
|
||||
Only use this in explicit fallback retries, following the guidance
|
||||
in draft-ietf-tls-downgrade-scsv-00.
|
||||
|
||||
=back
|
||||
|
||||
=head1 RETURN VALUES
|
||||
|
||||
@@ -152,15 +152,7 @@ temporary/ephemeral DH parameters are used.
|
||||
|
||||
=item SSL_OP_EPHEMERAL_RSA
|
||||
|
||||
Always use ephemeral (temporary) RSA key when doing RSA operations
|
||||
(see L<SSL_CTX_set_tmp_rsa_callback(3)|SSL_CTX_set_tmp_rsa_callback(3)>).
|
||||
According to the specifications this is only done, when a RSA key
|
||||
can only be used for signature operations (namely under export ciphers
|
||||
with restricted RSA keylength). By setting this option, ephemeral
|
||||
RSA keys are always used. This option breaks compatibility with the
|
||||
SSL/TLS specifications and may lead to interoperability problems with
|
||||
clients and should therefore never be used. Ciphers with EDH (ephemeral
|
||||
Diffie-Hellman) key exchange should be used instead.
|
||||
This option is no longer implemented and is treated as no op.
|
||||
|
||||
=item SSL_OP_CIPHER_SERVER_PREFERENCE
|
||||
|
||||
|
||||
@@ -48,12 +48,13 @@ even if he gets hold of the normal (certified) key, as this key was
|
||||
only used for signing.
|
||||
|
||||
In order to perform a DH key exchange the server must use a DH group
|
||||
(DH parameters) and generate a DH key. The server will always generate a new
|
||||
DH key during the negotiation, when the DH parameters are supplied via
|
||||
callback and/or when the SSL_OP_SINGLE_DH_USE option of
|
||||
L<SSL_CTX_set_options(3)|SSL_CTX_set_options(3)> is set. It will
|
||||
immediately create a DH key, when DH parameters are supplied via
|
||||
SSL_CTX_set_tmp_dh() and SSL_OP_SINGLE_DH_USE is not set. In this case,
|
||||
(DH parameters) and generate a DH key.
|
||||
The server will always generate a new DH key during the negotiation
|
||||
if either the DH parameters are supplied via callback or the
|
||||
SSL_OP_SINGLE_DH_USE option of SSL_CTX_set_options(3) is set (or both).
|
||||
It will immediately create a DH key if DH parameters are supplied via
|
||||
SSL_CTX_set_tmp_dh() and SSL_OP_SINGLE_DH_USE is not set.
|
||||
In this case,
|
||||
it may happen that a key is generated on initialization without later
|
||||
being needed, while on the other hand the computer time during the
|
||||
negotiation is being saved.
|
||||
@@ -139,7 +140,7 @@ partly left out.)
|
||||
dh_tmp = dh_512;
|
||||
break;
|
||||
case 1024:
|
||||
if (!dh_1024)
|
||||
if (!dh_1024)
|
||||
dh_1024 = get_dh1024();
|
||||
dh_tmp = dh_1024;
|
||||
break;
|
||||
|
||||
@@ -74,21 +74,14 @@ exchange and use EDH (Ephemeral Diffie-Hellman) key exchange instead
|
||||
in order to achieve forward secrecy (see
|
||||
L<SSL_CTX_set_tmp_dh_callback(3)|SSL_CTX_set_tmp_dh_callback(3)>).
|
||||
|
||||
On OpenSSL servers ephemeral RSA key exchange is therefore disabled by default
|
||||
and must be explicitly enabled using the SSL_OP_EPHEMERAL_RSA option of
|
||||
L<SSL_CTX_set_options(3)|SSL_CTX_set_options(3)>, violating the TLS/SSL
|
||||
standard. When ephemeral RSA key exchange is required for export ciphers,
|
||||
it will automatically be used without this option!
|
||||
|
||||
An application may either directly specify the key or can supply the key via
|
||||
a callback function. The callback approach has the advantage, that the
|
||||
callback may generate the key only in case it is actually needed. As the
|
||||
generation of a RSA key is however costly, it will lead to a significant
|
||||
delay in the handshake procedure. Another advantage of the callback function
|
||||
is that it can supply keys of different size (e.g. for SSL_OP_EPHEMERAL_RSA
|
||||
usage) while the explicit setting of the key is only useful for key size of
|
||||
512 bits to satisfy the export restricted ciphers and does give away key length
|
||||
if a longer key would be allowed.
|
||||
An application may either directly specify the key or can supply the key via a
|
||||
callback function. The callback approach has the advantage, that the callback
|
||||
may generate the key only in case it is actually needed. As the generation of a
|
||||
RSA key is however costly, it will lead to a significant delay in the handshake
|
||||
procedure. Another advantage of the callback function is that it can supply
|
||||
keys of different size while the explicit setting of the key is only useful for
|
||||
key size of 512 bits to satisfy the export restricted ciphers and does give
|
||||
away key length if a longer key would be allowed.
|
||||
|
||||
The B<tmp_rsa_callback> is called with the B<keylength> needed and
|
||||
the B<is_export> information. The B<is_export> flag is set, when the
|
||||
|
||||
21
e_os.h
21
e_os.h
@@ -291,7 +291,7 @@ extern "C" {
|
||||
# ifdef _WIN64
|
||||
# define strlen(s) _strlen31(s)
|
||||
/* cut strings to 2GB */
|
||||
static unsigned int _strlen31(const char *str)
|
||||
static __inline unsigned int _strlen31(const char *str)
|
||||
{
|
||||
unsigned int len=0;
|
||||
while (*str && len<0x80000000U) str++, len++;
|
||||
@@ -376,7 +376,7 @@ static unsigned int _strlen31(const char *str)
|
||||
# define check_winnt() (1)
|
||||
#else
|
||||
# define check_winnt() (GetVersion() < 0x80000000)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#else /* The non-microsoft world */
|
||||
|
||||
@@ -744,10 +744,25 @@ struct servent *getservbyname(const char *name, const char *proto);
|
||||
#include <OS.h>
|
||||
#endif
|
||||
|
||||
#if !defined(inline) && !defined(__cplusplus)
|
||||
# if defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L
|
||||
/* do nothing, inline works */
|
||||
# elif defined(__GNUC__) && __GNUC__>=2
|
||||
# define inline __inline__
|
||||
# elif defined(_MSC_VER)
|
||||
/*
|
||||
* Visual Studio: inline is available in C++ only, however
|
||||
* __inline is available for C, see
|
||||
* http://msdn.microsoft.com/en-us/library/z8y1yy88.aspx
|
||||
*/
|
||||
# define inline __inline
|
||||
# else
|
||||
# define inline
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -155,7 +155,7 @@ $ ENGINE_ = "engine_vector.mar"
|
||||
$ TV_OBJ_NAME = OBJ_DIR + F$PARSE(ENGINE_,,,"NAME","SYNTAX_ONLY") + ".OBJ"
|
||||
$ TV_OBJ = ",''TV_OBJ_NAME'"
|
||||
$ ENDIF
|
||||
$ ENGINE_4758CCA = "e_4758cca"
|
||||
$ ENGINE_4758cca = "e_4758cca"
|
||||
$ ENGINE_aep = "e_aep"
|
||||
$ ENGINE_atalla = "e_atalla"
|
||||
$ ENGINE_cswift = "e_cswift"
|
||||
@@ -756,9 +756,12 @@ $ CCDEFS = "TCPIP_TYPE_''OPT_TCPIP_LIB',DSO_VMS"
|
||||
$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = CCDEFS + "," + USER_CCDEFS
|
||||
$ CCEXTRAFLAGS = ""
|
||||
$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS
|
||||
$ CCDISABLEWARNINGS = "" !!! "LONGLONGTYPE,LONGLONGSUFX"
|
||||
$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. "" THEN -
|
||||
CCDISABLEWARNINGS = CCDISABLEWARNINGS + "," + USER_CCDISABLEWARNINGS
|
||||
$ CCDISABLEWARNINGS = "" !!! "MAYLOSEDATA3" !!! "LONGLONGTYPE,LONGLONGSUFX"
|
||||
$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. ""
|
||||
$ THEN
|
||||
$ IF CCDISABLEWARNINGS .NES. "" THEN CCDISABLEWARNINGS = CCDISABLEWARNINGS + ","
|
||||
$ CCDISABLEWARNINGS = CCDISABLEWARNINGS + USER_CCDISABLEWARNINGS
|
||||
$ ENDIF
|
||||
$!
|
||||
$! Check To See If We Have A ZLIB Option.
|
||||
$!
|
||||
@@ -922,6 +925,18 @@ $! Finish up the definition of CC.
|
||||
$!
|
||||
$ IF COMPILER .EQS. "DECC"
|
||||
$ THEN
|
||||
$! Not all compiler versions support MAYLOSEDATA3.
|
||||
$ OPT_TEST = "MAYLOSEDATA3"
|
||||
$ DEFINE /USER_MODE SYS$ERROR NL:
|
||||
$ DEFINE /USER_MODE SYS$OUTPUT NL:
|
||||
$ 'CC' /NOCROSS_REFERENCE /NOLIST /NOOBJECT -
|
||||
/WARNINGS = DISABLE = ('OPT_TEST', EMPTYFILE) NL:
|
||||
$ IF ($SEVERITY)
|
||||
$ THEN
|
||||
$ IF CCDISABLEWARNINGS .NES. "" THEN -
|
||||
CCDISABLEWARNINGS = CCDISABLEWARNINGS+ ","
|
||||
$ CCDISABLEWARNINGS = CCDISABLEWARNINGS+ OPT_TEST
|
||||
$ ENDIF
|
||||
$ IF CCDISABLEWARNINGS .NES. ""
|
||||
$ THEN
|
||||
$ CCDISABLEWARNINGS = " /WARNING=(DISABLE=(" + CCDISABLEWARNINGS + "))"
|
||||
|
||||
16
makevms.com
16
makevms.com
@@ -281,6 +281,7 @@ $ CONFIG_LOGICALS := AES,-
|
||||
MD4,-
|
||||
MD5,-
|
||||
MDC2,-
|
||||
NEXTPROTONEG,-
|
||||
OCSP,-
|
||||
PSK,-
|
||||
RC2,-
|
||||
@@ -335,7 +336,11 @@ $ CONFIG_DISABLE_RULES := RIJNDAEL/AES;-
|
||||
DSA/GOST;-
|
||||
DH/GOST;-
|
||||
/STATIC_ENGINE;-
|
||||
/KRB5
|
||||
/KRB5;-
|
||||
/GMP;-
|
||||
/MD2;-
|
||||
/RC5;-
|
||||
/RFC3779
|
||||
$ CONFIG_ENABLE_RULES := ZLIB_DYNAMIC/ZLIB;-
|
||||
/THREADS
|
||||
$
|
||||
@@ -698,8 +703,8 @@ $!
|
||||
$ SDIRS := , -
|
||||
'ARCHD', -
|
||||
OBJECTS, -
|
||||
MD2, MD4, MD5, SHA, MDC2, HMAC, RIPEMD, WHRLPOOL, -
|
||||
DES, AES, RC2, RC4, RC5, IDEA, BF, CAST, CAMELLIA, SEED, MODES, -
|
||||
MD4, MD5, SHA, MDC2, HMAC, RIPEMD, WHRLPOOL, -
|
||||
DES, AES, RC2, RC4, IDEA, BF, CAST, CAMELLIA, SEED, MODES, -
|
||||
BN, EC, RSA, DSA, ECDSA, DH, ECDH, DSO, ENGINE, -
|
||||
BUFFER, BIO, STACK, LHASH, RAND, ERR, -
|
||||
EVP, ASN1, PEM, X509, X509V3, CONF, TXT_DB, PKCS7, PKCS12, -
|
||||
@@ -809,8 +814,9 @@ $ @CRYPTO-LIB LIBRARY 'DEBUGGER' "''COMPILER'" "''TCPIP_TYPE'" -
|
||||
$!
|
||||
$! Build The [.xxx.EXE.CRYPTO]*.EXE Test Applications.
|
||||
$!
|
||||
$ @CRYPTO-LIB APPS 'DEBUGGER' "''COMPILER'" "''TCPIP_TYPE'" -
|
||||
"''ISSEVEN'" "''BUILDPART'" "''POINTER_SIZE'" "''ZLIB'"
|
||||
$!!! DISABLED, as these test programs lack any support
|
||||
$!!!$ @CRYPTO-LIB APPS 'DEBUGGER' "''COMPILER'" "''TCPIP_TYPE'" -
|
||||
$!!! "''ISSEVEN'" "''BUILDPART'" "''POINTER_SIZE'" "''ZLIB'"
|
||||
$!
|
||||
$! Go Back To The Main Directory.
|
||||
$!
|
||||
|
||||
@@ -6,7 +6,7 @@ Release: 1
|
||||
|
||||
Summary: Secure Sockets Layer and cryptography libraries and tools
|
||||
Name: openssl
|
||||
Version: 1.0.0n
|
||||
Version: 1.0.0p
|
||||
Source0: ftp://ftp.openssl.org/source/%{name}-%{version}.tar.gz
|
||||
License: OpenSSL
|
||||
Group: System Environment/Libraries
|
||||
|
||||
84
ssl/Makefile
84
ssl/Makefile
@@ -515,26 +515,26 @@ s3_both.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
|
||||
s3_both.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
|
||||
s3_both.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s3_both.c
|
||||
s3_both.o: ssl_locl.h
|
||||
s3_cbc.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
|
||||
s3_cbc.o: ../include/openssl/buffer.h ../include/openssl/comp.h
|
||||
s3_cbc.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
|
||||
s3_cbc.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
|
||||
s3_cbc.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
|
||||
s3_cbc.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
|
||||
s3_cbc.o: ../include/openssl/evp.h ../include/openssl/hmac.h
|
||||
s3_cbc.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
|
||||
s3_cbc.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
|
||||
s3_cbc.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
|
||||
s3_cbc.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
|
||||
s3_cbc.o: ../include/openssl/pem.h ../include/openssl/pem2.h
|
||||
s3_cbc.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
|
||||
s3_cbc.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
|
||||
s3_cbc.o: ../include/openssl/sha.h ../include/openssl/ssl.h
|
||||
s3_cbc.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
|
||||
s3_cbc.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
|
||||
s3_cbc.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
|
||||
s3_cbc.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s3_cbc.c
|
||||
s3_cbc.o: ssl_locl.h
|
||||
s3_cbc.o: ../crypto/constant_time_locl.h ../e_os.h ../include/openssl/asn1.h
|
||||
s3_cbc.o: ../include/openssl/bio.h ../include/openssl/buffer.h
|
||||
s3_cbc.o: ../include/openssl/comp.h ../include/openssl/crypto.h
|
||||
s3_cbc.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
|
||||
s3_cbc.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
|
||||
s3_cbc.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
|
||||
s3_cbc.o: ../include/openssl/err.h ../include/openssl/evp.h
|
||||
s3_cbc.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
|
||||
s3_cbc.o: ../include/openssl/lhash.h ../include/openssl/md5.h
|
||||
s3_cbc.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
|
||||
s3_cbc.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
|
||||
s3_cbc.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
|
||||
s3_cbc.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
|
||||
s3_cbc.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
|
||||
s3_cbc.o: ../include/openssl/safestack.h ../include/openssl/sha.h
|
||||
s3_cbc.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
|
||||
s3_cbc.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
|
||||
s3_cbc.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
|
||||
s3_cbc.o: ../include/openssl/tls1.h ../include/openssl/x509.h
|
||||
s3_cbc.o: ../include/openssl/x509_vfy.h s3_cbc.c ssl_locl.h
|
||||
s3_clnt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
|
||||
s3_clnt.o: ../include/openssl/bn.h ../include/openssl/buffer.h
|
||||
s3_clnt.o: ../include/openssl/comp.h ../include/openssl/crypto.h
|
||||
@@ -636,28 +636,28 @@ s3_pkt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
|
||||
s3_pkt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
|
||||
s3_pkt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
|
||||
s3_pkt.o: ../include/openssl/x509_vfy.h s3_pkt.c ssl_locl.h
|
||||
s3_srvr.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
|
||||
s3_srvr.o: ../include/openssl/bn.h ../include/openssl/buffer.h
|
||||
s3_srvr.o: ../include/openssl/comp.h ../include/openssl/crypto.h
|
||||
s3_srvr.o: ../include/openssl/dh.h ../include/openssl/dsa.h
|
||||
s3_srvr.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
|
||||
s3_srvr.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
|
||||
s3_srvr.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
|
||||
s3_srvr.o: ../include/openssl/evp.h ../include/openssl/hmac.h
|
||||
s3_srvr.o: ../include/openssl/krb5_asn.h ../include/openssl/kssl.h
|
||||
s3_srvr.o: ../include/openssl/lhash.h ../include/openssl/md5.h
|
||||
s3_srvr.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
|
||||
s3_srvr.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
|
||||
s3_srvr.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
|
||||
s3_srvr.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
|
||||
s3_srvr.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
|
||||
s3_srvr.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
|
||||
s3_srvr.o: ../include/openssl/sha.h ../include/openssl/ssl.h
|
||||
s3_srvr.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
|
||||
s3_srvr.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
|
||||
s3_srvr.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
|
||||
s3_srvr.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h kssl_lcl.h
|
||||
s3_srvr.o: s3_srvr.c ssl_locl.h
|
||||
s3_srvr.o: ../crypto/constant_time_locl.h ../e_os.h ../include/openssl/asn1.h
|
||||
s3_srvr.o: ../include/openssl/bio.h ../include/openssl/bn.h
|
||||
s3_srvr.o: ../include/openssl/buffer.h ../include/openssl/comp.h
|
||||
s3_srvr.o: ../include/openssl/crypto.h ../include/openssl/dh.h
|
||||
s3_srvr.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
|
||||
s3_srvr.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
|
||||
s3_srvr.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
|
||||
s3_srvr.o: ../include/openssl/err.h ../include/openssl/evp.h
|
||||
s3_srvr.o: ../include/openssl/hmac.h ../include/openssl/krb5_asn.h
|
||||
s3_srvr.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
|
||||
s3_srvr.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
|
||||
s3_srvr.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
|
||||
s3_srvr.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
|
||||
s3_srvr.o: ../include/openssl/pem.h ../include/openssl/pem2.h
|
||||
s3_srvr.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
|
||||
s3_srvr.o: ../include/openssl/rand.h ../include/openssl/rsa.h
|
||||
s3_srvr.o: ../include/openssl/safestack.h ../include/openssl/sha.h
|
||||
s3_srvr.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
|
||||
s3_srvr.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
|
||||
s3_srvr.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
|
||||
s3_srvr.o: ../include/openssl/tls1.h ../include/openssl/x509.h
|
||||
s3_srvr.o: ../include/openssl/x509_vfy.h kssl_lcl.h s3_srvr.c ssl_locl.h
|
||||
ssl_algs.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
|
||||
ssl_algs.o: ../include/openssl/buffer.h ../include/openssl/comp.h
|
||||
ssl_algs.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
|
||||
|
||||
168
ssl/d1_both.c
168
ssl/d1_both.c
@@ -156,9 +156,8 @@ static unsigned char bitmask_start_values[] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe
|
||||
static unsigned char bitmask_end_values[] = {0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f};
|
||||
|
||||
/* XDTLS: figure out the right values */
|
||||
static unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28};
|
||||
static const unsigned int g_probable_mtu[] = {1500, 512, 256};
|
||||
|
||||
static unsigned int dtls1_guess_mtu(unsigned int curr_mtu);
|
||||
static void dtls1_fix_message_header(SSL *s, unsigned long frag_off,
|
||||
unsigned long frag_len);
|
||||
static unsigned char *dtls1_write_message_header(SSL *s,
|
||||
@@ -211,8 +210,7 @@ dtls1_hm_fragment_new(unsigned long frag_len, int reassembly)
|
||||
return frag;
|
||||
}
|
||||
|
||||
static void
|
||||
dtls1_hm_fragment_free(hm_fragment *frag)
|
||||
void dtls1_hm_fragment_free(hm_fragment *frag)
|
||||
{
|
||||
|
||||
if (frag->msg_header.is_ccs)
|
||||
@@ -225,53 +223,50 @@ dtls1_hm_fragment_free(hm_fragment *frag)
|
||||
OPENSSL_free(frag);
|
||||
}
|
||||
|
||||
static int dtls1_query_mtu(SSL *s)
|
||||
{
|
||||
if(s->d1->link_mtu)
|
||||
{
|
||||
s->d1->mtu = s->d1->link_mtu-BIO_dgram_get_mtu_overhead(SSL_get_wbio(s));
|
||||
s->d1->link_mtu = 0;
|
||||
}
|
||||
|
||||
/* AHA! Figure out the MTU, and stick to the right size */
|
||||
if (s->d1->mtu < dtls1_min_mtu(s))
|
||||
{
|
||||
if(!(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
|
||||
{
|
||||
s->d1->mtu =
|
||||
BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
|
||||
|
||||
/* I've seen the kernel return bogus numbers when it doesn't know
|
||||
* (initial write), so just make sure we have a reasonable number */
|
||||
if (s->d1->mtu < dtls1_min_mtu(s))
|
||||
{
|
||||
/* Set to min mtu */
|
||||
s->d1->mtu = dtls1_min_mtu(s);
|
||||
BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SET_MTU,
|
||||
s->d1->mtu, NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or SSL3_RT_CHANGE_CIPHER_SPEC) */
|
||||
int dtls1_do_write(SSL *s, int type)
|
||||
{
|
||||
int ret;
|
||||
int curr_mtu;
|
||||
unsigned int len, frag_off, mac_size, blocksize;
|
||||
unsigned int curr_mtu;
|
||||
int retry = 1;
|
||||
unsigned int len, frag_off, mac_size, blocksize, used_len;
|
||||
|
||||
/* AHA! Figure out the MTU, and stick to the right size */
|
||||
if (s->d1->mtu < dtls1_min_mtu() && !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
|
||||
{
|
||||
s->d1->mtu =
|
||||
BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
|
||||
if(!dtls1_query_mtu(s))
|
||||
return -1;
|
||||
|
||||
/* I've seen the kernel return bogus numbers when it doesn't know
|
||||
* (initial write), so just make sure we have a reasonable number */
|
||||
if (s->d1->mtu < dtls1_min_mtu())
|
||||
{
|
||||
s->d1->mtu = 0;
|
||||
s->d1->mtu = dtls1_guess_mtu(s->d1->mtu);
|
||||
BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SET_MTU,
|
||||
s->d1->mtu, NULL);
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
mtu = s->d1->mtu;
|
||||
|
||||
fprintf(stderr, "using MTU = %d\n", mtu);
|
||||
|
||||
mtu -= (DTLS1_HM_HEADER_LENGTH + DTLS1_RT_HEADER_LENGTH);
|
||||
|
||||
curr_mtu = mtu - BIO_wpending(SSL_get_wbio(s));
|
||||
|
||||
if ( curr_mtu > 0)
|
||||
mtu = curr_mtu;
|
||||
else if ( ( ret = BIO_flush(SSL_get_wbio(s))) <= 0)
|
||||
return ret;
|
||||
|
||||
if ( BIO_wpending(SSL_get_wbio(s)) + s->init_num >= mtu)
|
||||
{
|
||||
ret = BIO_flush(SSL_get_wbio(s));
|
||||
if ( ret <= 0)
|
||||
return ret;
|
||||
mtu = s->d1->mtu - (DTLS1_HM_HEADER_LENGTH + DTLS1_RT_HEADER_LENGTH);
|
||||
}
|
||||
#endif
|
||||
|
||||
OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu()); /* should have something reasonable now */
|
||||
OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu(s)); /* should have something reasonable now */
|
||||
|
||||
if ( s->init_off == 0 && type == SSL3_RT_HANDSHAKE)
|
||||
OPENSSL_assert(s->init_num ==
|
||||
@@ -289,10 +284,15 @@ int dtls1_do_write(SSL *s, int type)
|
||||
blocksize = 0;
|
||||
|
||||
frag_off = 0;
|
||||
while( s->init_num)
|
||||
/* s->init_num shouldn't ever be < 0...but just in case */
|
||||
while(s->init_num > 0)
|
||||
{
|
||||
curr_mtu = s->d1->mtu - BIO_wpending(SSL_get_wbio(s)) -
|
||||
DTLS1_RT_HEADER_LENGTH - mac_size - blocksize;
|
||||
used_len = BIO_wpending(SSL_get_wbio(s)) + DTLS1_RT_HEADER_LENGTH
|
||||
+ mac_size + blocksize;
|
||||
if(s->d1->mtu > used_len)
|
||||
curr_mtu = s->d1->mtu - used_len;
|
||||
else
|
||||
curr_mtu = 0;
|
||||
|
||||
if ( curr_mtu <= DTLS1_HM_HEADER_LENGTH)
|
||||
{
|
||||
@@ -300,15 +300,27 @@ int dtls1_do_write(SSL *s, int type)
|
||||
ret = BIO_flush(SSL_get_wbio(s));
|
||||
if ( ret <= 0)
|
||||
return ret;
|
||||
curr_mtu = s->d1->mtu - DTLS1_RT_HEADER_LENGTH -
|
||||
mac_size - blocksize;
|
||||
used_len = DTLS1_RT_HEADER_LENGTH + mac_size + blocksize;
|
||||
if(s->d1->mtu > used_len + DTLS1_HM_HEADER_LENGTH)
|
||||
{
|
||||
curr_mtu = s->d1->mtu - used_len;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Shouldn't happen */
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( s->init_num > curr_mtu)
|
||||
/* We just checked that s->init_num > 0 so this cast should be safe */
|
||||
if (((unsigned int)s->init_num) > curr_mtu)
|
||||
len = curr_mtu;
|
||||
else
|
||||
len = s->init_num;
|
||||
|
||||
/* Shouldn't ever happen */
|
||||
if(len > INT_MAX)
|
||||
len = INT_MAX;
|
||||
|
||||
/* XDTLS: this function is too long. split out the CCS part */
|
||||
if ( type == SSL3_RT_HANDSHAKE)
|
||||
@@ -319,18 +331,29 @@ int dtls1_do_write(SSL *s, int type)
|
||||
s->init_off -= DTLS1_HM_HEADER_LENGTH;
|
||||
s->init_num += DTLS1_HM_HEADER_LENGTH;
|
||||
|
||||
if ( s->init_num > curr_mtu)
|
||||
/* We just checked that s->init_num > 0 so this cast should be safe */
|
||||
if (((unsigned int)s->init_num) > curr_mtu)
|
||||
len = curr_mtu;
|
||||
else
|
||||
len = s->init_num;
|
||||
}
|
||||
|
||||
/* Shouldn't ever happen */
|
||||
if(len > INT_MAX)
|
||||
len = INT_MAX;
|
||||
|
||||
if ( len < DTLS1_HM_HEADER_LENGTH )
|
||||
{
|
||||
/*
|
||||
* len is so small that we really can't do anything sensible
|
||||
* so fail
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
dtls1_fix_message_header(s, frag_off,
|
||||
len - DTLS1_HM_HEADER_LENGTH);
|
||||
|
||||
dtls1_write_message_header(s, (unsigned char *)&s->init_buf->data[s->init_off]);
|
||||
|
||||
OPENSSL_assert(len >= DTLS1_HM_HEADER_LENGTH);
|
||||
}
|
||||
|
||||
ret=dtls1_write_bytes(s,type,&s->init_buf->data[s->init_off],
|
||||
@@ -343,12 +366,23 @@ int dtls1_do_write(SSL *s, int type)
|
||||
* is fine and wait for an alert to handle the
|
||||
* retransmit
|
||||
*/
|
||||
if ( BIO_ctrl(SSL_get_wbio(s),
|
||||
if ( retry && BIO_ctrl(SSL_get_wbio(s),
|
||||
BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL) > 0 )
|
||||
s->d1->mtu = BIO_ctrl(SSL_get_wbio(s),
|
||||
BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
|
||||
{
|
||||
if(!(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
|
||||
{
|
||||
if(!dtls1_query_mtu(s))
|
||||
return -1;
|
||||
/* Have one more go */
|
||||
retry = 0;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1408,28 +1442,20 @@ dtls1_write_message_header(SSL *s, unsigned char *p)
|
||||
return p;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
dtls1_min_mtu(void)
|
||||
unsigned int
|
||||
dtls1_link_min_mtu(void)
|
||||
{
|
||||
return (g_probable_mtu[(sizeof(g_probable_mtu) /
|
||||
sizeof(g_probable_mtu[0])) - 1]);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
dtls1_guess_mtu(unsigned int curr_mtu)
|
||||
unsigned int
|
||||
dtls1_min_mtu(SSL *s)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if ( curr_mtu == 0 )
|
||||
return g_probable_mtu[0] ;
|
||||
|
||||
for ( i = 0; i < sizeof(g_probable_mtu)/sizeof(g_probable_mtu[0]); i++)
|
||||
if ( curr_mtu > g_probable_mtu[i])
|
||||
return g_probable_mtu[i];
|
||||
|
||||
return curr_mtu;
|
||||
return dtls1_link_min_mtu()-BIO_dgram_get_mtu_overhead(SSL_get_wbio(s));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr)
|
||||
{
|
||||
|
||||
@@ -1548,6 +1548,12 @@ int dtls1_send_client_certificate(SSL *s)
|
||||
s->state=SSL3_ST_CW_CERT_D;
|
||||
l=dtls1_output_cert_chain(s,
|
||||
(s->s3->tmp.cert_req == 2)?NULL:s->cert->key->x509);
|
||||
if (!l)
|
||||
{
|
||||
SSLerr(SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE, ERR_R_INTERNAL_ERROR);
|
||||
ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
s->init_num=(int)l;
|
||||
s->init_off=0;
|
||||
|
||||
|
||||
@@ -241,7 +241,8 @@ int dtls1_enc(SSL *s, int send)
|
||||
return 0;
|
||||
}
|
||||
|
||||
EVP_Cipher(ds,rec->data,rec->input,l);
|
||||
if(EVP_Cipher(ds,rec->data,rec->input,l) < 1)
|
||||
return -1;
|
||||
|
||||
#ifdef KSSL_DEBUG
|
||||
{
|
||||
|
||||
48
ssl/d1_lib.c
48
ssl/d1_lib.c
@@ -112,6 +112,9 @@ int dtls1_new(SSL *s)
|
||||
d1->cookie_len = sizeof(s->d1->cookie);
|
||||
}
|
||||
|
||||
d1->link_mtu = 0;
|
||||
d1->mtu = 0;
|
||||
|
||||
if( ! d1->unprocessed_rcds.q || ! d1->processed_rcds.q
|
||||
|| ! d1->buffered_messages || ! d1->sent_messages || ! d1->buffered_app_data.q)
|
||||
{
|
||||
@@ -160,16 +163,14 @@ static void dtls1_clear_queues(SSL *s)
|
||||
while( (item = pqueue_pop(s->d1->buffered_messages)) != NULL)
|
||||
{
|
||||
frag = (hm_fragment *)item->data;
|
||||
OPENSSL_free(frag->fragment);
|
||||
OPENSSL_free(frag);
|
||||
dtls1_hm_fragment_free(frag);
|
||||
pitem_free(item);
|
||||
}
|
||||
|
||||
while ( (item = pqueue_pop(s->d1->sent_messages)) != NULL)
|
||||
{
|
||||
frag = (hm_fragment *)item->data;
|
||||
OPENSSL_free(frag->fragment);
|
||||
OPENSSL_free(frag);
|
||||
dtls1_hm_fragment_free(frag);
|
||||
pitem_free(item);
|
||||
}
|
||||
|
||||
@@ -209,6 +210,7 @@ void dtls1_clear(SSL *s)
|
||||
pqueue sent_messages;
|
||||
pqueue buffered_app_data;
|
||||
unsigned int mtu;
|
||||
unsigned int link_mtu;
|
||||
|
||||
if (s->d1)
|
||||
{
|
||||
@@ -218,6 +220,7 @@ void dtls1_clear(SSL *s)
|
||||
sent_messages = s->d1->sent_messages;
|
||||
buffered_app_data = s->d1->buffered_app_data.q;
|
||||
mtu = s->d1->mtu;
|
||||
link_mtu = s->d1->link_mtu;
|
||||
|
||||
dtls1_clear_queues(s);
|
||||
|
||||
@@ -231,6 +234,7 @@ void dtls1_clear(SSL *s)
|
||||
if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)
|
||||
{
|
||||
s->d1->mtu = mtu;
|
||||
s->d1->link_mtu = link_mtu;
|
||||
}
|
||||
|
||||
s->d1->unprocessed_rcds.q = unprocessed_rcds;
|
||||
@@ -265,7 +269,32 @@ long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg)
|
||||
case DTLS_CTRL_LISTEN:
|
||||
ret = dtls1_listen(s, parg);
|
||||
break;
|
||||
|
||||
case SSL_CTRL_CHECK_PROTO_VERSION:
|
||||
/* For library-internal use; checks that the current protocol
|
||||
* is the highest enabled version (according to s->ctx->method,
|
||||
* as version negotiation may have changed s->method). */
|
||||
#if DTLS_MAX_VERSION != DTLS1_VERSION
|
||||
# error Code needs update for DTLS_method() support beyond DTLS1_VERSION.
|
||||
#endif
|
||||
/* Just one protocol version is supported so far;
|
||||
* fail closed if the version is not as expected. */
|
||||
return s->version == DTLS_MAX_VERSION;
|
||||
case DTLS_CTRL_SET_LINK_MTU:
|
||||
if (larg < (long)dtls1_link_min_mtu())
|
||||
return 0;
|
||||
s->d1->link_mtu = larg;
|
||||
return 1;
|
||||
case DTLS_CTRL_GET_LINK_MIN_MTU:
|
||||
return (long)dtls1_link_min_mtu();
|
||||
case SSL_CTRL_SET_MTU:
|
||||
/*
|
||||
* We may not have a BIO set yet so can't call dtls1_min_mtu()
|
||||
* We'll have to make do with dtls1_link_min_mtu() and max overhead
|
||||
*/
|
||||
if (larg < (long)dtls1_link_min_mtu() - DTLS1_MAX_MTU_OVERHEAD)
|
||||
return 0;
|
||||
s->d1->mtu = larg;
|
||||
return larg;
|
||||
default:
|
||||
ret = ssl3_ctrl(s, cmd, larg, parg);
|
||||
break;
|
||||
@@ -395,12 +424,17 @@ void dtls1_stop_timer(SSL *s)
|
||||
|
||||
int dtls1_check_timeout_num(SSL *s)
|
||||
{
|
||||
unsigned int mtu;
|
||||
|
||||
s->d1->timeout.num_alerts++;
|
||||
|
||||
/* Reduce MTU after 2 unsuccessful retransmissions */
|
||||
if (s->d1->timeout.num_alerts > 2)
|
||||
if (s->d1->timeout.num_alerts > 2
|
||||
&& !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
|
||||
{
|
||||
s->d1->mtu = BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL);
|
||||
mtu = BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL);
|
||||
if(mtu < s->d1->mtu)
|
||||
s->d1->mtu = mtu;
|
||||
}
|
||||
|
||||
if (s->d1->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT)
|
||||
|
||||
37
ssl/d1_pkt.c
37
ssl/d1_pkt.c
@@ -212,7 +212,7 @@ dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority)
|
||||
/* Limit the size of the queue to prevent DOS attacks */
|
||||
if (pqueue_size(queue->q) >= 100)
|
||||
return 0;
|
||||
|
||||
|
||||
rdata = OPENSSL_malloc(sizeof(DTLS1_RECORD_DATA));
|
||||
item = pitem_new(priority, rdata);
|
||||
if (rdata == NULL || item == NULL)
|
||||
@@ -239,18 +239,22 @@ dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority)
|
||||
if (!ssl3_setup_buffers(s))
|
||||
{
|
||||
SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR);
|
||||
if (rdata->rbuf.buf != NULL)
|
||||
OPENSSL_free(rdata->rbuf.buf);
|
||||
OPENSSL_free(rdata);
|
||||
pitem_free(item);
|
||||
return(0);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* insert should not fail, since duplicates are dropped */
|
||||
if (pqueue_insert(queue->q, item) == NULL)
|
||||
{
|
||||
SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR);
|
||||
if (rdata->rbuf.buf != NULL)
|
||||
OPENSSL_free(rdata->rbuf.buf);
|
||||
OPENSSL_free(rdata);
|
||||
pitem_free(item);
|
||||
return(0);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
return(1);
|
||||
@@ -306,8 +310,9 @@ dtls1_process_buffered_records(SSL *s)
|
||||
dtls1_get_unprocessed_record(s);
|
||||
if ( ! dtls1_process_record(s))
|
||||
return(0);
|
||||
dtls1_buffer_record(s, &(s->d1->processed_rcds),
|
||||
s->s3->rrec.seq_num);
|
||||
if(dtls1_buffer_record(s, &(s->d1->processed_rcds),
|
||||
s->s3->rrec.seq_num)<0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -522,7 +527,6 @@ printf("\n");
|
||||
|
||||
/* we have pulled in a full packet so zero things */
|
||||
s->packet_length=0;
|
||||
dtls1_record_bitmap_update(s, &(s->d1->bitmap));/* Mark receipt of record. */
|
||||
return(1);
|
||||
|
||||
f_err:
|
||||
@@ -555,7 +559,8 @@ int dtls1_get_record(SSL *s)
|
||||
|
||||
/* The epoch may have changed. If so, process all the
|
||||
* pending records. This is a non-blocking operation. */
|
||||
dtls1_process_buffered_records(s);
|
||||
if(dtls1_process_buffered_records(s)<0)
|
||||
return -1;
|
||||
|
||||
/* if we're renegotiating, then there may be buffered records */
|
||||
if (dtls1_get_processed_record(s))
|
||||
@@ -634,8 +639,6 @@ again:
|
||||
/* now s->packet_length == DTLS1_RT_HEADER_LENGTH */
|
||||
i=rr->length;
|
||||
n=ssl3_read_n(s,i,i,1);
|
||||
if (n <= 0) return(n); /* error or non-blocking io */
|
||||
|
||||
/* this packet contained a partial record, dump it */
|
||||
if ( n != i)
|
||||
{
|
||||
@@ -665,7 +668,8 @@ again:
|
||||
* would be dropped unnecessarily.
|
||||
*/
|
||||
if (!(s->d1->listen && rr->type == SSL3_RT_HANDSHAKE &&
|
||||
*p == SSL3_MT_CLIENT_HELLO) &&
|
||||
s->packet_length > DTLS1_RT_HEADER_LENGTH &&
|
||||
s->packet[DTLS1_RT_HEADER_LENGTH] == SSL3_MT_CLIENT_HELLO) &&
|
||||
!dtls1_record_replay_check(s, bitmap))
|
||||
{
|
||||
rr->length = 0;
|
||||
@@ -685,7 +689,9 @@ again:
|
||||
{
|
||||
if ((SSL_in_init(s) || s->in_handshake) && !s->d1->listen)
|
||||
{
|
||||
dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), rr->seq_num);
|
||||
if(dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), rr->seq_num)<0)
|
||||
return -1;
|
||||
dtls1_record_bitmap_update(s, bitmap);/* Mark receipt of record. */
|
||||
}
|
||||
rr->length = 0;
|
||||
s->packet_length = 0;
|
||||
@@ -698,6 +704,7 @@ again:
|
||||
s->packet_length = 0; /* dump this record */
|
||||
goto again; /* get another record */
|
||||
}
|
||||
dtls1_record_bitmap_update(s, bitmap);/* Mark receipt of record. */
|
||||
|
||||
return(1);
|
||||
|
||||
@@ -830,7 +837,11 @@ start:
|
||||
* buffer the application data for later processing rather
|
||||
* than dropping the connection.
|
||||
*/
|
||||
dtls1_buffer_record(s, &(s->d1->buffered_app_data), rr->seq_num);
|
||||
if(dtls1_buffer_record(s, &(s->d1->buffered_app_data), rr->seq_num)<0)
|
||||
{
|
||||
SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR);
|
||||
return -1;
|
||||
}
|
||||
rr->length = 0;
|
||||
goto start;
|
||||
}
|
||||
@@ -1511,7 +1522,7 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len,
|
||||
wr->length += bs;
|
||||
}
|
||||
|
||||
s->method->ssl3_enc->enc(s,1);
|
||||
if(s->method->ssl3_enc->enc(s,1) < 1) goto err;
|
||||
|
||||
/* record length after mac and block padding */
|
||||
/* if (type == SSL3_RT_APPLICATION_DATA ||
|
||||
|
||||
@@ -209,6 +209,7 @@ int dtls1_accept(SSL *s)
|
||||
}
|
||||
if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))
|
||||
{
|
||||
BUF_MEM_free(buf);
|
||||
ret= -1;
|
||||
goto end;
|
||||
}
|
||||
@@ -372,24 +373,15 @@ int dtls1_accept(SSL *s)
|
||||
case SSL3_ST_SW_KEY_EXCH_B:
|
||||
alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
|
||||
|
||||
/* clear this, it may get reset by
|
||||
* send_server_key_exchange */
|
||||
if ((s->options & SSL_OP_EPHEMERAL_RSA)
|
||||
#ifndef OPENSSL_NO_KRB5
|
||||
&& !(alg_k & SSL_kKRB5)
|
||||
#endif /* OPENSSL_NO_KRB5 */
|
||||
)
|
||||
/* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key
|
||||
* even when forbidden by protocol specs
|
||||
* (handshake may fail as clients are not required to
|
||||
* be able to handle this) */
|
||||
s->s3->tmp.use_rsa_tmp=1;
|
||||
else
|
||||
s->s3->tmp.use_rsa_tmp=0;
|
||||
/*
|
||||
* clear this, it may get reset by
|
||||
* send_server_key_exchange
|
||||
*/
|
||||
s->s3->tmp.use_rsa_tmp=0;
|
||||
|
||||
/* only send if a DH key exchange or
|
||||
* RSA but we have a sign only certificate */
|
||||
if (s->s3->tmp.use_rsa_tmp
|
||||
if (0
|
||||
/* PSK: send ServerKeyExchange if PSK identity
|
||||
* hint if provided */
|
||||
#ifndef OPENSSL_NO_PSK
|
||||
@@ -1445,6 +1437,11 @@ int dtls1_send_server_certificate(SSL *s)
|
||||
}
|
||||
|
||||
l=dtls1_output_cert_chain(s,x);
|
||||
if (!l)
|
||||
{
|
||||
SSLerr(SSL_F_DTLS1_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR);
|
||||
return(0);
|
||||
}
|
||||
s->state=SSL3_ST_SW_CERT_B;
|
||||
s->init_num=(int)l;
|
||||
s->init_off=0;
|
||||
|
||||
@@ -80,6 +80,8 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#define DTLS1_VERSION 0xFEFF
|
||||
#define DTLS_MAX_VERSION DTLS1_VERSION
|
||||
|
||||
#define DTLS1_BAD_VER 0x0100
|
||||
|
||||
#if 0
|
||||
@@ -106,6 +108,9 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* Max MTU overhead we know about so far is 40 for IPv6 + 8 for UDP */
|
||||
#define DTLS1_MAX_MTU_OVERHEAD 48
|
||||
|
||||
typedef struct dtls1_bitmap_st
|
||||
{
|
||||
unsigned long map; /* track 32 packets on 32-bit systems
|
||||
@@ -220,6 +225,7 @@ typedef struct dtls1_state_st
|
||||
/* Is set when listening for new connections with dtls1_listen() */
|
||||
unsigned int listen;
|
||||
|
||||
unsigned int link_mtu; /* max on-the-wire DTLS packet size */
|
||||
unsigned int mtu; /* max DTLS packet size */
|
||||
|
||||
struct hm_header_st w_msg_hdr;
|
||||
@@ -264,4 +270,3 @@ typedef struct dtls1_record_data_st
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -125,9 +125,11 @@ static const SSL_METHOD *ssl23_get_client_method(int ver)
|
||||
if (ver == SSL2_VERSION)
|
||||
return(SSLv2_client_method());
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SSL3
|
||||
if (ver == SSL3_VERSION)
|
||||
return(SSLv3_client_method());
|
||||
else if (ver == TLS1_VERSION)
|
||||
#endif
|
||||
if (ver == TLS1_VERSION)
|
||||
return(TLSv1_client_method());
|
||||
else
|
||||
return(NULL);
|
||||
@@ -614,13 +616,16 @@ static int ssl23_get_server_hello(SSL *s)
|
||||
{
|
||||
/* we have sslv3 or tls1 (server hello or alert) */
|
||||
|
||||
#ifndef OPENSSL_NO_SSL3
|
||||
if ((p[2] == SSL3_VERSION_MINOR) &&
|
||||
!(s->options & SSL_OP_NO_SSLv3))
|
||||
{
|
||||
s->version=SSL3_VERSION;
|
||||
s->method=SSLv3_client_method();
|
||||
}
|
||||
else if ((p[2] == TLS1_VERSION_MINOR) &&
|
||||
else
|
||||
#endif
|
||||
if ((p[2] == TLS1_VERSION_MINOR) &&
|
||||
!(s->options & SSL_OP_NO_TLSv1))
|
||||
{
|
||||
s->version=TLS1_VERSION;
|
||||
@@ -632,6 +637,9 @@ static int ssl23_get_server_hello(SSL *s)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* ensure that TLS_MAX_VERSION is up-to-date */
|
||||
OPENSSL_assert(s->version <= TLS_MAX_VERSION);
|
||||
|
||||
if (p[0] == SSL3_RT_ALERT && p[5] != SSL3_AL_WARNING)
|
||||
{
|
||||
/* fatal alert */
|
||||
|
||||
@@ -124,9 +124,11 @@ static const SSL_METHOD *ssl23_get_server_method(int ver)
|
||||
if (ver == SSL2_VERSION)
|
||||
return(SSLv2_server_method());
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SSL3
|
||||
if (ver == SSL3_VERSION)
|
||||
return(SSLv3_server_method());
|
||||
else if (ver == TLS1_VERSION)
|
||||
#endif
|
||||
if (ver == TLS1_VERSION)
|
||||
return(TLSv1_server_method());
|
||||
else
|
||||
return(NULL);
|
||||
@@ -183,6 +185,7 @@ int ssl23_accept(SSL *s)
|
||||
}
|
||||
if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))
|
||||
{
|
||||
BUF_MEM_free(buf);
|
||||
ret= -1;
|
||||
goto end;
|
||||
}
|
||||
@@ -389,6 +392,9 @@ int ssl23_get_client_hello(SSL *s)
|
||||
}
|
||||
}
|
||||
|
||||
/* ensure that TLS_MAX_VERSION is up-to-date */
|
||||
OPENSSL_assert(s->version <= TLS_MAX_VERSION);
|
||||
|
||||
if (s->state == SSL23_ST_SR_CLNT_HELLO_B)
|
||||
{
|
||||
/* we have SSLv3/TLSv1 in an SSLv2 header
|
||||
@@ -556,6 +562,14 @@ int ssl23_get_client_hello(SSL *s)
|
||||
if ((type == 2) || (type == 3))
|
||||
{
|
||||
/* we have SSLv3/TLSv1 (type 2: SSL2 style, type 3: SSL3/TLS style) */
|
||||
const SSL_METHOD *new_method;
|
||||
new_method = ssl23_get_server_method(s->version);
|
||||
if (new_method == NULL)
|
||||
{
|
||||
SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_UNSUPPORTED_PROTOCOL);
|
||||
goto err;
|
||||
}
|
||||
s->method = new_method;
|
||||
|
||||
if (!ssl_init_wbio_buffer(s,1)) goto err;
|
||||
|
||||
@@ -583,11 +597,6 @@ int ssl23_get_client_hello(SSL *s)
|
||||
s->s3->rbuf.left=0;
|
||||
s->s3->rbuf.offset=0;
|
||||
}
|
||||
|
||||
if (s->version == TLS1_VERSION)
|
||||
s->method = TLSv1_server_method();
|
||||
else
|
||||
s->method = SSLv3_server_method();
|
||||
#if 0 /* ssl3_get_client_hello does this */
|
||||
s->client_version=(v[0]<<8)|v[1];
|
||||
#endif
|
||||
|
||||
12
ssl/s2_enc.c
12
ssl/s2_enc.c
@@ -117,8 +117,9 @@ err:
|
||||
|
||||
/* read/writes from s->s2->mac_data using length for encrypt and
|
||||
* decrypt. It sets s->s2->padding and s->[rw]length
|
||||
* if we are encrypting */
|
||||
void ssl2_enc(SSL *s, int send)
|
||||
* if we are encrypting
|
||||
* Returns 0 on error and 1 on success */
|
||||
int ssl2_enc(SSL *s, int send)
|
||||
{
|
||||
EVP_CIPHER_CTX *ds;
|
||||
unsigned long l;
|
||||
@@ -136,7 +137,7 @@ void ssl2_enc(SSL *s, int send)
|
||||
}
|
||||
|
||||
/* check for NULL cipher */
|
||||
if (ds == NULL) return;
|
||||
if (ds == NULL) return 1;
|
||||
|
||||
|
||||
bs=ds->cipher->block_size;
|
||||
@@ -145,7 +146,10 @@ void ssl2_enc(SSL *s, int send)
|
||||
if (bs == 8)
|
||||
l=(l+7)/8*8;
|
||||
|
||||
EVP_Cipher(ds,s->s2->mac_data,s->s2->mac_data,l);
|
||||
if(EVP_Cipher(ds,s->s2->mac_data,s->s2->mac_data,l) < 1)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ssl2_mac(SSL *s, unsigned char *md, int send)
|
||||
|
||||
@@ -391,6 +391,8 @@ long ssl2_ctrl(SSL *s, int cmd, long larg, void *parg)
|
||||
case SSL_CTRL_GET_SESSION_REUSED:
|
||||
ret=s->hit;
|
||||
break;
|
||||
case SSL_CTRL_CHECK_PROTO_VERSION:
|
||||
return ssl3_ctrl(s, SSL_CTRL_CHECK_PROTO_VERSION, larg, parg);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -437,7 +439,7 @@ int ssl2_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p)
|
||||
if (p != NULL)
|
||||
{
|
||||
l=c->id;
|
||||
if ((l & 0xff000000) != 0x02000000) return(0);
|
||||
if ((l & 0xff000000) != 0x02000000 && l != SSL3_CK_FALLBACK_SCSV) return(0);
|
||||
p[0]=((unsigned char)(l>>16L))&0xFF;
|
||||
p[1]=((unsigned char)(l>> 8L))&0xFF;
|
||||
p[2]=((unsigned char)(l ))&0xFF;
|
||||
|
||||
@@ -265,7 +265,11 @@ static int ssl2_read_internal(SSL *s, void *buf, int len, int peek)
|
||||
if ((!s->s2->clear_text) &&
|
||||
(s->s2->rlength >= (unsigned int)mac_size))
|
||||
{
|
||||
ssl2_enc(s,0);
|
||||
if(!ssl2_enc(s,0))
|
||||
{
|
||||
SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_DECRYPTION_FAILED);
|
||||
return(-1);
|
||||
}
|
||||
s->s2->ract_data_length-=mac_size;
|
||||
ssl2_mac(s,mac,0);
|
||||
s->s2->ract_data_length-=s->s2->padding;
|
||||
@@ -616,7 +620,8 @@ static int n_do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len)
|
||||
s->s2->wact_data_length=len+p;
|
||||
ssl2_mac(s,s->s2->mac_data,1);
|
||||
s->s2->wlength+=p+mac_size;
|
||||
ssl2_enc(s,1);
|
||||
if(ssl2_enc(s,1) < 1)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* package up the header */
|
||||
|
||||
@@ -188,13 +188,21 @@ int ssl2_accept(SSL *s)
|
||||
s->version=SSL2_VERSION;
|
||||
s->type=SSL_ST_ACCEPT;
|
||||
|
||||
buf=s->init_buf;
|
||||
if ((buf == NULL) && ((buf=BUF_MEM_new()) == NULL))
|
||||
{ ret= -1; goto end; }
|
||||
if (!BUF_MEM_grow(buf,(int)
|
||||
SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER))
|
||||
{ ret= -1; goto end; }
|
||||
s->init_buf=buf;
|
||||
if(s->init_buf == NULL)
|
||||
{
|
||||
if ((buf=BUF_MEM_new()) == NULL)
|
||||
{
|
||||
ret= -1;
|
||||
goto end;
|
||||
}
|
||||
if (!BUF_MEM_grow(buf,(int) SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER))
|
||||
{
|
||||
BUF_MEM_free(buf);
|
||||
ret= -1;
|
||||
goto end;
|
||||
}
|
||||
s->init_buf=buf;
|
||||
}
|
||||
s->init_num=0;
|
||||
s->ctx->stats.sess_accept++;
|
||||
s->handshake_func=ssl2_accept;
|
||||
|
||||
@@ -408,6 +408,7 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
|
||||
goto f_err;
|
||||
}
|
||||
*ok=1;
|
||||
s->state = stn;
|
||||
s->init_msg = s->init_buf->data + 4;
|
||||
s->init_num = (int)s->s3->tmp.message_size;
|
||||
return s->init_num;
|
||||
|
||||
65
ssl/s3_cbc.c
65
ssl/s3_cbc.c
@@ -53,6 +53,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../crypto/constant_time_locl.h"
|
||||
#include "ssl_locl.h"
|
||||
|
||||
#include <openssl/md5.h>
|
||||
@@ -67,37 +68,6 @@
|
||||
* supported by TLS.) */
|
||||
#define MAX_HASH_BLOCK_SIZE 128
|
||||
|
||||
/* Some utility functions are needed:
|
||||
*
|
||||
* These macros return the given value with the MSB copied to all the other
|
||||
* bits. They use the fact that arithmetic shift shifts-in the sign bit.
|
||||
* However, this is not ensured by the C standard so you may need to replace
|
||||
* them with something else on odd CPUs. */
|
||||
#define DUPLICATE_MSB_TO_ALL(x) ( (unsigned)( (int)(x) >> (sizeof(int)*8-1) ) )
|
||||
#define DUPLICATE_MSB_TO_ALL_8(x) ((unsigned char)(DUPLICATE_MSB_TO_ALL(x)))
|
||||
|
||||
/* constant_time_lt returns 0xff if a<b and 0x00 otherwise. */
|
||||
static unsigned constant_time_lt(unsigned a, unsigned b)
|
||||
{
|
||||
a -= b;
|
||||
return DUPLICATE_MSB_TO_ALL(a);
|
||||
}
|
||||
|
||||
/* constant_time_ge returns 0xff if a>=b and 0x00 otherwise. */
|
||||
static unsigned constant_time_ge(unsigned a, unsigned b)
|
||||
{
|
||||
a -= b;
|
||||
return DUPLICATE_MSB_TO_ALL(~a);
|
||||
}
|
||||
|
||||
/* constant_time_eq_8 returns 0xff if a==b and 0x00 otherwise. */
|
||||
static unsigned char constant_time_eq_8(unsigned a, unsigned b)
|
||||
{
|
||||
unsigned c = a ^ b;
|
||||
c--;
|
||||
return DUPLICATE_MSB_TO_ALL_8(c);
|
||||
}
|
||||
|
||||
/* ssl3_cbc_remove_padding removes padding from the decrypted, SSLv3, CBC
|
||||
* record in |rec| by updating |rec->length| in constant time.
|
||||
*
|
||||
@@ -126,8 +96,8 @@ int ssl3_cbc_remove_padding(const SSL* s,
|
||||
padding_length = good & (padding_length+1);
|
||||
rec->length -= padding_length;
|
||||
rec->type |= padding_length<<8; /* kludge: pass padding length */
|
||||
return (int)((good & 1) | (~good & -1));
|
||||
}
|
||||
return constant_time_select_int(good, 1, -1);
|
||||
}
|
||||
|
||||
/* tls1_cbc_remove_padding removes the CBC padding from the decrypted, TLS, CBC
|
||||
* record in |rec| in constant time and returns 1 if the padding is valid and
|
||||
@@ -201,7 +171,7 @@ int tls1_cbc_remove_padding(const SSL* s,
|
||||
|
||||
for (i = 0; i < to_check; i++)
|
||||
{
|
||||
unsigned char mask = constant_time_ge(padding_length, i);
|
||||
unsigned char mask = constant_time_ge_8(padding_length, i);
|
||||
unsigned char b = rec->data[rec->length-1-i];
|
||||
/* The final |padding_length+1| bytes should all have the value
|
||||
* |padding_length|. Therefore the XOR should be zero. */
|
||||
@@ -209,20 +179,14 @@ int tls1_cbc_remove_padding(const SSL* s,
|
||||
}
|
||||
|
||||
/* If any of the final |padding_length+1| bytes had the wrong value,
|
||||
* one or more of the lower eight bits of |good| will be cleared. We
|
||||
* AND the bottom 8 bits together and duplicate the result to all the
|
||||
* bits. */
|
||||
good &= good >> 4;
|
||||
good &= good >> 2;
|
||||
good &= good >> 1;
|
||||
good <<= sizeof(good)*8-1;
|
||||
good = DUPLICATE_MSB_TO_ALL(good);
|
||||
|
||||
* one or more of the lower eight bits of |good| will be cleared.
|
||||
*/
|
||||
good = constant_time_eq(0xff, good & 0xff);
|
||||
padding_length = good & (padding_length+1);
|
||||
rec->length -= padding_length;
|
||||
rec->type |= padding_length<<8; /* kludge: pass padding length */
|
||||
|
||||
return (int)((good & 1) | (~good & -1));
|
||||
return constant_time_select_int(good, 1, -1);
|
||||
}
|
||||
|
||||
/* ssl3_cbc_copy_mac copies |md_size| bytes from the end of |rec| to |out| in
|
||||
@@ -289,8 +253,8 @@ void ssl3_cbc_copy_mac(unsigned char* out,
|
||||
memset(rotated_mac, 0, md_size);
|
||||
for (i = scan_start, j = 0; i < orig_len; i++)
|
||||
{
|
||||
unsigned char mac_started = constant_time_ge(i, mac_start);
|
||||
unsigned char mac_ended = constant_time_ge(i, mac_end);
|
||||
unsigned char mac_started = constant_time_ge_8(i, mac_start);
|
||||
unsigned char mac_ended = constant_time_ge_8(i, mac_end);
|
||||
unsigned char b = rec->data[i];
|
||||
rotated_mac[j++] |= b & mac_started & ~mac_ended;
|
||||
j &= constant_time_lt(j,md_size);
|
||||
@@ -672,12 +636,12 @@ void ssl3_cbc_digest_record(
|
||||
b = data[k-header_length];
|
||||
k++;
|
||||
|
||||
is_past_c = is_block_a & constant_time_ge(j, c);
|
||||
is_past_cp1 = is_block_a & constant_time_ge(j, c+1);
|
||||
is_past_c = is_block_a & constant_time_ge_8(j, c);
|
||||
is_past_cp1 = is_block_a & constant_time_ge_8(j, c+1);
|
||||
/* If this is the block containing the end of the
|
||||
* application data, and we are at the offset for the
|
||||
* 0x80 value, then overwrite b with 0x80. */
|
||||
b = (b&~is_past_c) | (0x80&is_past_c);
|
||||
b = constant_time_select_8(is_past_c, 0x80, b);
|
||||
/* If this the the block containing the end of the
|
||||
* application data and we're past the 0x80 value then
|
||||
* just write zero. */
|
||||
@@ -693,7 +657,8 @@ void ssl3_cbc_digest_record(
|
||||
if (j >= md_block_size - md_length_size)
|
||||
{
|
||||
/* If this is index_b, write a length byte. */
|
||||
b = (b&~is_block_b) | (is_block_b&length_bytes[j-(md_block_size-md_length_size)]);
|
||||
b = constant_time_select_8(
|
||||
is_block_b, length_bytes[j-(md_block_size-md_length_size)], b);
|
||||
}
|
||||
block[j] = b;
|
||||
}
|
||||
|
||||
199
ssl/s3_clnt.c
199
ssl/s3_clnt.c
@@ -1174,8 +1174,8 @@ int ssl3_get_key_exchange(SSL *s)
|
||||
#endif
|
||||
EVP_MD_CTX md_ctx;
|
||||
unsigned char *param,*p;
|
||||
int al,i,j,param_len,ok;
|
||||
long n,alg_k,alg_a;
|
||||
int al,j,ok;
|
||||
long i,param_len,n,alg_k,alg_a;
|
||||
EVP_PKEY *pkey=NULL;
|
||||
#ifndef OPENSSL_NO_RSA
|
||||
RSA *rsa=NULL;
|
||||
@@ -1191,6 +1191,8 @@ int ssl3_get_key_exchange(SSL *s)
|
||||
int encoded_pt_len = 0;
|
||||
#endif
|
||||
|
||||
EVP_MD_CTX_init(&md_ctx);
|
||||
|
||||
/* use same message size as in ssl3_get_certificate_request()
|
||||
* as ServerKeyExchange message may be skipped */
|
||||
n=s->method->ssl_get_message(s,
|
||||
@@ -1201,14 +1203,26 @@ int ssl3_get_key_exchange(SSL *s)
|
||||
&ok);
|
||||
if (!ok) return((int)n);
|
||||
|
||||
alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
|
||||
|
||||
if (s->s3->tmp.message_type != SSL3_MT_SERVER_KEY_EXCHANGE)
|
||||
{
|
||||
/*
|
||||
* Can't skip server key exchange if this is an ephemeral
|
||||
* ciphersuite.
|
||||
*/
|
||||
if (alg_k & (SSL_kEDH|SSL_kEECDH))
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE);
|
||||
al = SSL_AD_UNEXPECTED_MESSAGE;
|
||||
goto f_err;
|
||||
}
|
||||
#ifndef OPENSSL_NO_PSK
|
||||
/* In plain PSK ciphersuite, ServerKeyExchange can be
|
||||
omitted if no identity hint is sent. Set
|
||||
session->sess_cert anyway to avoid problems
|
||||
later.*/
|
||||
if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)
|
||||
if (alg_k & SSL_kPSK)
|
||||
{
|
||||
s->session->sess_cert=ssl_sess_cert_new();
|
||||
if (s->ctx->psk_identity_hint)
|
||||
@@ -1250,36 +1264,46 @@ int ssl3_get_key_exchange(SSL *s)
|
||||
s->session->sess_cert=ssl_sess_cert_new();
|
||||
}
|
||||
|
||||
/* Total length of the parameters including the length prefix */
|
||||
param_len=0;
|
||||
alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
|
||||
|
||||
alg_a=s->s3->tmp.new_cipher->algorithm_auth;
|
||||
EVP_MD_CTX_init(&md_ctx);
|
||||
|
||||
al=SSL_AD_DECODE_ERROR;
|
||||
|
||||
#ifndef OPENSSL_NO_PSK
|
||||
if (alg_k & SSL_kPSK)
|
||||
{
|
||||
char tmp_id_hint[PSK_MAX_IDENTITY_LEN+1];
|
||||
|
||||
al=SSL_AD_HANDSHAKE_FAILURE;
|
||||
param_len = 2;
|
||||
if (param_len > n)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
|
||||
SSL_R_LENGTH_TOO_SHORT);
|
||||
goto f_err;
|
||||
}
|
||||
n2s(p,i);
|
||||
param_len=i+2;
|
||||
|
||||
/* Store PSK identity hint for later use, hint is used
|
||||
* in ssl3_send_client_key_exchange. Assume that the
|
||||
* maximum length of a PSK identity hint can be as
|
||||
* long as the maximum length of a PSK identity. */
|
||||
if (i > PSK_MAX_IDENTITY_LEN)
|
||||
{
|
||||
al=SSL_AD_HANDSHAKE_FAILURE;
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
|
||||
SSL_R_DATA_LENGTH_TOO_LONG);
|
||||
goto f_err;
|
||||
}
|
||||
if (param_len > n)
|
||||
if (i > n - param_len)
|
||||
{
|
||||
al=SSL_AD_DECODE_ERROR;
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
|
||||
SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH);
|
||||
goto f_err;
|
||||
}
|
||||
param_len += i;
|
||||
|
||||
/* If received PSK identity hint contains NULL
|
||||
* characters, the hint is truncated from the first
|
||||
* NULL. p may not be ending with NULL, so create a
|
||||
@@ -1291,6 +1315,7 @@ int ssl3_get_key_exchange(SSL *s)
|
||||
s->ctx->psk_identity_hint = BUF_strdup(tmp_id_hint);
|
||||
if (s->ctx->psk_identity_hint == NULL)
|
||||
{
|
||||
al=SSL_AD_HANDSHAKE_FAILURE;
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
|
||||
goto f_err;
|
||||
}
|
||||
@@ -1303,19 +1328,35 @@ int ssl3_get_key_exchange(SSL *s)
|
||||
#ifndef OPENSSL_NO_RSA
|
||||
if (alg_k & SSL_kRSA)
|
||||
{
|
||||
/* Temporary RSA keys only allowed in export ciphersuites */
|
||||
if (!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher))
|
||||
{
|
||||
al=SSL_AD_UNEXPECTED_MESSAGE;
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE);
|
||||
goto f_err;
|
||||
}
|
||||
if ((rsa=RSA_new()) == NULL)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
n2s(p,i);
|
||||
param_len=i+2;
|
||||
|
||||
param_len = 2;
|
||||
if (param_len > n)
|
||||
{
|
||||
al=SSL_AD_DECODE_ERROR;
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
|
||||
SSL_R_LENGTH_TOO_SHORT);
|
||||
goto f_err;
|
||||
}
|
||||
n2s(p,i);
|
||||
|
||||
if (i > n - param_len)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_RSA_MODULUS_LENGTH);
|
||||
goto f_err;
|
||||
}
|
||||
param_len += i;
|
||||
|
||||
if (!(rsa->n=BN_bin2bn(p,i,rsa->n)))
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
|
||||
@@ -1323,14 +1364,23 @@ int ssl3_get_key_exchange(SSL *s)
|
||||
}
|
||||
p+=i;
|
||||
|
||||
n2s(p,i);
|
||||
param_len+=i+2;
|
||||
if (param_len > n)
|
||||
if (2 > n - param_len)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
|
||||
SSL_R_LENGTH_TOO_SHORT);
|
||||
goto f_err;
|
||||
}
|
||||
param_len += 2;
|
||||
|
||||
n2s(p,i);
|
||||
|
||||
if (i > n - param_len)
|
||||
{
|
||||
al=SSL_AD_DECODE_ERROR;
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_RSA_E_LENGTH);
|
||||
goto f_err;
|
||||
}
|
||||
param_len += i;
|
||||
|
||||
if (!(rsa->e=BN_bin2bn(p,i,rsa->e)))
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
|
||||
@@ -1362,14 +1412,23 @@ int ssl3_get_key_exchange(SSL *s)
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_DH_LIB);
|
||||
goto err;
|
||||
}
|
||||
n2s(p,i);
|
||||
param_len=i+2;
|
||||
|
||||
param_len = 2;
|
||||
if (param_len > n)
|
||||
{
|
||||
al=SSL_AD_DECODE_ERROR;
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
|
||||
SSL_R_LENGTH_TOO_SHORT);
|
||||
goto f_err;
|
||||
}
|
||||
n2s(p,i);
|
||||
|
||||
if (i > n - param_len)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_DH_P_LENGTH);
|
||||
goto f_err;
|
||||
}
|
||||
param_len += i;
|
||||
|
||||
if (!(dh->p=BN_bin2bn(p,i,NULL)))
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
|
||||
@@ -1377,14 +1436,23 @@ int ssl3_get_key_exchange(SSL *s)
|
||||
}
|
||||
p+=i;
|
||||
|
||||
n2s(p,i);
|
||||
param_len+=i+2;
|
||||
if (param_len > n)
|
||||
if (2 > n - param_len)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
|
||||
SSL_R_LENGTH_TOO_SHORT);
|
||||
goto f_err;
|
||||
}
|
||||
param_len += 2;
|
||||
|
||||
n2s(p,i);
|
||||
|
||||
if (i > n - param_len)
|
||||
{
|
||||
al=SSL_AD_DECODE_ERROR;
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_DH_G_LENGTH);
|
||||
goto f_err;
|
||||
}
|
||||
param_len += i;
|
||||
|
||||
if (!(dh->g=BN_bin2bn(p,i,NULL)))
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
|
||||
@@ -1392,14 +1460,23 @@ int ssl3_get_key_exchange(SSL *s)
|
||||
}
|
||||
p+=i;
|
||||
|
||||
n2s(p,i);
|
||||
param_len+=i+2;
|
||||
if (param_len > n)
|
||||
if (2 > n - param_len)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
|
||||
SSL_R_LENGTH_TOO_SHORT);
|
||||
goto f_err;
|
||||
}
|
||||
param_len += 2;
|
||||
|
||||
n2s(p,i);
|
||||
|
||||
if (i > n - param_len)
|
||||
{
|
||||
al=SSL_AD_DECODE_ERROR;
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_DH_PUB_KEY_LENGTH);
|
||||
goto f_err;
|
||||
}
|
||||
param_len += i;
|
||||
|
||||
if (!(dh->pub_key=BN_bin2bn(p,i,NULL)))
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
|
||||
@@ -1451,12 +1528,19 @@ int ssl3_get_key_exchange(SSL *s)
|
||||
*/
|
||||
|
||||
/* XXX: For now we only support named (not generic) curves
|
||||
* and the ECParameters in this case is just three bytes.
|
||||
* and the ECParameters in this case is just three bytes. We
|
||||
* also need one byte for the length of the encoded point
|
||||
*/
|
||||
param_len=3;
|
||||
if ((param_len > n) ||
|
||||
(*p != NAMED_CURVE_TYPE) ||
|
||||
((curve_nid = tls1_ec_curve_id2nid(*(p + 2))) == 0))
|
||||
param_len=4;
|
||||
if (param_len > n)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
|
||||
SSL_R_LENGTH_TOO_SHORT);
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
if ((*p != NAMED_CURVE_TYPE) ||
|
||||
((curve_nid = tls1_ec_curve_id2nid(*(p + 2))) == 0))
|
||||
{
|
||||
al=SSL_AD_INTERNAL_ERROR;
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS);
|
||||
@@ -1498,15 +1582,15 @@ int ssl3_get_key_exchange(SSL *s)
|
||||
|
||||
encoded_pt_len = *p; /* length of encoded point */
|
||||
p+=1;
|
||||
param_len += (1 + encoded_pt_len);
|
||||
if ((param_len > n) ||
|
||||
|
||||
if ((encoded_pt_len > n - param_len) ||
|
||||
(EC_POINT_oct2point(group, srvr_ecpoint,
|
||||
p, encoded_pt_len, bn_ctx) == 0))
|
||||
{
|
||||
al=SSL_AD_DECODE_ERROR;
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_ECPOINT);
|
||||
goto f_err;
|
||||
}
|
||||
param_len += encoded_pt_len;
|
||||
|
||||
n-=param_len;
|
||||
p+=encoded_pt_len;
|
||||
@@ -1551,10 +1635,10 @@ int ssl3_get_key_exchange(SSL *s)
|
||||
n-=2;
|
||||
j=EVP_PKEY_size(pkey);
|
||||
|
||||
/* Check signature length. If n is 0 then signature is empty */
|
||||
if ((i != n) || (n > j) || (n <= 0))
|
||||
{
|
||||
/* wrong packet length */
|
||||
al=SSL_AD_DECODE_ERROR;
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_WRONG_SIGNATURE_LENGTH);
|
||||
goto f_err;
|
||||
}
|
||||
@@ -1563,6 +1647,7 @@ int ssl3_get_key_exchange(SSL *s)
|
||||
if (pkey->type == EVP_PKEY_RSA)
|
||||
{
|
||||
int num;
|
||||
unsigned int size;
|
||||
|
||||
j=0;
|
||||
q=md_buf;
|
||||
@@ -1573,9 +1658,9 @@ int ssl3_get_key_exchange(SSL *s)
|
||||
EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
|
||||
EVP_DigestUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
|
||||
EVP_DigestUpdate(&md_ctx,param,param_len);
|
||||
EVP_DigestFinal_ex(&md_ctx,q,(unsigned int *)&i);
|
||||
q+=i;
|
||||
j+=i;
|
||||
EVP_DigestFinal_ex(&md_ctx,q,&size);
|
||||
q+=size;
|
||||
j+=size;
|
||||
}
|
||||
i=RSA_verify(NID_md5_sha1, md_buf, j, p, n,
|
||||
pkey->pkey.rsa);
|
||||
@@ -1647,7 +1732,6 @@ int ssl3_get_key_exchange(SSL *s)
|
||||
/* still data left over */
|
||||
if (n != 0)
|
||||
{
|
||||
al=SSL_AD_DECODE_ERROR;
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_EXTRA_DATA_IN_MESSAGE);
|
||||
goto f_err;
|
||||
}
|
||||
@@ -2588,7 +2672,11 @@ int ssl3_send_client_key_exchange(SSL *s)
|
||||
#ifndef OPENSSL_NO_PSK
|
||||
else if (alg_k & SSL_kPSK)
|
||||
{
|
||||
char identity[PSK_MAX_IDENTITY_LEN];
|
||||
/* The callback needs PSK_MAX_IDENTITY_LEN + 1 bytes
|
||||
* to return a \0-terminated identity. The last byte
|
||||
* is for us for simulating strnlen. */
|
||||
char identity[PSK_MAX_IDENTITY_LEN + 2];
|
||||
size_t identity_len;
|
||||
unsigned char *t = NULL;
|
||||
unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN*2+4];
|
||||
unsigned int pre_ms_len = 0, psk_len = 0;
|
||||
@@ -2602,8 +2690,9 @@ int ssl3_send_client_key_exchange(SSL *s)
|
||||
goto err;
|
||||
}
|
||||
|
||||
memset(identity, 0, sizeof(identity));
|
||||
psk_len = s->psk_client_callback(s, s->ctx->psk_identity_hint,
|
||||
identity, PSK_MAX_IDENTITY_LEN,
|
||||
identity, sizeof(identity) - 1,
|
||||
psk_or_pre_ms, sizeof(psk_or_pre_ms));
|
||||
if (psk_len > PSK_MAX_PSK_LEN)
|
||||
{
|
||||
@@ -2617,7 +2706,14 @@ int ssl3_send_client_key_exchange(SSL *s)
|
||||
SSL_R_PSK_IDENTITY_NOT_FOUND);
|
||||
goto psk_err;
|
||||
}
|
||||
|
||||
identity[PSK_MAX_IDENTITY_LEN + 1] = '\0';
|
||||
identity_len = strlen(identity);
|
||||
if (identity_len > PSK_MAX_IDENTITY_LEN)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
goto psk_err;
|
||||
}
|
||||
/* create PSK pre_master_secret */
|
||||
pre_ms_len = 2+psk_len+2+psk_len;
|
||||
t = psk_or_pre_ms;
|
||||
@@ -2651,14 +2747,13 @@ int ssl3_send_client_key_exchange(SSL *s)
|
||||
s->session->master_key_length =
|
||||
s->method->ssl3_enc->generate_master_secret(s,
|
||||
s->session->master_key,
|
||||
psk_or_pre_ms, pre_ms_len);
|
||||
n = strlen(identity);
|
||||
s2n(n, p);
|
||||
memcpy(p, identity, n);
|
||||
n+=2;
|
||||
psk_or_pre_ms, pre_ms_len);
|
||||
s2n(identity_len, p);
|
||||
memcpy(p, identity, identity_len);
|
||||
n = 2 + identity_len;
|
||||
psk_err = 0;
|
||||
psk_err:
|
||||
OPENSSL_cleanse(identity, PSK_MAX_IDENTITY_LEN);
|
||||
OPENSSL_cleanse(identity, sizeof(identity));
|
||||
OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms));
|
||||
if (psk_err != 0)
|
||||
{
|
||||
@@ -2886,6 +2981,12 @@ int ssl3_send_client_certificate(SSL *s)
|
||||
s->state=SSL3_ST_CW_CERT_D;
|
||||
l=ssl3_output_cert_chain(s,
|
||||
(s->s3->tmp.cert_req == 2)?NULL:s->cert->key->x509);
|
||||
if (!l)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_SEND_CLIENT_CERTIFICATE, ERR_R_INTERNAL_ERROR);
|
||||
ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
s->init_num=(int)l;
|
||||
s->init_off=0;
|
||||
}
|
||||
|
||||
@@ -534,7 +534,8 @@ int ssl3_enc(SSL *s, int send)
|
||||
/* otherwise, rec->length >= bs */
|
||||
}
|
||||
|
||||
EVP_Cipher(ds,rec->data,rec->input,l);
|
||||
if(EVP_Cipher(ds,rec->data,rec->input,l) < 1)
|
||||
return -1;
|
||||
|
||||
if (EVP_MD_CTX_md(s->read_hash) != NULL)
|
||||
mac_size = EVP_MD_CTX_size(s->read_hash);
|
||||
@@ -888,7 +889,7 @@ int ssl3_alert_code(int code)
|
||||
case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(SSL3_AD_HANDSHAKE_FAILURE);
|
||||
case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(SSL3_AD_HANDSHAKE_FAILURE);
|
||||
case SSL_AD_UNKNOWN_PSK_IDENTITY:return(TLS1_AD_UNKNOWN_PSK_IDENTITY);
|
||||
case SSL_AD_INAPPROPRIATE_FALLBACK:return(TLS1_AD_INAPPROPRIATE_FALLBACK);
|
||||
default: return(-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
27
ssl/s3_lib.c
27
ssl/s3_lib.c
@@ -2492,6 +2492,29 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
|
||||
break;
|
||||
|
||||
#endif /* !OPENSSL_NO_TLSEXT */
|
||||
|
||||
case SSL_CTRL_CHECK_PROTO_VERSION:
|
||||
/* For library-internal use; checks that the current protocol
|
||||
* is the highest enabled version (according to s->ctx->method,
|
||||
* as version negotiation may have changed s->method). */
|
||||
if (s->version == s->ctx->method->version)
|
||||
return 1;
|
||||
/* Apparently we're using a version-flexible SSL_METHOD
|
||||
* (not at its highest protocol version). */
|
||||
if (s->ctx->method->version == SSLv23_method()->version)
|
||||
{
|
||||
#if TLS_MAX_VERSION != TLS1_VERSION
|
||||
# error Code needs update for SSLv23_method() support beyond TLS1_VERSION.
|
||||
#endif
|
||||
if (!(s->options & SSL_OP_NO_TLSv1))
|
||||
return s->version == TLS1_VERSION;
|
||||
if (!(s->options & SSL_OP_NO_SSLv3))
|
||||
return s->version == SSL3_VERSION;
|
||||
if (!(s->options & SSL_OP_NO_SSLv2))
|
||||
return s->version == SSL2_VERSION;
|
||||
}
|
||||
return 0; /* Unexpected state; fail closed. */
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -2793,6 +2816,7 @@ long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void))
|
||||
break;
|
||||
|
||||
#endif
|
||||
|
||||
default:
|
||||
return(0);
|
||||
}
|
||||
@@ -3034,6 +3058,7 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
|
||||
}
|
||||
ok = ok && ec_ok;
|
||||
}
|
||||
#ifndef OPENSSL_NO_ECDH
|
||||
if (
|
||||
/* if we are considering an ECC cipher suite that uses an ephemeral EC key */
|
||||
(alg_k & SSL_kEECDH)
|
||||
@@ -3081,6 +3106,7 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
|
||||
}
|
||||
ok = ok && ec_ok;
|
||||
}
|
||||
#endif /* OPENSSL_NO_ECDH */
|
||||
#endif /* OPENSSL_NO_EC */
|
||||
#endif /* OPENSSL_NO_TLSEXT */
|
||||
|
||||
@@ -3347,4 +3373,3 @@ need to go to SSL_ST_ACCEPT.
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
24
ssl/s3_pkt.c
24
ssl/s3_pkt.c
@@ -182,6 +182,8 @@ int ssl3_read_n(SSL *s, int n, int max, int extend)
|
||||
* at once (as long as it fits into the buffer). */
|
||||
if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER)
|
||||
{
|
||||
if (left == 0 && extend)
|
||||
return 0;
|
||||
if (left > 0 && n > left)
|
||||
n = left;
|
||||
}
|
||||
@@ -272,6 +274,12 @@ int ssl3_read_n(SSL *s, int n, int max, int extend)
|
||||
return(n);
|
||||
}
|
||||
|
||||
/* MAX_EMPTY_RECORDS defines the number of consecutive, empty records that will
|
||||
* be processed per call to ssl3_get_record. Without this limit an attacker
|
||||
* could send empty records at a faster rate than we can process and cause
|
||||
* ssl3_get_record to loop forever. */
|
||||
#define MAX_EMPTY_RECORDS 32
|
||||
|
||||
/* Call this to get a new input record.
|
||||
* It will return <= 0 if more data is needed, normally due to an error
|
||||
* or non-blocking IO.
|
||||
@@ -292,6 +300,7 @@ static int ssl3_get_record(SSL *s)
|
||||
short version;
|
||||
unsigned mac_size, orig_len;
|
||||
size_t extra;
|
||||
unsigned empty_record_count = 0;
|
||||
|
||||
rr= &(s->s3->rrec);
|
||||
sess=s->session;
|
||||
@@ -522,7 +531,17 @@ printf("\n");
|
||||
s->packet_length=0;
|
||||
|
||||
/* just read a 0 length packet */
|
||||
if (rr->length == 0) goto again;
|
||||
if (rr->length == 0)
|
||||
{
|
||||
empty_record_count++;
|
||||
if (empty_record_count > MAX_EMPTY_RECORDS)
|
||||
{
|
||||
al=SSL_AD_UNEXPECTED_MESSAGE;
|
||||
SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_RECORD_TOO_SMALL);
|
||||
goto f_err;
|
||||
}
|
||||
goto again;
|
||||
}
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "Ultimate Record type=%d, Length=%d\n", rr->type, rr->length);
|
||||
@@ -799,8 +818,7 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
|
||||
wr->data=p;
|
||||
}
|
||||
|
||||
/* ssl3_enc can only have an error on read */
|
||||
s->method->ssl3_enc->enc(s,1);
|
||||
if(s->method->ssl3_enc->enc(s,1)<1) goto err;
|
||||
|
||||
/* record length after mac and block padding */
|
||||
s2n(wr->length,plen);
|
||||
|
||||
147
ssl/s3_srvr.c
147
ssl/s3_srvr.c
@@ -154,6 +154,7 @@
|
||||
#include <stdio.h>
|
||||
#include "ssl_locl.h"
|
||||
#include "kssl_lcl.h"
|
||||
#include "../crypto/constant_time_locl.h"
|
||||
#include <openssl/buffer.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/objects.h>
|
||||
@@ -245,6 +246,7 @@ int ssl3_accept(SSL *s)
|
||||
}
|
||||
if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))
|
||||
{
|
||||
BUF_MEM_free(buf);
|
||||
ret= -1;
|
||||
goto end;
|
||||
}
|
||||
@@ -378,20 +380,11 @@ int ssl3_accept(SSL *s)
|
||||
case SSL3_ST_SW_KEY_EXCH_B:
|
||||
alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
|
||||
|
||||
/* clear this, it may get reset by
|
||||
* send_server_key_exchange */
|
||||
if ((s->options & SSL_OP_EPHEMERAL_RSA)
|
||||
#ifndef OPENSSL_NO_KRB5
|
||||
&& !(alg_k & SSL_kKRB5)
|
||||
#endif /* OPENSSL_NO_KRB5 */
|
||||
)
|
||||
/* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key
|
||||
* even when forbidden by protocol specs
|
||||
* (handshake may fail as clients are not required to
|
||||
* be able to handle this) */
|
||||
s->s3->tmp.use_rsa_tmp=1;
|
||||
else
|
||||
s->s3->tmp.use_rsa_tmp=0;
|
||||
/*
|
||||
* clear this, it may get reset by
|
||||
* send_server_key_exchange
|
||||
*/
|
||||
s->s3->tmp.use_rsa_tmp=0;
|
||||
|
||||
|
||||
/* only send if a DH key exchange, fortezza or
|
||||
@@ -405,7 +398,7 @@ int ssl3_accept(SSL *s)
|
||||
* server certificate contains the server's
|
||||
* public key for key exchange.
|
||||
*/
|
||||
if (s->s3->tmp.use_rsa_tmp
|
||||
if (0
|
||||
/* PSK: send ServerKeyExchange if PSK identity
|
||||
* hint if provided */
|
||||
#ifndef OPENSSL_NO_PSK
|
||||
@@ -2010,6 +2003,11 @@ int ssl3_get_client_key_exchange(SSL *s)
|
||||
#ifndef OPENSSL_NO_RSA
|
||||
if (alg_k & SSL_kRSA)
|
||||
{
|
||||
unsigned char rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH];
|
||||
int decrypt_len;
|
||||
unsigned char decrypt_good, version_good;
|
||||
size_t j;
|
||||
|
||||
/* FIX THIS UP EAY EAY EAY EAY */
|
||||
if (s->s3->tmp.use_rsa_tmp)
|
||||
{
|
||||
@@ -2047,8 +2045,9 @@ int ssl3_get_client_key_exchange(SSL *s)
|
||||
{
|
||||
if (!(s->options & SSL_OP_TLS_D5_BUG))
|
||||
{
|
||||
al = SSL_AD_DECODE_ERROR;
|
||||
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG);
|
||||
goto err;
|
||||
goto f_err;
|
||||
}
|
||||
else
|
||||
p-=2;
|
||||
@@ -2057,59 +2056,84 @@ int ssl3_get_client_key_exchange(SSL *s)
|
||||
n=i;
|
||||
}
|
||||
|
||||
i=RSA_private_decrypt((int)n,p,p,rsa,RSA_PKCS1_PADDING);
|
||||
|
||||
al = -1;
|
||||
|
||||
if (i != SSL_MAX_MASTER_KEY_LENGTH)
|
||||
/*
|
||||
* Reject overly short RSA ciphertext because we want to be sure
|
||||
* that the buffer size makes it safe to iterate over the entire
|
||||
* size of a premaster secret (SSL_MAX_MASTER_KEY_LENGTH). The
|
||||
* actual expected size is larger due to RSA padding, but the
|
||||
* bound is sufficient to be safe.
|
||||
*/
|
||||
if (n < SSL_MAX_MASTER_KEY_LENGTH)
|
||||
{
|
||||
al=SSL_AD_DECODE_ERROR;
|
||||
/* SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_RSA_DECRYPT); */
|
||||
al = SSL_AD_DECRYPT_ERROR;
|
||||
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG);
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
if ((al == -1) && !((p[0] == (s->client_version>>8)) && (p[1] == (s->client_version & 0xff))))
|
||||
{
|
||||
/* The premaster secret must contain the same version number as the
|
||||
* ClientHello to detect version rollback attacks (strangely, the
|
||||
* protocol does not offer such protection for DH ciphersuites).
|
||||
* However, buggy clients exist that send the negotiated protocol
|
||||
* version instead if the server does not support the requested
|
||||
* protocol version.
|
||||
* If SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such clients. */
|
||||
if (!((s->options & SSL_OP_TLS_ROLLBACK_BUG) &&
|
||||
(p[0] == (s->version>>8)) && (p[1] == (s->version & 0xff))))
|
||||
{
|
||||
al=SSL_AD_DECODE_ERROR;
|
||||
/* SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_PROTOCOL_VERSION_NUMBER); */
|
||||
/* We must not leak whether a decryption failure occurs because
|
||||
* of Bleichenbacher's attack on PKCS #1 v1.5 RSA padding (see
|
||||
* RFC 2246, section 7.4.7.1). The code follows that advice of
|
||||
* the TLS RFC and generates a random premaster secret for the
|
||||
* case that the decrypt fails. See
|
||||
* https://tools.ietf.org/html/rfc5246#section-7.4.7.1 */
|
||||
|
||||
/* The Klima-Pokorny-Rosa extension of Bleichenbacher's attack
|
||||
* (http://eprint.iacr.org/2003/052/) exploits the version
|
||||
* number check as a "bad version oracle" -- an alert would
|
||||
* reveal that the plaintext corresponding to some ciphertext
|
||||
* made up by the adversary is properly formatted except
|
||||
* that the version number is wrong. To avoid such attacks,
|
||||
* we should treat this just like any other decryption error. */
|
||||
}
|
||||
/* should be RAND_bytes, but we cannot work around a failure. */
|
||||
if (RAND_pseudo_bytes(rand_premaster_secret,
|
||||
sizeof(rand_premaster_secret)) <= 0)
|
||||
goto err;
|
||||
decrypt_len = RSA_private_decrypt((int)n,p,p,rsa,RSA_PKCS1_PADDING);
|
||||
ERR_clear_error();
|
||||
|
||||
/* decrypt_len should be SSL_MAX_MASTER_KEY_LENGTH.
|
||||
* decrypt_good will be 0xff if so and zero otherwise. */
|
||||
decrypt_good = constant_time_eq_int_8(decrypt_len, SSL_MAX_MASTER_KEY_LENGTH);
|
||||
|
||||
/* If the version in the decrypted pre-master secret is correct
|
||||
* then version_good will be 0xff, otherwise it'll be zero.
|
||||
* The Klima-Pokorny-Rosa extension of Bleichenbacher's attack
|
||||
* (http://eprint.iacr.org/2003/052/) exploits the version
|
||||
* number check as a "bad version oracle". Thus version checks
|
||||
* are done in constant time and are treated like any other
|
||||
* decryption error. */
|
||||
version_good = constant_time_eq_8(p[0], (unsigned)(s->client_version>>8));
|
||||
version_good &= constant_time_eq_8(p[1], (unsigned)(s->client_version&0xff));
|
||||
|
||||
/* The premaster secret must contain the same version number as
|
||||
* the ClientHello to detect version rollback attacks
|
||||
* (strangely, the protocol does not offer such protection for
|
||||
* DH ciphersuites). However, buggy clients exist that send the
|
||||
* negotiated protocol version instead if the server does not
|
||||
* support the requested protocol version. If
|
||||
* SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such clients. */
|
||||
if (s->options & SSL_OP_TLS_ROLLBACK_BUG)
|
||||
{
|
||||
unsigned char workaround_good;
|
||||
workaround_good = constant_time_eq_8(p[0], (unsigned)(s->version>>8));
|
||||
workaround_good &= constant_time_eq_8(p[1], (unsigned)(s->version&0xff));
|
||||
version_good |= workaround_good;
|
||||
}
|
||||
|
||||
if (al != -1)
|
||||
/* Both decryption and version must be good for decrypt_good
|
||||
* to remain non-zero (0xff). */
|
||||
decrypt_good &= version_good;
|
||||
|
||||
/*
|
||||
* Now copy rand_premaster_secret over from p using
|
||||
* decrypt_good_mask. If decryption failed, then p does not
|
||||
* contain valid plaintext, however, a check above guarantees
|
||||
* it is still sufficiently large to read from.
|
||||
*/
|
||||
for (j = 0; j < sizeof(rand_premaster_secret); j++)
|
||||
{
|
||||
/* Some decryption failure -- use random value instead as countermeasure
|
||||
* against Bleichenbacher's attack on PKCS #1 v1.5 RSA padding
|
||||
* (see RFC 2246, section 7.4.7.1). */
|
||||
ERR_clear_error();
|
||||
i = SSL_MAX_MASTER_KEY_LENGTH;
|
||||
p[0] = s->client_version >> 8;
|
||||
p[1] = s->client_version & 0xff;
|
||||
if (RAND_pseudo_bytes(p+2, i-2) <= 0) /* should be RAND_bytes, but we cannot work around a failure */
|
||||
goto err;
|
||||
p[j] = constant_time_select_8(decrypt_good, p[j],
|
||||
rand_premaster_secret[j]);
|
||||
}
|
||||
|
||||
|
||||
s->session->master_key_length=
|
||||
s->method->ssl3_enc->generate_master_secret(s,
|
||||
s->session->master_key,
|
||||
p,i);
|
||||
OPENSSL_cleanse(p,i);
|
||||
p,sizeof(rand_premaster_secret));
|
||||
OPENSSL_cleanse(p,sizeof(rand_premaster_secret));
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@@ -2741,7 +2765,7 @@ int ssl3_get_cert_verify(SSL *s)
|
||||
if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_VERIFY)
|
||||
{
|
||||
s->s3->tmp.reuse_message=1;
|
||||
if ((peer != NULL) && (type & EVP_PKT_SIGN))
|
||||
if (peer != NULL)
|
||||
{
|
||||
al=SSL_AD_UNEXPECTED_MESSAGE;
|
||||
SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_MISSING_VERIFY_MESSAGE);
|
||||
@@ -3071,6 +3095,11 @@ int ssl3_send_server_certificate(SSL *s)
|
||||
}
|
||||
|
||||
l=ssl3_output_cert_chain(s,x);
|
||||
if (!l)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR);
|
||||
return(0);
|
||||
}
|
||||
s->state=SSL3_ST_SW_CERT_B;
|
||||
s->init_num=(int)l;
|
||||
s->init_off=0;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user