diff --git a/.github/workflows/compile-examples.yml b/.github/workflows/compile-examples.yml index b465ffd85..5eb4f66d9 100644 --- a/.github/workflows/compile-examples.yml +++ b/.github/workflows/compile-examples.yml @@ -105,6 +105,7 @@ jobs: # Install samd platform via Boards Manager - name: arduino:samd libraries: | + - name: ArduinoBearSSL - name: ArduinoECCX08 - name: Blues Wireless Notecard - name: RTCZero @@ -122,6 +123,7 @@ jobs: - name: arduino:samd - name: arduino:mbed_nano libraries: | + - name: ArduinoBearSSL - name: ArduinoECCX08 - name: Blues Wireless Notecard - name: RTCZero @@ -154,6 +156,7 @@ jobs: # Install samd platform via Boards Manager - name: arduino:samd libraries: | + - name: ArduinoBearSSL - name: ArduinoECCX08 - name: Blues Wireless Notecard - name: RTCZero @@ -170,6 +173,7 @@ jobs: # Install samd platform via Boards Manager - name: arduino:samd libraries: | + - name: ArduinoBearSSL - name: ArduinoECCX08 - name: Blues Wireless Notecard - name: RTCZero @@ -186,6 +190,7 @@ jobs: # Install mbed_portenta platform via Boards Manager - name: arduino:mbed_portenta libraries: | + - name: ArduinoBearSSL - name: ArduinoECCX08 - name: Arduino_Cellular - name: Blues Wireless Notecard @@ -214,6 +219,7 @@ jobs: # Install mbed_opta platform via Boards Manager - name: arduino:mbed_opta libraries: | + - name: ArduinoBearSSL - name: ArduinoECCX08 - name: Blues Wireless Notecard sketch-paths: | @@ -228,6 +234,7 @@ jobs: # Install mbed_giga platform via Boards Manager - name: arduino:mbed_giga libraries: | + - name: ArduinoBearSSL - name: ArduinoECCX08 - name: Blues Wireless Notecard sketch-paths: | diff --git a/examples/ArduinoIoTCloud-AWS-Basic/ArduinoIoTCloud-AWS-Basic.ino b/examples/ArduinoIoTCloud-AWS-Basic/ArduinoIoTCloud-AWS-Basic.ino new file mode 100644 index 000000000..3213a3bf8 --- /dev/null +++ b/examples/ArduinoIoTCloud-AWS-Basic/ArduinoIoTCloud-AWS-Basic.ino @@ -0,0 +1,151 @@ +#include "arduino_secrets.h" +/* + This sketch demonstrates how to connect to ArduinoIoTCloud and AWS IoT core. + + The full list of compatible boards can be found here: + - https://github.com/arduino-libraries/ArduinoIoTCloud#what +*/ + +#include "thingProperties.h" +#include "aws_secrets.h" + +Client& getDefaultClient() { + switch(ArduinoIoTPreferredConnection.getInterface()) { + +#ifdef BOARD_HAS_WIFI + case NetworkAdapter::WIFI: + static WiFiClient wclient; + return wclient; +#endif + +#ifdef BOARD_HAS_ETHERNET + case NetworkAdapter::ETHERNET: + static EthernetClient eclient; + return eclient; +#endif + + default: + Serial.println("Error: could not create default AWS client"); + break; + } +} + +unsigned long publishMillis = 0; +unsigned long connectMillis = 0; + +BearSSLClient sslClientAWS(getDefaultClient()); +MqttClient mqttClientAWS(sslClientAWS); + +void setup() { + /* Initialize serial and wait up to 5 seconds for port to open */ + Serial.begin(9600); + + /* Configure LED pin as an output */ + pinMode(LED_BUILTIN, OUTPUT); + + /* This function takes care of connecting your sketch variables to the ArduinoIoTCloud object */ + initProperties(); + + /* Initialize Arduino IoT Cloud library */ + ArduinoCloud.begin(ArduinoIoTPreferredConnection, true, "iot.arduino.cc"); + + setDebugMessageLevel(5); + ArduinoCloud.printDebugInfo(); + + /* Initialize AWS Client */ + ArduinoBearSSL.onGetTime(getTime); + sslClientAWS.setEccSlot(AWS_SLOT, AWS_CERTIFICATE); + + mqttClientAWS.setId("ArduinoAWSClient"); + mqttClientAWS.onMessage(onMessageReceived); + mqttClientAWS.setConnectionTimeout(10 * 1000); + mqttClientAWS.setKeepAliveInterval(30 * 1000); + mqttClientAWS.setCleanSession(false); +} + +void loop() { + ArduinoCloud.update(); + potentiometer = analogRead(A0); + seconds = millis() / 1000; + + if (!ArduinoCloud.connected()) { + return; + } + + if (!mqttClientAWS.connected()) { + if (millis() - connectMillis > 5000) { + connectMillis = millis(); + // MQTT client is disconnected, connect + if (!connectMQTT()) { + return; + } + } else { + return; + } + } + + // poll for new MQTT messages and send keep alive + mqttClientAWS.poll(); + + // publish a message roughly every 5 seconds. + if (millis() - publishMillis > 5000) { + publishMillis = millis(); + + publishMessage(); + } +} + +/* + * 'onLedChange' is called when the "led" property of your Thing changes + */ +void onLedChange() { + Serial.print("LED set to "); + Serial.println(led); + digitalWrite(LED_BUILTIN, led); +} + +void onMessageReceived(int messageSize) +{ + // we received a message, print out the topic and contents + Serial.print("Received a message with topic '"); + Serial.print(mqttClientAWS.messageTopic()); + Serial.print("', length "); + Serial.print(messageSize); + Serial.println(" bytes:"); + + for (int i = 0; i < messageSize; i++) { + const char c = mqttClientAWS.read(); + Serial.print(c); + } + Serial.println(); +} + +int connectMQTT() { + Serial.print("Attempting to connect to MQTT broker: "); + Serial.print(AWS_BROKER); + Serial.println(" "); + + if (!mqttClientAWS.connect(AWS_BROKER, 8883)) { + // failed, retry + Serial.print("."); + return 0; + } + Serial.println(); + + Serial.println("You're connected to the MQTT broker"); + Serial.println(); + + // subscribe to a topic + mqttClientAWS.subscribe("arduino/incoming"); + return 1; +} + +void publishMessage() { + Serial.println("Publishing message"); + + // send message, the Print interface can be used to set the message contents + mqttClientAWS.beginMessage("arduino/outgoing"); + mqttClientAWS.print("hello "); + mqttClientAWS.print(millis()); + mqttClientAWS.endMessage(); +} diff --git a/examples/ArduinoIoTCloud-AWS-Basic/arduino_secrets.h b/examples/ArduinoIoTCloud-AWS-Basic/arduino_secrets.h new file mode 100644 index 000000000..dee3e7210 --- /dev/null +++ b/examples/ArduinoIoTCloud-AWS-Basic/arduino_secrets.h @@ -0,0 +1,2 @@ +#define SECRET_SSID "" +#define SECRET_OPTIONAL_PASS "" diff --git a/examples/ArduinoIoTCloud-AWS-Basic/aws_secrets.h b/examples/ArduinoIoTCloud-AWS-Basic/aws_secrets.h new file mode 100644 index 000000000..07131d1da --- /dev/null +++ b/examples/ArduinoIoTCloud-AWS-Basic/aws_secrets.h @@ -0,0 +1,10 @@ +/* Fill in the hostname of your AWS IoT broker */ +#define AWS_BROKER "" + +#define AWS_SLOT 4 + +/* Fill in the boards public certificate */ +const char AWS_CERTIFICATE[] = R"( +-----BEGIN CERTIFICATE----- +-----END CERTIFICATE----- +)"; diff --git a/examples/ArduinoIoTCloud-AWS-Basic/thingProperties.h b/examples/ArduinoIoTCloud-AWS-Basic/thingProperties.h new file mode 100644 index 000000000..6717ea377 --- /dev/null +++ b/examples/ArduinoIoTCloud-AWS-Basic/thingProperties.h @@ -0,0 +1,21 @@ +// Code generated by Arduino IoT Cloud, DO NOT EDIT. + +#include +#include + +const char SSID[] = SECRET_SSID; // Network SSID (name) +const char PASS[] = SECRET_OPTIONAL_PASS; // Network password (use for WPA, or use as key for WEP) + +void onLedChange(); + +bool led; +int potentiometer; +int seconds; + +void initProperties() { + ArduinoCloud.addProperty(led, Permission::Write).onUpdate(onLedChange); + ArduinoCloud.addProperty(potentiometer, Permission::Read).publishOnChange(10); + ArduinoCloud.addProperty(seconds, Permission::Read).publishOnChange(1); +} + +WiFiConnectionHandler ArduinoIoTPreferredConnection(SECRET_SSID, SECRET_OPTIONAL_PASS); diff --git a/library.properties b/library.properties index 9435ba340..26f66f372 100644 --- a/library.properties +++ b/library.properties @@ -8,4 +8,5 @@ category=Communication url=https://github.com/arduino-libraries/ArduinoIoTCloud architectures=mbed,samd,esp8266,mbed_nano,mbed_portenta,mbed_nicla,esp32,mbed_opta,mbed_giga,renesas_portenta,renesas_uno,mbed_edge,stm32 includes=ArduinoIoTCloud.h -depends=Arduino_ConnectionHandler,Arduino_DebugUtils,Arduino_SecureElement,ArduinoMqttClient,ArduinoECCX08,RTCZero,Adafruit SleepyDog Library,ArduinoHttpClient,Arduino_CloudUtils +depends=Arduino_ConnectionHandler,Arduino_DebugUtils,Arduino_SecureElement,ArduinoMqttClient,ArduinoECCX08,RTCZero,Adafruit SleepyDog Library,ArduinoHttpClient,Arduino_CloudUtils,ArduinoBearSSL + diff --git a/src/AIoTC_Config.h b/src/AIoTC_Config.h index 779a4607f..4061cdd05 100644 --- a/src/AIoTC_Config.h +++ b/src/AIoTC_Config.h @@ -122,10 +122,6 @@ #define HAS_TCP #endif -#if defined(ARDUINO_NANO_RP2040_CONNECT) - #define BEAR_SSL_CLIENT_IBUF_SIZE (16384 + 325) // Allows download from storage API -#endif - #if defined(ARDUINO_EDGE_CONTROL) #define BOARD_HAS_SECRET_KEY #define HAS_TCP @@ -149,7 +145,6 @@ #endif // HAS_NOTECARD #if defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_NICLA_VISION) || defined(ARDUINO_OPTA) || defined(ARDUINO_GIGA) - #define BEAR_SSL_CLIENT_IBUF_SIZE (16384 + 325) // Allows download from storage API #define BOARD_STM32H7 #endif diff --git a/src/ArduinoBearSSLConfig.h b/src/ArduinoBearSSLConfig.h new file mode 100644 index 000000000..1d340d423 --- /dev/null +++ b/src/ArduinoBearSSLConfig.h @@ -0,0 +1,61 @@ +/* + This file is part of ArduinoIoTCloud. + + Copyright 2024 ARDUINO SA (http://www.arduino.cc/) + + This software is released under the GNU General Public License version 3, + which covers the main part of arduino-cli. + The terms of this license can be found at: + https://www.gnu.org/licenses/gpl-3.0.en.html + + You can be released from the requirements of the above licenses by purchasing + a commercial license. Buying such a license is mandatory if you want to modify or + otherwise use the software for commercial activities involving the Arduino + software without disclosing the source code of your own applications. To purchase + a commercial license, send an email to license@arduino.cc. +*/ + +#ifndef ARDUINO_BEARSSL_CONFIG_H_ +#define ARDUINO_BEARSSL_CONFIG_H_ + +/* Enabling this define allows the usage of ArduinoBearSSL without crypto chip. */ +//#define ARDUINO_DISABLE_ECCX08 + +/* Enable/Disable global instances*/ +#define ARDUINO_BEARSSL_DISABLE_AES128 +#define ARDUINO_BEARSSL_DISABLE_DES +#define ARDUINO_BEARSSL_DISABLE_MD5 +#define ARDUINO_BEARSSL_DISABLE_SHA1 +#define ARDUINO_BEARSSL_DISABLE_SHA256 + +#define ARDUINO_BEARSSL_DISABLE_KEY_DECODER + +/* If uncommented profile should be configured using client.setProfile(...) */ +//#define ARDUINO_BEARSSL_DISABLE_FULL_CLIENT_PROFILE + +/* If uncommented TA should be configured via constructor */ +//#define ARDUINO_BEARSSL_DISABLE_BUILTIN_TRUST_ANCHORS + +/* If uncommented disables br_sslio_close call.From BearSSL docs: + * + * br_sslio_close(): perform the SSL closure protocol. This entails sending a + * close_notify alert, and receiving a close_notify response. + * + * Note that a number of deployed SSL implementations do not follow the protocol + * for closure, and may drop the underlying socket abruptly. As such, errors are + * often reported by br_sslio_close(). + * + * In case of mbed-os + ArduinoIoTCloud br_sslio_close is endless looping + * blocking sketch execution. + */ +#define ARDUINO_BEARSSL_DISABLE_TLS_CLOSE + +#define BEAR_SSL_CLIENT_CHAIN_SIZE 1 + +#if defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_NICLA_VISION) || defined(ARDUINO_OPTA) ||\ + defined(ARDUINO_GIGA) || defined(ARDUINO_NANO_RP2040_CONNECT) + /* Allows download from OTA storage API */ + #define BEAR_SSL_CLIENT_IBUF_SIZE (16384 + 325) +#endif + +#endif /* ARDUINO_BEARSSL_CONFIG_H_ */ diff --git a/src/tls/BearSSLClient.cpp b/src/tls/BearSSLClient.cpp deleted file mode 100644 index 995718e93..000000000 --- a/src/tls/BearSSLClient.cpp +++ /dev/null @@ -1,415 +0,0 @@ -/* - * Copyright (c) 2018 Arduino SA. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include - -#include - -#include "BearSSLTrustAnchors.h" -#include "utility/eccX08_asn1.h" - -#include "BearSSLClient.h" - -extern "C" void aiotc_client_profile_init(br_ssl_client_context *cc, br_x509_minimal_context *xc, const br_x509_trust_anchor *trust_anchors, size_t trust_anchors_num); - -BearSSLClient::BearSSLClient() : - _noSNI(false), - _get_time_func(nullptr), - _sslio_closing(false) -{ - _ecKey.curve = 0; - _ecKey.x = NULL; - _ecKey.xlen = 0; - - _ecCert.data = NULL; - _ecCert.data_len = 0; - _ecCertDynamic = false; -} - -BearSSLClient::BearSSLClient(Client* client, const br_x509_trust_anchor* myTAs, int myNumTAs, GetTimeCallbackFunc func) : - _client(client), - _TAs(myTAs), - _numTAs(myNumTAs), - _noSNI(false), - _get_time_func(func), - _br_ssl_client_init_function(aiotc_client_profile_init) -{ - assert(_get_time_func != nullptr); - - _ecKey.curve = 0; - _ecKey.x = NULL; - _ecKey.xlen = 0; - - _ecCert.data = NULL; - _ecCert.data_len = 0; - _ecCertDynamic = false; -} - -BearSSLClient::~BearSSLClient() -{ - if (_ecCertDynamic && _ecCert.data) { - free(_ecCert.data); - _ecCert.data = NULL; - } -} - -int BearSSLClient::connect(IPAddress ip, uint16_t port) -{ - if (!_client->connect(ip, port)) { - return 0; - } - - return connectSSL(NULL); -} - -int BearSSLClient::connect(const char* host, uint16_t port) -{ - if (!_client->connect(host, port)) { - return 0; - } - - return connectSSL(_noSNI ? NULL : host); -} - -size_t BearSSLClient::write(uint8_t b) -{ - return write(&b, sizeof(b)); -} - -size_t BearSSLClient::write(const uint8_t *buf, size_t size) -{ - size_t written = 0; - - while (written < size) { - int result = br_sslio_write(&_ioc, buf, size - written); - - if (result < 0) { - break; - } - - buf += result; - written += result; - } - - if (written == size && br_sslio_flush(&_ioc) < 0) { - return 0; - } - - return written; -} - -int BearSSLClient::available() -{ - int available = br_sslio_read_available(&_ioc); - - if (available < 0) { - available = 0; - } - - return available; -} - -int BearSSLClient::read() -{ - byte b; - - if (read(&b, sizeof(b)) == sizeof(b)) { - return b; - } - - return -1; -} - -int BearSSLClient::read(uint8_t *buf, size_t size) -{ - return br_sslio_read(&_ioc, buf, size); -} - -int BearSSLClient::peek() -{ - byte b; - - if (br_sslio_peek(&_ioc, &b, sizeof(b)) == sizeof(b)) { - return b; - } - - return -1; -} - -void BearSSLClient::flush() -{ - br_sslio_flush(&_ioc); - - _client->flush(); -} - -void BearSSLClient::stop() -{ - if (_client->connected()) { - if ((br_ssl_engine_current_state(&_sc.eng) & BR_SSL_CLOSED) == 0) { - _sslio_closing = true; - br_sslio_close(&_ioc); - } - - _client->stop(); - } -} - -uint8_t BearSSLClient::connected() -{ - if (!_client->connected()) { - return 0; - } - - unsigned state = br_ssl_engine_current_state(&_sc.eng); - - if (state == BR_SSL_CLOSED) { - return 0; - } - - return 1; -} - -BearSSLClient::operator bool() -{ - return (*_client); -} - -void BearSSLClient::setInsecure(SNI insecure) -{ - switch (insecure) { - case SNI::Insecure : _noSNI = true; break; - default: _noSNI = false; - } -} - -void BearSSLClient::setEccSlot(int ecc508KeySlot, const byte cert[], int certLength) -{ - // HACK: put the key slot info. in the br_ec_private_key structure - _ecKey.curve = 23; - _ecKey.x = (unsigned char*)ecc508KeySlot; - _ecKey.xlen = 32; - - _ecCert.data = (unsigned char*)cert; - _ecCert.data_len = certLength; - _ecCertDynamic = false; -} - -void BearSSLClient::setEccSlot(int ecc508KeySlot, const char cert[]) -{ - // try to decode the cert - br_pem_decoder_context pemDecoder; - - size_t certLen = strlen(cert); - - // free old data - if (_ecCertDynamic && _ecCert.data) { - free(_ecCert.data); - _ecCert.data = NULL; - } - - // assume the decoded cert is 3/4 the length of the input - _ecCert.data = (unsigned char*)malloc(((certLen * 3) + 3) / 4); - _ecCert.data_len = 0; - - br_pem_decoder_init(&pemDecoder); - - while (certLen) { - size_t len = br_pem_decoder_push(&pemDecoder, cert, certLen); - - cert += len; - certLen -= len; - - switch (br_pem_decoder_event(&pemDecoder)) { - case BR_PEM_BEGIN_OBJ: - br_pem_decoder_setdest(&pemDecoder, BearSSLClient::clientAppendCert, this); - break; - - case BR_PEM_END_OBJ: - if (_ecCert.data_len) { - // done - setEccSlot(ecc508KeySlot, _ecCert.data, _ecCert.data_len); - _ecCertDynamic = true; - return; - } - break; - - case BR_PEM_ERROR: - // failure - free(_ecCert.data); - setEccSlot(ecc508KeySlot, NULL, 0); - return; - } - } -} - -int BearSSLClient::errorCode() -{ - return br_ssl_engine_last_error(&_sc.eng); -} - -int BearSSLClient::connectSSL(const char* host) -{ - /* Ensure this flag is cleared so we don't terminate a just starting connection. */ - _sslio_closing = false; - - // initialize client context with enabled algorithms and trust anchors - _br_ssl_client_init_function(&_sc, &_xc, _TAs, _numTAs); - - br_ssl_engine_set_buffers_bidi(&_sc.eng, _ibuf, sizeof(_ibuf), _obuf, sizeof(_obuf)); - - // inject entropy in engine - unsigned char entropy[32]; - - if (ECCX08.begin() && ECCX08.locked() && ECCX08.random(entropy, sizeof(entropy))) { - // ECC508 random success, add custom ECDSA vfry and EC sign - br_ssl_engine_set_ecdsa(&_sc.eng, eccX08_vrfy_asn1); - br_x509_minimal_set_ecdsa(&_xc, br_ssl_engine_get_ec(&_sc.eng), br_ssl_engine_get_ecdsa(&_sc.eng)); - - // enable client auth using the ECCX08 - if (_ecCert.data_len && _ecKey.xlen) { - br_ssl_client_set_single_ec(&_sc, &_ecCert, 1, &_ecKey, BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN, BR_KEYTYPE_EC, br_ec_get_default(), eccX08_sign_asn1); - } - } else { - // no ECCX08 or random failed, fallback to pseudo random - for (size_t i = 0; i < sizeof(entropy); i++) { - entropy[i] = random(0, 255); - } - } - br_ssl_engine_inject_entropy(&_sc.eng, entropy, sizeof(entropy)); - - // set the hostname used for SNI - br_ssl_client_reset(&_sc, host, 0); - - // get the current time and set it for X.509 validation - uint32_t now = _get_time_func(); - uint32_t days = now / 86400 + 719528; - uint32_t sec = now % 86400; - - br_x509_minimal_set_time(&_xc, days, sec); - - // use our own socket I/O operations - br_sslio_init(&_ioc, &_sc.eng, BearSSLClient::clientRead, this, BearSSLClient::clientWrite, this); - - br_sslio_flush(&_ioc); - - while (1) { - unsigned state = br_ssl_engine_current_state(&_sc.eng); - - if (state & BR_SSL_SENDAPP) { - break; - } else if (state & BR_SSL_CLOSED) { - return 0; - } - } - - return 1; -} - -// #define DEBUGSERIAL Serial - -int BearSSLClient::clientRead(void *ctx, unsigned char *buf, size_t len) -{ - BearSSLClient* bc = (BearSSLClient*)ctx; - Client* c = bc->_client; - - if(bc->_sslio_closing) { - return -1; - } - - if (!c->connected()) { - return -1; - } - - int result = c->read(buf, len); - if (result == -1) { - return 0; - } - -#ifdef DEBUGSERIAL - DEBUGSERIAL.print("BearSSLClient::clientRead - "); - DEBUGSERIAL.print(result); - DEBUGSERIAL.print(" - "); - for (size_t i = 0; i < result; i++) { - byte b = buf[i]; - - if (b < 16) { - DEBUGSERIAL.print("0"); - } - DEBUGSERIAL.print(b, HEX); - } - DEBUGSERIAL.println(); -#endif - - return result; -} - -int BearSSLClient::clientWrite(void *ctx, const unsigned char *buf, size_t len) -{ - BearSSLClient* bc = (BearSSLClient*)ctx; - Client* c = bc->_client; - - if(bc->_sslio_closing) { - return -1; - } - -#ifdef DEBUGSERIAL - DEBUGSERIAL.print("BearSSLClient::clientWrite - "); - DEBUGSERIAL.print(len); - DEBUGSERIAL.print(" - "); - for (size_t i = 0; i < len; i++) { - byte b = buf[i]; - - if (b < 16) { - DEBUGSERIAL.print("0"); - } - DEBUGSERIAL.print(b, HEX); - } - DEBUGSERIAL.println(); -#endif - - if (!c->connected()) { - return -1; - } - - int result = c->write(buf, len); - if (result == 0) { - return -1; - } - - return result; -} - -void BearSSLClient::clientAppendCert(void *ctx, const void *data, size_t len) -{ - BearSSLClient* c = (BearSSLClient*)ctx; - - memcpy(&c->_ecCert.data[c->_ecCert.data_len], data, len); - c->_ecCert.data_len += len; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/BearSSLClient.h b/src/tls/BearSSLClient.h deleted file mode 100644 index 32fb18727..000000000 --- a/src/tls/BearSSLClient.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2018 Arduino SA. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef _BEAR_SSL_CLIENT_H_ -#define _BEAR_SSL_CLIENT_H_ - -#include -#ifdef BOARD_HAS_ECCX08 - -#ifndef BEAR_SSL_CLIENT_OBUF_SIZE -#define BEAR_SSL_CLIENT_OBUF_SIZE 512 + 85 -#endif - -#ifndef BEAR_SSL_CLIENT_IBUF_SIZE -#define BEAR_SSL_CLIENT_IBUF_SIZE 8192 + 85 + 325 - BEAR_SSL_CLIENT_OBUF_SIZE -#endif - -#include -#include - -#include "bearssl/bearssl.h" - -typedef unsigned long(*GetTimeCallbackFunc)(); - -class BearSSLClient : public Client { - -public: - - BearSSLClient(Client* client, const br_x509_trust_anchor* myTAs, int myNumTAs, GetTimeCallbackFunc func); - BearSSLClient(); - virtual ~BearSSLClient(); - - - inline void setClient(Client& client) { _client = &client; } - inline void setProfile(void(*client_init_function)(br_ssl_client_context *cc, br_x509_minimal_context *xc, const br_x509_trust_anchor *trust_anchors, size_t trustrust_anchorst_anchors_num)) { _br_ssl_client_init_function = client_init_function; } - inline void setTrustAnchors(const br_x509_trust_anchor* myTAs, int myNumTAs) { _TAs = myTAs; _numTAs = myNumTAs; } - inline void onGetTime(GetTimeCallbackFunc callback) { _get_time_func = callback;} - - virtual int connect(IPAddress ip, uint16_t port); - virtual int connect(const char* host, uint16_t port); - virtual size_t write(uint8_t); - virtual size_t write(const uint8_t *buf, size_t size); - virtual int available(); - virtual int read(); - virtual int read(uint8_t *buf, size_t size); - virtual int peek(); - virtual void flush(); - virtual void stop(); - virtual uint8_t connected(); - virtual operator bool(); - - using Print::write; - - enum class SNI { - Insecure - }; - - void setInsecure(SNI insecure) __attribute__((deprecated("INSECURE. DO NOT USE IN PRODUCTION"))); - - void setEccSlot(int ecc508KeySlot, const byte cert[], int certLength); - void setEccSlot(int ecc508KeySlot, const char cert[]); - - int errorCode(); - -private: - int connectSSL(const char* host); - static int clientRead(void *ctx, unsigned char *buf, size_t len); - static int clientWrite(void *ctx, const unsigned char *buf, size_t len); - static void clientAppendCert(void *ctx, const void *data, size_t len); - -private: - Client* _client; - const br_x509_trust_anchor* _TAs; - int _numTAs; - bool _noSNI; - GetTimeCallbackFunc _get_time_func; - - br_ec_private_key _ecKey; - br_x509_certificate _ecCert; - bool _ecCertDynamic; - - /* FIXME By introducing _sslio_closing we are overriding the correct behaviour of SSL protocol - * where the client is require to correctly close the ssl session. In the way we use it - * we are blocking bearssl from sending any data on the underlying level, this fix requires - * further investigation in the bearssl code - */ - bool _sslio_closing; - br_ssl_client_context _sc; - br_x509_minimal_context _xc; - unsigned char _ibuf[BEAR_SSL_CLIENT_IBUF_SIZE]; - unsigned char _obuf[BEAR_SSL_CLIENT_OBUF_SIZE]; - br_sslio_context _ioc; - - void (*_br_ssl_client_init_function)(br_ssl_client_context *cc, br_x509_minimal_context *xc, const br_x509_trust_anchor *trust_anchors, size_t trust_anchors_num); -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ - -#endif diff --git a/src/tls/profile/aiotc_profile.c b/src/tls/BearSSLClientProfile.c similarity index 94% rename from src/tls/profile/aiotc_profile.c rename to src/tls/BearSSLClientProfile.c index e546b7577..cd787889f 100644 --- a/src/tls/profile/aiotc_profile.c +++ b/src/tls/BearSSLClientProfile.c @@ -22,10 +22,14 @@ * SOFTWARE. */ +/****************************************************************************** + * INCLUDE + ******************************************************************************/ + #include #ifdef BOARD_HAS_ECCX08 -#include "../bearssl/inner.h" +#include "bearssl/inner.h" /* see bearssl_ssl.h */ void aiotc_client_profile_init(br_ssl_client_context *cc, br_x509_minimal_context *xc, const br_x509_trust_anchor *trust_anchors, size_t trust_anchors_num) @@ -99,3 +103,4 @@ void aiotc_client_profile_init(br_ssl_client_context *cc, br_x509_minimal_contex } #endif /* #ifdef BOARD_HAS_ECCX08 */ + diff --git a/src/tls/bearssl/i32_add.c b/src/tls/BearSSLClientProfile.h similarity index 73% rename from src/tls/bearssl/i32_add.c rename to src/tls/BearSSLClientProfile.h index 20f2d2555..dbf9792db 100644 --- a/src/tls/bearssl/i32_add.c +++ b/src/tls/BearSSLClientProfile.h @@ -22,35 +22,19 @@ * SOFTWARE. */ -#include -#ifdef BOARD_HAS_ECCX08 +#ifndef _BEAR_SSL_CLIENT_PROFILE_H_ +#define _BEAR_SSL_CLIENT_PROFILE_H_ -#include "inner.h" +/****************************************************************************** + * INCLUDE + ******************************************************************************/ -/* see inner.h */ -uint32_t -br_i32_add(uint32_t *a, const uint32_t *b, uint32_t ctl) -{ - uint32_t cc; - size_t u, m; +#include +#ifdef BOARD_HAS_ECCX08 - cc = 0; - m = (a[0] + 63) >> 5; - for (u = 1; u < m; u ++) { - uint32_t aw, bw, naw; +extern "C" void aiotc_client_profile_init(br_ssl_client_context *cc, br_x509_minimal_context *xc, const br_x509_trust_anchor *trust_anchors, size_t trust_anchors_num); - aw = a[u]; - bw = b[u]; - naw = aw + bw + cc; +#endif /* #ifdef BOARD_HAS_ECCX08 */ - /* - * Carry is 1 if naw < aw. Carry is also 1 if naw == aw - * AND the carry was already 1. - */ - cc = (cc & EQ(naw, aw)) | LT(naw, aw); - a[u] = MUX(ctl, naw, aw); - } - return cc; -} +#endif /* _BEAR_SSL_CLIENT_PROFILE_H_ */ -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/LICENSE.txt b/src/tls/bearssl/LICENSE.txt deleted file mode 100644 index 088502032..000000000 --- a/src/tls/bearssl/LICENSE.txt +++ /dev/null @@ -1,21 +0,0 @@ -Copyright (c) 2016 Thomas Pornin - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/src/tls/bearssl/aes_big_cbcdec.c b/src/tls/bearssl/aes_big_cbcdec.c deleted file mode 100644 index ff7b693f8..000000000 --- a/src/tls/bearssl/aes_big_cbcdec.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_block.h */ -void -br_aes_big_cbcdec_init(br_aes_big_cbcdec_keys *ctx, - const void *key, size_t len) -{ - ctx->vtable = &br_aes_big_cbcdec_vtable; - ctx->num_rounds = br_aes_big_keysched_inv(ctx->skey, key, len); -} - -/* see bearssl_block.h */ -void -br_aes_big_cbcdec_run(const br_aes_big_cbcdec_keys *ctx, - void *iv, void *data, size_t len) -{ - unsigned char *buf, *ivbuf; - - ivbuf = iv; - buf = data; - while (len > 0) { - unsigned char tmp[16]; - int i; - - memcpy(tmp, buf, 16); - br_aes_big_decrypt(ctx->num_rounds, ctx->skey, buf); - for (i = 0; i < 16; i ++) { - buf[i] ^= ivbuf[i]; - } - memcpy(ivbuf, tmp, 16); - buf += 16; - len -= 16; - } -} - -/* see bearssl_block.h */ -const br_block_cbcdec_class br_aes_big_cbcdec_vtable = { - sizeof(br_aes_big_cbcdec_keys), - 16, - 4, - (void (*)(const br_block_cbcdec_class **, const void *, size_t)) - &br_aes_big_cbcdec_init, - (void (*)(const br_block_cbcdec_class *const *, void *, void *, size_t)) - &br_aes_big_cbcdec_run -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/aes_big_cbcenc.c b/src/tls/bearssl/aes_big_cbcenc.c deleted file mode 100644 index 6bdbac199..000000000 --- a/src/tls/bearssl/aes_big_cbcenc.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_block.h */ -void -br_aes_big_cbcenc_init(br_aes_big_cbcenc_keys *ctx, - const void *key, size_t len) -{ - ctx->vtable = &br_aes_big_cbcenc_vtable; - ctx->num_rounds = br_aes_keysched(ctx->skey, key, len); -} - -/* see bearssl_block.h */ -void -br_aes_big_cbcenc_run(const br_aes_big_cbcenc_keys *ctx, - void *iv, void *data, size_t len) -{ - unsigned char *buf, *ivbuf; - - ivbuf = iv; - buf = data; - while (len > 0) { - int i; - - for (i = 0; i < 16; i ++) { - buf[i] ^= ivbuf[i]; - } - br_aes_big_encrypt(ctx->num_rounds, ctx->skey, buf); - memcpy(ivbuf, buf, 16); - buf += 16; - len -= 16; - } -} - -/* see bearssl_block.h */ -const br_block_cbcenc_class br_aes_big_cbcenc_vtable = { - sizeof(br_aes_big_cbcenc_keys), - 16, - 4, - (void (*)(const br_block_cbcenc_class **, const void *, size_t)) - &br_aes_big_cbcenc_init, - (void (*)(const br_block_cbcenc_class *const *, void *, void *, size_t)) - &br_aes_big_cbcenc_run -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/aes_big_ctr.c b/src/tls/bearssl/aes_big_ctr.c deleted file mode 100644 index 965edc056..000000000 --- a/src/tls/bearssl/aes_big_ctr.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_block.h */ -void -br_aes_big_ctr_init(br_aes_big_ctr_keys *ctx, - const void *key, size_t len) -{ - ctx->vtable = &br_aes_big_ctr_vtable; - ctx->num_rounds = br_aes_keysched(ctx->skey, key, len); -} - -static void -xorbuf(void *dst, const void *src, size_t len) -{ - unsigned char *d; - const unsigned char *s; - - d = dst; - s = src; - while (len -- > 0) { - *d ++ ^= *s ++; - } -} - -/* see bearssl_block.h */ -uint32_t -br_aes_big_ctr_run(const br_aes_big_ctr_keys *ctx, - const void *iv, uint32_t cc, void *data, size_t len) -{ - unsigned char *buf; - - buf = data; - while (len > 0) { - unsigned char tmp[16]; - - memcpy(tmp, iv, 12); - br_enc32be(tmp + 12, cc ++); - br_aes_big_encrypt(ctx->num_rounds, ctx->skey, tmp); - if (len <= 16) { - xorbuf(buf, tmp, len); - break; - } - xorbuf(buf, tmp, 16); - buf += 16; - len -= 16; - } - return cc; -} - -/* see bearssl_block.h */ -const br_block_ctr_class br_aes_big_ctr_vtable = { - sizeof(br_aes_big_ctr_keys), - 16, - 4, - (void (*)(const br_block_ctr_class **, const void *, size_t)) - &br_aes_big_ctr_init, - (uint32_t (*)(const br_block_ctr_class *const *, - const void *, uint32_t, void *, size_t)) - &br_aes_big_ctr_run -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/aes_big_ctrcbc.c b/src/tls/bearssl/aes_big_ctrcbc.c deleted file mode 100644 index 28343e4a1..000000000 --- a/src/tls/bearssl/aes_big_ctrcbc.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_block.h */ -void -br_aes_big_ctrcbc_init(br_aes_big_ctrcbc_keys *ctx, - const void *key, size_t len) -{ - ctx->vtable = &br_aes_big_ctrcbc_vtable; - ctx->num_rounds = br_aes_keysched(ctx->skey, key, len); -} - -static void -xorbuf(void *dst, const void *src, size_t len) -{ - unsigned char *d; - const unsigned char *s; - - d = dst; - s = src; - while (len -- > 0) { - *d ++ ^= *s ++; - } -} - -/* see bearssl_block.h */ -void -br_aes_big_ctrcbc_ctr(const br_aes_big_ctrcbc_keys *ctx, - void *ctr, void *data, size_t len) -{ - unsigned char *buf, *bctr; - uint32_t cc0, cc1, cc2, cc3; - - buf = data; - bctr = ctr; - cc3 = br_dec32be(bctr + 0); - cc2 = br_dec32be(bctr + 4); - cc1 = br_dec32be(bctr + 8); - cc0 = br_dec32be(bctr + 12); - while (len > 0) { - unsigned char tmp[16]; - uint32_t carry; - - br_enc32be(tmp + 0, cc3); - br_enc32be(tmp + 4, cc2); - br_enc32be(tmp + 8, cc1); - br_enc32be(tmp + 12, cc0); - br_aes_big_encrypt(ctx->num_rounds, ctx->skey, tmp); - xorbuf(buf, tmp, 16); - buf += 16; - len -= 16; - cc0 ++; - carry = (~(cc0 | -cc0)) >> 31; - cc1 += carry; - carry &= (~(cc1 | -cc1)) >> 31; - cc2 += carry; - carry &= (~(cc2 | -cc2)) >> 31; - cc3 += carry; - } - br_enc32be(bctr + 0, cc3); - br_enc32be(bctr + 4, cc2); - br_enc32be(bctr + 8, cc1); - br_enc32be(bctr + 12, cc0); -} - -/* see bearssl_block.h */ -void -br_aes_big_ctrcbc_mac(const br_aes_big_ctrcbc_keys *ctx, - void *cbcmac, const void *data, size_t len) -{ - const unsigned char *buf; - - buf = data; - while (len > 0) { - xorbuf(cbcmac, buf, 16); - br_aes_big_encrypt(ctx->num_rounds, ctx->skey, cbcmac); - buf += 16; - len -= 16; - } -} - -/* see bearssl_block.h */ -void -br_aes_big_ctrcbc_encrypt(const br_aes_big_ctrcbc_keys *ctx, - void *ctr, void *cbcmac, void *data, size_t len) -{ - br_aes_big_ctrcbc_ctr(ctx, ctr, data, len); - br_aes_big_ctrcbc_mac(ctx, cbcmac, data, len); -} - -/* see bearssl_block.h */ -void -br_aes_big_ctrcbc_decrypt(const br_aes_big_ctrcbc_keys *ctx, - void *ctr, void *cbcmac, void *data, size_t len) -{ - br_aes_big_ctrcbc_mac(ctx, cbcmac, data, len); - br_aes_big_ctrcbc_ctr(ctx, ctr, data, len); -} - -/* see bearssl_block.h */ -const br_block_ctrcbc_class br_aes_big_ctrcbc_vtable = { - sizeof(br_aes_big_ctrcbc_keys), - 16, - 4, - (void (*)(const br_block_ctrcbc_class **, const void *, size_t)) - &br_aes_big_ctrcbc_init, - (void (*)(const br_block_ctrcbc_class *const *, - void *, void *, void *, size_t)) - &br_aes_big_ctrcbc_encrypt, - (void (*)(const br_block_ctrcbc_class *const *, - void *, void *, void *, size_t)) - &br_aes_big_ctrcbc_decrypt, - (void (*)(const br_block_ctrcbc_class *const *, - void *, void *, size_t)) - &br_aes_big_ctrcbc_ctr, - (void (*)(const br_block_ctrcbc_class *const *, - void *, const void *, size_t)) - &br_aes_big_ctrcbc_mac -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/aes_big_dec.c b/src/tls/bearssl/aes_big_dec.c deleted file mode 100644 index 3d407670b..000000000 --- a/src/tls/bearssl/aes_big_dec.c +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * Inverse S-box (used in key schedule for decryption). - */ -static const unsigned char iS[] = { - 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, - 0x81, 0xF3, 0xD7, 0xFB, 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, - 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 0x54, 0x7B, 0x94, 0x32, - 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, - 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, - 0x6D, 0x8B, 0xD1, 0x25, 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, - 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 0x6C, 0x70, 0x48, 0x50, - 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, - 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, - 0xB8, 0xB3, 0x45, 0x06, 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, - 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 0x3A, 0x91, 0x11, 0x41, - 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, - 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, - 0x1C, 0x75, 0xDF, 0x6E, 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, - 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 0xFC, 0x56, 0x3E, 0x4B, - 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, - 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, - 0x27, 0x80, 0xEC, 0x5F, 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, - 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 0xA0, 0xE0, 0x3B, 0x4D, - 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, - 0x55, 0x21, 0x0C, 0x7D -}; - -static const uint32_t iSsm0[] = { - 0x51F4A750, 0x7E416553, 0x1A17A4C3, 0x3A275E96, 0x3BAB6BCB, 0x1F9D45F1, - 0xACFA58AB, 0x4BE30393, 0x2030FA55, 0xAD766DF6, 0x88CC7691, 0xF5024C25, - 0x4FE5D7FC, 0xC52ACBD7, 0x26354480, 0xB562A38F, 0xDEB15A49, 0x25BA1B67, - 0x45EA0E98, 0x5DFEC0E1, 0xC32F7502, 0x814CF012, 0x8D4697A3, 0x6BD3F9C6, - 0x038F5FE7, 0x15929C95, 0xBF6D7AEB, 0x955259DA, 0xD4BE832D, 0x587421D3, - 0x49E06929, 0x8EC9C844, 0x75C2896A, 0xF48E7978, 0x99583E6B, 0x27B971DD, - 0xBEE14FB6, 0xF088AD17, 0xC920AC66, 0x7DCE3AB4, 0x63DF4A18, 0xE51A3182, - 0x97513360, 0x62537F45, 0xB16477E0, 0xBB6BAE84, 0xFE81A01C, 0xF9082B94, - 0x70486858, 0x8F45FD19, 0x94DE6C87, 0x527BF8B7, 0xAB73D323, 0x724B02E2, - 0xE31F8F57, 0x6655AB2A, 0xB2EB2807, 0x2FB5C203, 0x86C57B9A, 0xD33708A5, - 0x302887F2, 0x23BFA5B2, 0x02036ABA, 0xED16825C, 0x8ACF1C2B, 0xA779B492, - 0xF307F2F0, 0x4E69E2A1, 0x65DAF4CD, 0x0605BED5, 0xD134621F, 0xC4A6FE8A, - 0x342E539D, 0xA2F355A0, 0x058AE132, 0xA4F6EB75, 0x0B83EC39, 0x4060EFAA, - 0x5E719F06, 0xBD6E1051, 0x3E218AF9, 0x96DD063D, 0xDD3E05AE, 0x4DE6BD46, - 0x91548DB5, 0x71C45D05, 0x0406D46F, 0x605015FF, 0x1998FB24, 0xD6BDE997, - 0x894043CC, 0x67D99E77, 0xB0E842BD, 0x07898B88, 0xE7195B38, 0x79C8EEDB, - 0xA17C0A47, 0x7C420FE9, 0xF8841EC9, 0x00000000, 0x09808683, 0x322BED48, - 0x1E1170AC, 0x6C5A724E, 0xFD0EFFFB, 0x0F853856, 0x3DAED51E, 0x362D3927, - 0x0A0FD964, 0x685CA621, 0x9B5B54D1, 0x24362E3A, 0x0C0A67B1, 0x9357E70F, - 0xB4EE96D2, 0x1B9B919E, 0x80C0C54F, 0x61DC20A2, 0x5A774B69, 0x1C121A16, - 0xE293BA0A, 0xC0A02AE5, 0x3C22E043, 0x121B171D, 0x0E090D0B, 0xF28BC7AD, - 0x2DB6A8B9, 0x141EA9C8, 0x57F11985, 0xAF75074C, 0xEE99DDBB, 0xA37F60FD, - 0xF701269F, 0x5C72F5BC, 0x44663BC5, 0x5BFB7E34, 0x8B432976, 0xCB23C6DC, - 0xB6EDFC68, 0xB8E4F163, 0xD731DCCA, 0x42638510, 0x13972240, 0x84C61120, - 0x854A247D, 0xD2BB3DF8, 0xAEF93211, 0xC729A16D, 0x1D9E2F4B, 0xDCB230F3, - 0x0D8652EC, 0x77C1E3D0, 0x2BB3166C, 0xA970B999, 0x119448FA, 0x47E96422, - 0xA8FC8CC4, 0xA0F03F1A, 0x567D2CD8, 0x223390EF, 0x87494EC7, 0xD938D1C1, - 0x8CCAA2FE, 0x98D40B36, 0xA6F581CF, 0xA57ADE28, 0xDAB78E26, 0x3FADBFA4, - 0x2C3A9DE4, 0x5078920D, 0x6A5FCC9B, 0x547E4662, 0xF68D13C2, 0x90D8B8E8, - 0x2E39F75E, 0x82C3AFF5, 0x9F5D80BE, 0x69D0937C, 0x6FD52DA9, 0xCF2512B3, - 0xC8AC993B, 0x10187DA7, 0xE89C636E, 0xDB3BBB7B, 0xCD267809, 0x6E5918F4, - 0xEC9AB701, 0x834F9AA8, 0xE6956E65, 0xAAFFE67E, 0x21BCCF08, 0xEF15E8E6, - 0xBAE79BD9, 0x4A6F36CE, 0xEA9F09D4, 0x29B07CD6, 0x31A4B2AF, 0x2A3F2331, - 0xC6A59430, 0x35A266C0, 0x744EBC37, 0xFC82CAA6, 0xE090D0B0, 0x33A7D815, - 0xF104984A, 0x41ECDAF7, 0x7FCD500E, 0x1791F62F, 0x764DD68D, 0x43EFB04D, - 0xCCAA4D54, 0xE49604DF, 0x9ED1B5E3, 0x4C6A881B, 0xC12C1FB8, 0x4665517F, - 0x9D5EEA04, 0x018C355D, 0xFA877473, 0xFB0B412E, 0xB3671D5A, 0x92DBD252, - 0xE9105633, 0x6DD64713, 0x9AD7618C, 0x37A10C7A, 0x59F8148E, 0xEB133C89, - 0xCEA927EE, 0xB761C935, 0xE11CE5ED, 0x7A47B13C, 0x9CD2DF59, 0x55F2733F, - 0x1814CE79, 0x73C737BF, 0x53F7CDEA, 0x5FFDAA5B, 0xDF3D6F14, 0x7844DB86, - 0xCAAFF381, 0xB968C43E, 0x3824342C, 0xC2A3405F, 0x161DC372, 0xBCE2250C, - 0x283C498B, 0xFF0D9541, 0x39A80171, 0x080CB3DE, 0xD8B4E49C, 0x6456C190, - 0x7BCB8461, 0xD532B670, 0x486C5C74, 0xD0B85742 -}; - -static unsigned -mul2(unsigned x) -{ - x <<= 1; - return x ^ ((unsigned)(-(int)(x >> 8)) & 0x11B); -} - -static unsigned -mul9(unsigned x) -{ - return x ^ mul2(mul2(mul2(x))); -} - -static unsigned -mulb(unsigned x) -{ - unsigned x2; - - x2 = mul2(x); - return x ^ x2 ^ mul2(mul2(x2)); -} - -static unsigned -muld(unsigned x) -{ - unsigned x4; - - x4 = mul2(mul2(x)); - return x ^ x4 ^ mul2(x4); -} - -static unsigned -mule(unsigned x) -{ - unsigned x2, x4; - - x2 = mul2(x); - x4 = mul2(x2); - return x2 ^ x4 ^ mul2(x4); -} - -/* see inner.h */ -unsigned -br_aes_big_keysched_inv(uint32_t *skey, const void *key, size_t key_len) -{ - unsigned num_rounds; - int i, m; - - /* - * Sub-keys for decryption are distinct from encryption sub-keys - * in that InvMixColumns() is already applied for the inner - * rounds. - */ - num_rounds = br_aes_keysched(skey, key, key_len); - m = (int)(num_rounds << 2); - for (i = 4; i < m; i ++) { - uint32_t p; - unsigned p0, p1, p2, p3; - uint32_t q0, q1, q2, q3; - - p = skey[i]; - p0 = p >> 24; - p1 = (p >> 16) & 0xFF; - p2 = (p >> 8) & 0xFF; - p3 = p & 0xFF; - q0 = mule(p0) ^ mulb(p1) ^ muld(p2) ^ mul9(p3); - q1 = mul9(p0) ^ mule(p1) ^ mulb(p2) ^ muld(p3); - q2 = muld(p0) ^ mul9(p1) ^ mule(p2) ^ mulb(p3); - q3 = mulb(p0) ^ muld(p1) ^ mul9(p2) ^ mule(p3); - skey[i] = (q0 << 24) | (q1 << 16) | (q2 << 8) | q3; - } - return num_rounds; -} - -static inline uint32_t -rotr(uint32_t x, int n) -{ - return (x << (32 - n)) | (x >> n); -} - -#define iSboxExt0(x) (iSsm0[x]) -#define iSboxExt1(x) (rotr(iSsm0[x], 8)) -#define iSboxExt2(x) (rotr(iSsm0[x], 16)) -#define iSboxExt3(x) (rotr(iSsm0[x], 24)) - -/* see bearssl.h */ -void -br_aes_big_decrypt(unsigned num_rounds, const uint32_t *skey, void *data) -{ - unsigned char *buf; - uint32_t s0, s1, s2, s3; - uint32_t t0, t1, t2, t3; - unsigned u; - - buf = data; - s0 = br_dec32be(buf); - s1 = br_dec32be(buf + 4); - s2 = br_dec32be(buf + 8); - s3 = br_dec32be(buf + 12); - s0 ^= skey[(num_rounds << 2) + 0]; - s1 ^= skey[(num_rounds << 2) + 1]; - s2 ^= skey[(num_rounds << 2) + 2]; - s3 ^= skey[(num_rounds << 2) + 3]; - for (u = num_rounds - 1; u > 0; u --) { - uint32_t v0 = iSboxExt0(s0 >> 24) - ^ iSboxExt1((s3 >> 16) & 0xFF) - ^ iSboxExt2((s2 >> 8) & 0xFF) - ^ iSboxExt3(s1 & 0xFF); - uint32_t v1 = iSboxExt0(s1 >> 24) - ^ iSboxExt1((s0 >> 16) & 0xFF) - ^ iSboxExt2((s3 >> 8) & 0xFF) - ^ iSboxExt3(s2 & 0xFF); - uint32_t v2 = iSboxExt0(s2 >> 24) - ^ iSboxExt1((s1 >> 16) & 0xFF) - ^ iSboxExt2((s0 >> 8) & 0xFF) - ^ iSboxExt3(s3 & 0xFF); - uint32_t v3 = iSboxExt0(s3 >> 24) - ^ iSboxExt1((s2 >> 16) & 0xFF) - ^ iSboxExt2((s1 >> 8) & 0xFF) - ^ iSboxExt3(s0 & 0xFF); - s0 = v0; - s1 = v1; - s2 = v2; - s3 = v3; - s0 ^= skey[u << 2]; - s1 ^= skey[(u << 2) + 1]; - s2 ^= skey[(u << 2) + 2]; - s3 ^= skey[(u << 2) + 3]; - } - t0 = ((uint32_t)iS[s0 >> 24] << 24) - | ((uint32_t)iS[(s3 >> 16) & 0xFF] << 16) - | ((uint32_t)iS[(s2 >> 8) & 0xFF] << 8) - | (uint32_t)iS[s1 & 0xFF]; - t1 = ((uint32_t)iS[s1 >> 24] << 24) - | ((uint32_t)iS[(s0 >> 16) & 0xFF] << 16) - | ((uint32_t)iS[(s3 >> 8) & 0xFF] << 8) - | (uint32_t)iS[s2 & 0xFF]; - t2 = ((uint32_t)iS[s2 >> 24] << 24) - | ((uint32_t)iS[(s1 >> 16) & 0xFF] << 16) - | ((uint32_t)iS[(s0 >> 8) & 0xFF] << 8) - | (uint32_t)iS[s3 & 0xFF]; - t3 = ((uint32_t)iS[s3 >> 24] << 24) - | ((uint32_t)iS[(s2 >> 16) & 0xFF] << 16) - | ((uint32_t)iS[(s1 >> 8) & 0xFF] << 8) - | (uint32_t)iS[s0 & 0xFF]; - s0 = t0 ^ skey[0]; - s1 = t1 ^ skey[1]; - s2 = t2 ^ skey[2]; - s3 = t3 ^ skey[3]; - br_enc32be(buf, s0); - br_enc32be(buf + 4, s1); - br_enc32be(buf + 8, s2); - br_enc32be(buf + 12, s3); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/aes_big_enc.c b/src/tls/bearssl/aes_big_enc.c deleted file mode 100644 index 1d5a690a2..000000000 --- a/src/tls/bearssl/aes_big_enc.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -#define S br_aes_S - -static const uint32_t Ssm0[] = { - 0xC66363A5, 0xF87C7C84, 0xEE777799, 0xF67B7B8D, 0xFFF2F20D, 0xD66B6BBD, - 0xDE6F6FB1, 0x91C5C554, 0x60303050, 0x02010103, 0xCE6767A9, 0x562B2B7D, - 0xE7FEFE19, 0xB5D7D762, 0x4DABABE6, 0xEC76769A, 0x8FCACA45, 0x1F82829D, - 0x89C9C940, 0xFA7D7D87, 0xEFFAFA15, 0xB25959EB, 0x8E4747C9, 0xFBF0F00B, - 0x41ADADEC, 0xB3D4D467, 0x5FA2A2FD, 0x45AFAFEA, 0x239C9CBF, 0x53A4A4F7, - 0xE4727296, 0x9BC0C05B, 0x75B7B7C2, 0xE1FDFD1C, 0x3D9393AE, 0x4C26266A, - 0x6C36365A, 0x7E3F3F41, 0xF5F7F702, 0x83CCCC4F, 0x6834345C, 0x51A5A5F4, - 0xD1E5E534, 0xF9F1F108, 0xE2717193, 0xABD8D873, 0x62313153, 0x2A15153F, - 0x0804040C, 0x95C7C752, 0x46232365, 0x9DC3C35E, 0x30181828, 0x379696A1, - 0x0A05050F, 0x2F9A9AB5, 0x0E070709, 0x24121236, 0x1B80809B, 0xDFE2E23D, - 0xCDEBEB26, 0x4E272769, 0x7FB2B2CD, 0xEA75759F, 0x1209091B, 0x1D83839E, - 0x582C2C74, 0x341A1A2E, 0x361B1B2D, 0xDC6E6EB2, 0xB45A5AEE, 0x5BA0A0FB, - 0xA45252F6, 0x763B3B4D, 0xB7D6D661, 0x7DB3B3CE, 0x5229297B, 0xDDE3E33E, - 0x5E2F2F71, 0x13848497, 0xA65353F5, 0xB9D1D168, 0x00000000, 0xC1EDED2C, - 0x40202060, 0xE3FCFC1F, 0x79B1B1C8, 0xB65B5BED, 0xD46A6ABE, 0x8DCBCB46, - 0x67BEBED9, 0x7239394B, 0x944A4ADE, 0x984C4CD4, 0xB05858E8, 0x85CFCF4A, - 0xBBD0D06B, 0xC5EFEF2A, 0x4FAAAAE5, 0xEDFBFB16, 0x864343C5, 0x9A4D4DD7, - 0x66333355, 0x11858594, 0x8A4545CF, 0xE9F9F910, 0x04020206, 0xFE7F7F81, - 0xA05050F0, 0x783C3C44, 0x259F9FBA, 0x4BA8A8E3, 0xA25151F3, 0x5DA3A3FE, - 0x804040C0, 0x058F8F8A, 0x3F9292AD, 0x219D9DBC, 0x70383848, 0xF1F5F504, - 0x63BCBCDF, 0x77B6B6C1, 0xAFDADA75, 0x42212163, 0x20101030, 0xE5FFFF1A, - 0xFDF3F30E, 0xBFD2D26D, 0x81CDCD4C, 0x180C0C14, 0x26131335, 0xC3ECEC2F, - 0xBE5F5FE1, 0x359797A2, 0x884444CC, 0x2E171739, 0x93C4C457, 0x55A7A7F2, - 0xFC7E7E82, 0x7A3D3D47, 0xC86464AC, 0xBA5D5DE7, 0x3219192B, 0xE6737395, - 0xC06060A0, 0x19818198, 0x9E4F4FD1, 0xA3DCDC7F, 0x44222266, 0x542A2A7E, - 0x3B9090AB, 0x0B888883, 0x8C4646CA, 0xC7EEEE29, 0x6BB8B8D3, 0x2814143C, - 0xA7DEDE79, 0xBC5E5EE2, 0x160B0B1D, 0xADDBDB76, 0xDBE0E03B, 0x64323256, - 0x743A3A4E, 0x140A0A1E, 0x924949DB, 0x0C06060A, 0x4824246C, 0xB85C5CE4, - 0x9FC2C25D, 0xBDD3D36E, 0x43ACACEF, 0xC46262A6, 0x399191A8, 0x319595A4, - 0xD3E4E437, 0xF279798B, 0xD5E7E732, 0x8BC8C843, 0x6E373759, 0xDA6D6DB7, - 0x018D8D8C, 0xB1D5D564, 0x9C4E4ED2, 0x49A9A9E0, 0xD86C6CB4, 0xAC5656FA, - 0xF3F4F407, 0xCFEAEA25, 0xCA6565AF, 0xF47A7A8E, 0x47AEAEE9, 0x10080818, - 0x6FBABAD5, 0xF0787888, 0x4A25256F, 0x5C2E2E72, 0x381C1C24, 0x57A6A6F1, - 0x73B4B4C7, 0x97C6C651, 0xCBE8E823, 0xA1DDDD7C, 0xE874749C, 0x3E1F1F21, - 0x964B4BDD, 0x61BDBDDC, 0x0D8B8B86, 0x0F8A8A85, 0xE0707090, 0x7C3E3E42, - 0x71B5B5C4, 0xCC6666AA, 0x904848D8, 0x06030305, 0xF7F6F601, 0x1C0E0E12, - 0xC26161A3, 0x6A35355F, 0xAE5757F9, 0x69B9B9D0, 0x17868691, 0x99C1C158, - 0x3A1D1D27, 0x279E9EB9, 0xD9E1E138, 0xEBF8F813, 0x2B9898B3, 0x22111133, - 0xD26969BB, 0xA9D9D970, 0x078E8E89, 0x339494A7, 0x2D9B9BB6, 0x3C1E1E22, - 0x15878792, 0xC9E9E920, 0x87CECE49, 0xAA5555FF, 0x50282878, 0xA5DFDF7A, - 0x038C8C8F, 0x59A1A1F8, 0x09898980, 0x1A0D0D17, 0x65BFBFDA, 0xD7E6E631, - 0x844242C6, 0xD06868B8, 0x824141C3, 0x299999B0, 0x5A2D2D77, 0x1E0F0F11, - 0x7BB0B0CB, 0xA85454FC, 0x6DBBBBD6, 0x2C16163A -}; - -static inline uint32_t -rotr(uint32_t x, int n) -{ - return (x << (32 - n)) | (x >> n); -} - -#define SboxExt0(x) (Ssm0[x]) -#define SboxExt1(x) (rotr(Ssm0[x], 8)) -#define SboxExt2(x) (rotr(Ssm0[x], 16)) -#define SboxExt3(x) (rotr(Ssm0[x], 24)) - - -/* see bearssl.h */ -void -br_aes_big_encrypt(unsigned num_rounds, const uint32_t *skey, void *data) -{ - unsigned char *buf; - uint32_t s0, s1, s2, s3; - uint32_t t0, t1, t2, t3; - unsigned u; - - buf = data; - s0 = br_dec32be(buf); - s1 = br_dec32be(buf + 4); - s2 = br_dec32be(buf + 8); - s3 = br_dec32be(buf + 12); - s0 ^= skey[0]; - s1 ^= skey[1]; - s2 ^= skey[2]; - s3 ^= skey[3]; - for (u = 1; u < num_rounds; u ++) { - uint32_t v0, v1, v2, v3; - - v0 = SboxExt0(s0 >> 24) - ^ SboxExt1((s1 >> 16) & 0xFF) - ^ SboxExt2((s2 >> 8) & 0xFF) - ^ SboxExt3(s3 & 0xFF); - v1 = SboxExt0(s1 >> 24) - ^ SboxExt1((s2 >> 16) & 0xFF) - ^ SboxExt2((s3 >> 8) & 0xFF) - ^ SboxExt3(s0 & 0xFF); - v2 = SboxExt0(s2 >> 24) - ^ SboxExt1((s3 >> 16) & 0xFF) - ^ SboxExt2((s0 >> 8) & 0xFF) - ^ SboxExt3(s1 & 0xFF); - v3 = SboxExt0(s3 >> 24) - ^ SboxExt1((s0 >> 16) & 0xFF) - ^ SboxExt2((s1 >> 8) & 0xFF) - ^ SboxExt3(s2 & 0xFF); - s0 = v0; - s1 = v1; - s2 = v2; - s3 = v3; - s0 ^= skey[u << 2]; - s1 ^= skey[(u << 2) + 1]; - s2 ^= skey[(u << 2) + 2]; - s3 ^= skey[(u << 2) + 3]; - } - t0 = ((uint32_t)S[s0 >> 24] << 24) - | ((uint32_t)S[(s1 >> 16) & 0xFF] << 16) - | ((uint32_t)S[(s2 >> 8) & 0xFF] << 8) - | (uint32_t)S[s3 & 0xFF]; - t1 = ((uint32_t)S[s1 >> 24] << 24) - | ((uint32_t)S[(s2 >> 16) & 0xFF] << 16) - | ((uint32_t)S[(s3 >> 8) & 0xFF] << 8) - | (uint32_t)S[s0 & 0xFF]; - t2 = ((uint32_t)S[s2 >> 24] << 24) - | ((uint32_t)S[(s3 >> 16) & 0xFF] << 16) - | ((uint32_t)S[(s0 >> 8) & 0xFF] << 8) - | (uint32_t)S[s1 & 0xFF]; - t3 = ((uint32_t)S[s3 >> 24] << 24) - | ((uint32_t)S[(s0 >> 16) & 0xFF] << 16) - | ((uint32_t)S[(s1 >> 8) & 0xFF] << 8) - | (uint32_t)S[s2 & 0xFF]; - s0 = t0 ^ skey[num_rounds << 2]; - s1 = t1 ^ skey[(num_rounds << 2) + 1]; - s2 = t2 ^ skey[(num_rounds << 2) + 2]; - s3 = t3 ^ skey[(num_rounds << 2) + 3]; - br_enc32be(buf, s0); - br_enc32be(buf + 4, s1); - br_enc32be(buf + 8, s2); - br_enc32be(buf + 12, s3); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/aes_common.c b/src/tls/bearssl/aes_common.c deleted file mode 100644 index 485bb1a22..000000000 --- a/src/tls/bearssl/aes_common.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -static const uint32_t Rcon[] = { - 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, - 0x40000000, 0x80000000, 0x1B000000, 0x36000000 -}; - -#define S br_aes_S - -/* see inner.h */ -const unsigned char br_aes_S[] = { - 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, - 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, - 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, - 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, - 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, - 0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, - 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED, - 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, - 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, - 0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, - 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC, - 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, - 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, - 0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, - 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D, - 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, - 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, - 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, - 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, - 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, - 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, - 0xB0, 0x54, 0xBB, 0x16 -}; - -static uint32_t -SubWord(uint32_t x) -{ - return ((uint32_t)S[x >> 24] << 24) - | ((uint32_t)S[(x >> 16) & 0xFF] << 16) - | ((uint32_t)S[(x >> 8) & 0xFF] << 8) - | (uint32_t)S[x & 0xFF]; -} - -/* see inner.h */ -unsigned -br_aes_keysched(uint32_t *skey, const void *key, size_t key_len) -{ - unsigned num_rounds; - int i, j, k, nk, nkf; - - switch (key_len) { - case 16: - num_rounds = 10; - break; - case 24: - num_rounds = 12; - break; - case 32: - num_rounds = 14; - break; - default: - /* abort(); */ - return 0; - } - nk = (int)(key_len >> 2); - nkf = (int)((num_rounds + 1) << 2); - for (i = 0; i < nk; i ++) { - skey[i] = br_dec32be((const unsigned char *)key + (i << 2)); - } - for (i = nk, j = 0, k = 0; i < nkf; i ++) { - uint32_t tmp; - - tmp = skey[i - 1]; - if (j == 0) { - tmp = (tmp << 8) | (tmp >> 24); - tmp = SubWord(tmp) ^ Rcon[k]; - } else if (nk > 6 && j == 4) { - tmp = SubWord(tmp); - } - skey[i] = skey[i - nk] ^ tmp; - if (++ j == nk) { - j = 0; - k ++; - } - } - return num_rounds; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/aes_ct.c b/src/tls/bearssl/aes_ct.c deleted file mode 100644 index 6e5ac5598..000000000 --- a/src/tls/bearssl/aes_ct.c +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_aes_ct_bitslice_Sbox(uint32_t *q) -{ - /* - * This S-box implementation is a straightforward translation of - * the circuit described by Boyar and Peralta in "A new - * combinational logic minimization technique with applications - * to cryptology" (https://eprint.iacr.org/2009/191.pdf). - * - * Note that variables x* (input) and s* (output) are numbered - * in "reverse" order (x0 is the high bit, x7 is the low bit). - */ - - uint32_t x0, x1, x2, x3, x4, x5, x6, x7; - uint32_t y1, y2, y3, y4, y5, y6, y7, y8, y9; - uint32_t y10, y11, y12, y13, y14, y15, y16, y17, y18, y19; - uint32_t y20, y21; - uint32_t z0, z1, z2, z3, z4, z5, z6, z7, z8, z9; - uint32_t z10, z11, z12, z13, z14, z15, z16, z17; - uint32_t t0, t1, t2, t3, t4, t5, t6, t7, t8, t9; - uint32_t t10, t11, t12, t13, t14, t15, t16, t17, t18, t19; - uint32_t t20, t21, t22, t23, t24, t25, t26, t27, t28, t29; - uint32_t t30, t31, t32, t33, t34, t35, t36, t37, t38, t39; - uint32_t t40, t41, t42, t43, t44, t45, t46, t47, t48, t49; - uint32_t t50, t51, t52, t53, t54, t55, t56, t57, t58, t59; - uint32_t t60, t61, t62, t63, t64, t65, t66, t67; - uint32_t s0, s1, s2, s3, s4, s5, s6, s7; - - x0 = q[7]; - x1 = q[6]; - x2 = q[5]; - x3 = q[4]; - x4 = q[3]; - x5 = q[2]; - x6 = q[1]; - x7 = q[0]; - - /* - * Top linear transformation. - */ - y14 = x3 ^ x5; - y13 = x0 ^ x6; - y9 = x0 ^ x3; - y8 = x0 ^ x5; - t0 = x1 ^ x2; - y1 = t0 ^ x7; - y4 = y1 ^ x3; - y12 = y13 ^ y14; - y2 = y1 ^ x0; - y5 = y1 ^ x6; - y3 = y5 ^ y8; - t1 = x4 ^ y12; - y15 = t1 ^ x5; - y20 = t1 ^ x1; - y6 = y15 ^ x7; - y10 = y15 ^ t0; - y11 = y20 ^ y9; - y7 = x7 ^ y11; - y17 = y10 ^ y11; - y19 = y10 ^ y8; - y16 = t0 ^ y11; - y21 = y13 ^ y16; - y18 = x0 ^ y16; - - /* - * Non-linear section. - */ - t2 = y12 & y15; - t3 = y3 & y6; - t4 = t3 ^ t2; - t5 = y4 & x7; - t6 = t5 ^ t2; - t7 = y13 & y16; - t8 = y5 & y1; - t9 = t8 ^ t7; - t10 = y2 & y7; - t11 = t10 ^ t7; - t12 = y9 & y11; - t13 = y14 & y17; - t14 = t13 ^ t12; - t15 = y8 & y10; - t16 = t15 ^ t12; - t17 = t4 ^ t14; - t18 = t6 ^ t16; - t19 = t9 ^ t14; - t20 = t11 ^ t16; - t21 = t17 ^ y20; - t22 = t18 ^ y19; - t23 = t19 ^ y21; - t24 = t20 ^ y18; - - t25 = t21 ^ t22; - t26 = t21 & t23; - t27 = t24 ^ t26; - t28 = t25 & t27; - t29 = t28 ^ t22; - t30 = t23 ^ t24; - t31 = t22 ^ t26; - t32 = t31 & t30; - t33 = t32 ^ t24; - t34 = t23 ^ t33; - t35 = t27 ^ t33; - t36 = t24 & t35; - t37 = t36 ^ t34; - t38 = t27 ^ t36; - t39 = t29 & t38; - t40 = t25 ^ t39; - - t41 = t40 ^ t37; - t42 = t29 ^ t33; - t43 = t29 ^ t40; - t44 = t33 ^ t37; - t45 = t42 ^ t41; - z0 = t44 & y15; - z1 = t37 & y6; - z2 = t33 & x7; - z3 = t43 & y16; - z4 = t40 & y1; - z5 = t29 & y7; - z6 = t42 & y11; - z7 = t45 & y17; - z8 = t41 & y10; - z9 = t44 & y12; - z10 = t37 & y3; - z11 = t33 & y4; - z12 = t43 & y13; - z13 = t40 & y5; - z14 = t29 & y2; - z15 = t42 & y9; - z16 = t45 & y14; - z17 = t41 & y8; - - /* - * Bottom linear transformation. - */ - t46 = z15 ^ z16; - t47 = z10 ^ z11; - t48 = z5 ^ z13; - t49 = z9 ^ z10; - t50 = z2 ^ z12; - t51 = z2 ^ z5; - t52 = z7 ^ z8; - t53 = z0 ^ z3; - t54 = z6 ^ z7; - t55 = z16 ^ z17; - t56 = z12 ^ t48; - t57 = t50 ^ t53; - t58 = z4 ^ t46; - t59 = z3 ^ t54; - t60 = t46 ^ t57; - t61 = z14 ^ t57; - t62 = t52 ^ t58; - t63 = t49 ^ t58; - t64 = z4 ^ t59; - t65 = t61 ^ t62; - t66 = z1 ^ t63; - s0 = t59 ^ t63; - s6 = t56 ^ ~t62; - s7 = t48 ^ ~t60; - t67 = t64 ^ t65; - s3 = t53 ^ t66; - s4 = t51 ^ t66; - s5 = t47 ^ t65; - s1 = t64 ^ ~s3; - s2 = t55 ^ ~t67; - - q[7] = s0; - q[6] = s1; - q[5] = s2; - q[4] = s3; - q[3] = s4; - q[2] = s5; - q[1] = s6; - q[0] = s7; -} - -/* see inner.h */ -void -br_aes_ct_ortho(uint32_t *q) -{ -#define SWAPN(cl, ch, s, x, y) do { \ - uint32_t a, b; \ - a = (x); \ - b = (y); \ - (x) = (a & (uint32_t)cl) | ((b & (uint32_t)cl) << (s)); \ - (y) = ((a & (uint32_t)ch) >> (s)) | (b & (uint32_t)ch); \ - } while (0) - -#define SWAP2(x, y) SWAPN(0x55555555, 0xAAAAAAAA, 1, x, y) -#define SWAP4(x, y) SWAPN(0x33333333, 0xCCCCCCCC, 2, x, y) -#define SWAP8(x, y) SWAPN(0x0F0F0F0F, 0xF0F0F0F0, 4, x, y) - - SWAP2(q[0], q[1]); - SWAP2(q[2], q[3]); - SWAP2(q[4], q[5]); - SWAP2(q[6], q[7]); - - SWAP4(q[0], q[2]); - SWAP4(q[1], q[3]); - SWAP4(q[4], q[6]); - SWAP4(q[5], q[7]); - - SWAP8(q[0], q[4]); - SWAP8(q[1], q[5]); - SWAP8(q[2], q[6]); - SWAP8(q[3], q[7]); -} - -static const unsigned char Rcon[] = { - 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36 -}; - -static uint32_t -sub_word(uint32_t x) -{ - uint32_t q[8]; - int i; - - for (i = 0; i < 8; i ++) { - q[i] = x; - } - br_aes_ct_ortho(q); - br_aes_ct_bitslice_Sbox(q); - br_aes_ct_ortho(q); - return q[0]; -} - -/* see inner.h */ -unsigned -br_aes_ct_keysched(uint32_t *comp_skey, const void *key, size_t key_len) -{ - unsigned num_rounds; - int i, j, k, nk, nkf; - uint32_t tmp; - uint32_t skey[120]; - - switch (key_len) { - case 16: - num_rounds = 10; - break; - case 24: - num_rounds = 12; - break; - case 32: - num_rounds = 14; - break; - default: - /* abort(); */ - return 0; - } - nk = (int)(key_len >> 2); - nkf = (int)((num_rounds + 1) << 2); - tmp = 0; - for (i = 0; i < nk; i ++) { - tmp = br_dec32le((const unsigned char *)key + (i << 2)); - skey[(i << 1) + 0] = tmp; - skey[(i << 1) + 1] = tmp; - } - for (i = nk, j = 0, k = 0; i < nkf; i ++) { - if (j == 0) { - tmp = (tmp << 24) | (tmp >> 8); - tmp = sub_word(tmp) ^ Rcon[k]; - } else if (nk > 6 && j == 4) { - tmp = sub_word(tmp); - } - tmp ^= skey[(i - nk) << 1]; - skey[(i << 1) + 0] = tmp; - skey[(i << 1) + 1] = tmp; - if (++ j == nk) { - j = 0; - k ++; - } - } - for (i = 0; i < nkf; i += 4) { - br_aes_ct_ortho(skey + (i << 1)); - } - for (i = 0, j = 0; i < nkf; i ++, j += 2) { - comp_skey[i] = (skey[j + 0] & 0x55555555) - | (skey[j + 1] & 0xAAAAAAAA); - } - return num_rounds; -} - -/* see inner.h */ -void -br_aes_ct_skey_expand(uint32_t *skey, - unsigned num_rounds, const uint32_t *comp_skey) -{ - unsigned u, v, n; - - n = (num_rounds + 1) << 2; - for (u = 0, v = 0; u < n; u ++, v += 2) { - uint32_t x, y; - - x = y = comp_skey[u]; - x &= 0x55555555; - skey[v + 0] = x | (x << 1); - y &= 0xAAAAAAAA; - skey[v + 1] = y | (y >> 1); - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/aes_ct64.c b/src/tls/bearssl/aes_ct64.c deleted file mode 100644 index 99b650a39..000000000 --- a/src/tls/bearssl/aes_ct64.c +++ /dev/null @@ -1,403 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_aes_ct64_bitslice_Sbox(uint64_t *q) -{ - /* - * This S-box implementation is a straightforward translation of - * the circuit described by Boyar and Peralta in "A new - * combinational logic minimization technique with applications - * to cryptology" (https://eprint.iacr.org/2009/191.pdf). - * - * Note that variables x* (input) and s* (output) are numbered - * in "reverse" order (x0 is the high bit, x7 is the low bit). - */ - - uint64_t x0, x1, x2, x3, x4, x5, x6, x7; - uint64_t y1, y2, y3, y4, y5, y6, y7, y8, y9; - uint64_t y10, y11, y12, y13, y14, y15, y16, y17, y18, y19; - uint64_t y20, y21; - uint64_t z0, z1, z2, z3, z4, z5, z6, z7, z8, z9; - uint64_t z10, z11, z12, z13, z14, z15, z16, z17; - uint64_t t0, t1, t2, t3, t4, t5, t6, t7, t8, t9; - uint64_t t10, t11, t12, t13, t14, t15, t16, t17, t18, t19; - uint64_t t20, t21, t22, t23, t24, t25, t26, t27, t28, t29; - uint64_t t30, t31, t32, t33, t34, t35, t36, t37, t38, t39; - uint64_t t40, t41, t42, t43, t44, t45, t46, t47, t48, t49; - uint64_t t50, t51, t52, t53, t54, t55, t56, t57, t58, t59; - uint64_t t60, t61, t62, t63, t64, t65, t66, t67; - uint64_t s0, s1, s2, s3, s4, s5, s6, s7; - - x0 = q[7]; - x1 = q[6]; - x2 = q[5]; - x3 = q[4]; - x4 = q[3]; - x5 = q[2]; - x6 = q[1]; - x7 = q[0]; - - /* - * Top linear transformation. - */ - y14 = x3 ^ x5; - y13 = x0 ^ x6; - y9 = x0 ^ x3; - y8 = x0 ^ x5; - t0 = x1 ^ x2; - y1 = t0 ^ x7; - y4 = y1 ^ x3; - y12 = y13 ^ y14; - y2 = y1 ^ x0; - y5 = y1 ^ x6; - y3 = y5 ^ y8; - t1 = x4 ^ y12; - y15 = t1 ^ x5; - y20 = t1 ^ x1; - y6 = y15 ^ x7; - y10 = y15 ^ t0; - y11 = y20 ^ y9; - y7 = x7 ^ y11; - y17 = y10 ^ y11; - y19 = y10 ^ y8; - y16 = t0 ^ y11; - y21 = y13 ^ y16; - y18 = x0 ^ y16; - - /* - * Non-linear section. - */ - t2 = y12 & y15; - t3 = y3 & y6; - t4 = t3 ^ t2; - t5 = y4 & x7; - t6 = t5 ^ t2; - t7 = y13 & y16; - t8 = y5 & y1; - t9 = t8 ^ t7; - t10 = y2 & y7; - t11 = t10 ^ t7; - t12 = y9 & y11; - t13 = y14 & y17; - t14 = t13 ^ t12; - t15 = y8 & y10; - t16 = t15 ^ t12; - t17 = t4 ^ t14; - t18 = t6 ^ t16; - t19 = t9 ^ t14; - t20 = t11 ^ t16; - t21 = t17 ^ y20; - t22 = t18 ^ y19; - t23 = t19 ^ y21; - t24 = t20 ^ y18; - - t25 = t21 ^ t22; - t26 = t21 & t23; - t27 = t24 ^ t26; - t28 = t25 & t27; - t29 = t28 ^ t22; - t30 = t23 ^ t24; - t31 = t22 ^ t26; - t32 = t31 & t30; - t33 = t32 ^ t24; - t34 = t23 ^ t33; - t35 = t27 ^ t33; - t36 = t24 & t35; - t37 = t36 ^ t34; - t38 = t27 ^ t36; - t39 = t29 & t38; - t40 = t25 ^ t39; - - t41 = t40 ^ t37; - t42 = t29 ^ t33; - t43 = t29 ^ t40; - t44 = t33 ^ t37; - t45 = t42 ^ t41; - z0 = t44 & y15; - z1 = t37 & y6; - z2 = t33 & x7; - z3 = t43 & y16; - z4 = t40 & y1; - z5 = t29 & y7; - z6 = t42 & y11; - z7 = t45 & y17; - z8 = t41 & y10; - z9 = t44 & y12; - z10 = t37 & y3; - z11 = t33 & y4; - z12 = t43 & y13; - z13 = t40 & y5; - z14 = t29 & y2; - z15 = t42 & y9; - z16 = t45 & y14; - z17 = t41 & y8; - - /* - * Bottom linear transformation. - */ - t46 = z15 ^ z16; - t47 = z10 ^ z11; - t48 = z5 ^ z13; - t49 = z9 ^ z10; - t50 = z2 ^ z12; - t51 = z2 ^ z5; - t52 = z7 ^ z8; - t53 = z0 ^ z3; - t54 = z6 ^ z7; - t55 = z16 ^ z17; - t56 = z12 ^ t48; - t57 = t50 ^ t53; - t58 = z4 ^ t46; - t59 = z3 ^ t54; - t60 = t46 ^ t57; - t61 = z14 ^ t57; - t62 = t52 ^ t58; - t63 = t49 ^ t58; - t64 = z4 ^ t59; - t65 = t61 ^ t62; - t66 = z1 ^ t63; - s0 = t59 ^ t63; - s6 = t56 ^ ~t62; - s7 = t48 ^ ~t60; - t67 = t64 ^ t65; - s3 = t53 ^ t66; - s4 = t51 ^ t66; - s5 = t47 ^ t65; - s1 = t64 ^ ~s3; - s2 = t55 ^ ~t67; - - q[7] = s0; - q[6] = s1; - q[5] = s2; - q[4] = s3; - q[3] = s4; - q[2] = s5; - q[1] = s6; - q[0] = s7; -} - -/* see inner.h */ -void -br_aes_ct64_ortho(uint64_t *q) -{ -#define SWAPN(cl, ch, s, x, y) do { \ - uint64_t a, b; \ - a = (x); \ - b = (y); \ - (x) = (a & (uint64_t)cl) | ((b & (uint64_t)cl) << (s)); \ - (y) = ((a & (uint64_t)ch) >> (s)) | (b & (uint64_t)ch); \ - } while (0) - -#define SWAP2(x, y) SWAPN(0x5555555555555555, 0xAAAAAAAAAAAAAAAA, 1, x, y) -#define SWAP4(x, y) SWAPN(0x3333333333333333, 0xCCCCCCCCCCCCCCCC, 2, x, y) -#define SWAP8(x, y) SWAPN(0x0F0F0F0F0F0F0F0F, 0xF0F0F0F0F0F0F0F0, 4, x, y) - - SWAP2(q[0], q[1]); - SWAP2(q[2], q[3]); - SWAP2(q[4], q[5]); - SWAP2(q[6], q[7]); - - SWAP4(q[0], q[2]); - SWAP4(q[1], q[3]); - SWAP4(q[4], q[6]); - SWAP4(q[5], q[7]); - - SWAP8(q[0], q[4]); - SWAP8(q[1], q[5]); - SWAP8(q[2], q[6]); - SWAP8(q[3], q[7]); -} - -/* see inner.h */ -void -br_aes_ct64_interleave_in(uint64_t *q0, uint64_t *q1, const uint32_t *w) -{ - uint64_t x0, x1, x2, x3; - - x0 = w[0]; - x1 = w[1]; - x2 = w[2]; - x3 = w[3]; - x0 |= (x0 << 16); - x1 |= (x1 << 16); - x2 |= (x2 << 16); - x3 |= (x3 << 16); - x0 &= (uint64_t)0x0000FFFF0000FFFF; - x1 &= (uint64_t)0x0000FFFF0000FFFF; - x2 &= (uint64_t)0x0000FFFF0000FFFF; - x3 &= (uint64_t)0x0000FFFF0000FFFF; - x0 |= (x0 << 8); - x1 |= (x1 << 8); - x2 |= (x2 << 8); - x3 |= (x3 << 8); - x0 &= (uint64_t)0x00FF00FF00FF00FF; - x1 &= (uint64_t)0x00FF00FF00FF00FF; - x2 &= (uint64_t)0x00FF00FF00FF00FF; - x3 &= (uint64_t)0x00FF00FF00FF00FF; - *q0 = x0 | (x2 << 8); - *q1 = x1 | (x3 << 8); -} - -/* see inner.h */ -void -br_aes_ct64_interleave_out(uint32_t *w, uint64_t q0, uint64_t q1) -{ - uint64_t x0, x1, x2, x3; - - x0 = q0 & (uint64_t)0x00FF00FF00FF00FF; - x1 = q1 & (uint64_t)0x00FF00FF00FF00FF; - x2 = (q0 >> 8) & (uint64_t)0x00FF00FF00FF00FF; - x3 = (q1 >> 8) & (uint64_t)0x00FF00FF00FF00FF; - x0 |= (x0 >> 8); - x1 |= (x1 >> 8); - x2 |= (x2 >> 8); - x3 |= (x3 >> 8); - x0 &= (uint64_t)0x0000FFFF0000FFFF; - x1 &= (uint64_t)0x0000FFFF0000FFFF; - x2 &= (uint64_t)0x0000FFFF0000FFFF; - x3 &= (uint64_t)0x0000FFFF0000FFFF; - w[0] = (uint32_t)x0 | (uint32_t)(x0 >> 16); - w[1] = (uint32_t)x1 | (uint32_t)(x1 >> 16); - w[2] = (uint32_t)x2 | (uint32_t)(x2 >> 16); - w[3] = (uint32_t)x3 | (uint32_t)(x3 >> 16); -} - -static const unsigned char Rcon[] = { - 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36 -}; - -static uint32_t -sub_word(uint32_t x) -{ - uint64_t q[8]; - - memset(q, 0, sizeof q); - q[0] = x; - br_aes_ct64_ortho(q); - br_aes_ct64_bitslice_Sbox(q); - br_aes_ct64_ortho(q); - return (uint32_t)q[0]; -} - -/* see inner.h */ -unsigned -br_aes_ct64_keysched(uint64_t *comp_skey, const void *key, size_t key_len) -{ - unsigned num_rounds; - int i, j, k, nk, nkf; - uint32_t tmp; - uint32_t skey[60]; - - switch (key_len) { - case 16: - num_rounds = 10; - break; - case 24: - num_rounds = 12; - break; - case 32: - num_rounds = 14; - break; - default: - /* abort(); */ - return 0; - } - nk = (int)(key_len >> 2); - nkf = (int)((num_rounds + 1) << 2); - br_range_dec32le(skey, (key_len >> 2), key); - tmp = skey[(key_len >> 2) - 1]; - for (i = nk, j = 0, k = 0; i < nkf; i ++) { - if (j == 0) { - tmp = (tmp << 24) | (tmp >> 8); - tmp = sub_word(tmp) ^ Rcon[k]; - } else if (nk > 6 && j == 4) { - tmp = sub_word(tmp); - } - tmp ^= skey[i - nk]; - skey[i] = tmp; - if (++ j == nk) { - j = 0; - k ++; - } - } - - for (i = 0, j = 0; i < nkf; i += 4, j += 2) { - uint64_t q[8]; - - br_aes_ct64_interleave_in(&q[0], &q[4], skey + i); - q[1] = q[0]; - q[2] = q[0]; - q[3] = q[0]; - q[5] = q[4]; - q[6] = q[4]; - q[7] = q[4]; - br_aes_ct64_ortho(q); - comp_skey[j + 0] = - (q[0] & (uint64_t)0x1111111111111111) - | (q[1] & (uint64_t)0x2222222222222222) - | (q[2] & (uint64_t)0x4444444444444444) - | (q[3] & (uint64_t)0x8888888888888888); - comp_skey[j + 1] = - (q[4] & (uint64_t)0x1111111111111111) - | (q[5] & (uint64_t)0x2222222222222222) - | (q[6] & (uint64_t)0x4444444444444444) - | (q[7] & (uint64_t)0x8888888888888888); - } - return num_rounds; -} - -/* see inner.h */ -void -br_aes_ct64_skey_expand(uint64_t *skey, - unsigned num_rounds, const uint64_t *comp_skey) -{ - unsigned u, v, n; - - n = (num_rounds + 1) << 1; - for (u = 0, v = 0; u < n; u ++, v += 4) { - uint64_t x0, x1, x2, x3; - - x0 = x1 = x2 = x3 = comp_skey[u]; - x0 &= (uint64_t)0x1111111111111111; - x1 &= (uint64_t)0x2222222222222222; - x2 &= (uint64_t)0x4444444444444444; - x3 &= (uint64_t)0x8888888888888888; - x1 >>= 1; - x2 >>= 2; - x3 >>= 3; - skey[v + 0] = (x0 << 4) - x0; - skey[v + 1] = (x1 << 4) - x1; - skey[v + 2] = (x2 << 4) - x2; - skey[v + 3] = (x3 << 4) - x3; - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/aes_ct64_cbcdec.c b/src/tls/bearssl/aes_ct64_cbcdec.c deleted file mode 100644 index 5f0f8185d..000000000 --- a/src/tls/bearssl/aes_ct64_cbcdec.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_block.h */ -void -br_aes_ct64_cbcdec_init(br_aes_ct64_cbcdec_keys *ctx, - const void *key, size_t len) -{ - ctx->vtable = &br_aes_ct64_cbcdec_vtable; - ctx->num_rounds = br_aes_ct64_keysched(ctx->skey, key, len); -} - -/* see bearssl_block.h */ -void -br_aes_ct64_cbcdec_run(const br_aes_ct64_cbcdec_keys *ctx, - void *iv, void *data, size_t len) -{ - unsigned char *buf; - uint64_t sk_exp[120]; - uint32_t ivw[4]; - - br_aes_ct64_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); - br_range_dec32le(ivw, 4, iv); - buf = data; - while (len > 0) { - uint64_t q[8]; - uint32_t w1[16], w2[16]; - int i; - - if (len >= 64) { - br_range_dec32le(w1, 16, buf); - } else { - br_range_dec32le(w1, len >> 2, buf); - } - for (i = 0; i < 4; i ++) { - br_aes_ct64_interleave_in( - &q[i], &q[i + 4], w1 + (i << 2)); - } - br_aes_ct64_ortho(q); - br_aes_ct64_bitslice_decrypt(ctx->num_rounds, sk_exp, q); - br_aes_ct64_ortho(q); - for (i = 0; i < 4; i ++) { - br_aes_ct64_interleave_out( - w2 + (i << 2), q[i], q[i + 4]); - } - for (i = 0; i < 4; i ++) { - w2[i] ^= ivw[i]; - } - if (len >= 64) { - for (i = 4; i < 16; i ++) { - w2[i] ^= w1[i - 4]; - } - memcpy(ivw, w1 + 12, sizeof ivw); - br_range_enc32le(buf, w2, 16); - } else { - int j; - - j = (int)(len >> 2); - for (i = 4; i < j; i ++) { - w2[i] ^= w1[i - 4]; - } - memcpy(ivw, w1 + j - 4, sizeof ivw); - br_range_enc32le(buf, w2, j); - break; - } - buf += 64; - len -= 64; - } - br_range_enc32le(iv, ivw, 4); -} - -/* see bearssl_block.h */ -const br_block_cbcdec_class br_aes_ct64_cbcdec_vtable = { - sizeof(br_aes_ct64_cbcdec_keys), - 16, - 4, - (void (*)(const br_block_cbcdec_class **, const void *, size_t)) - &br_aes_ct64_cbcdec_init, - (void (*)(const br_block_cbcdec_class *const *, void *, void *, size_t)) - &br_aes_ct64_cbcdec_run -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/aes_ct64_cbcenc.c b/src/tls/bearssl/aes_ct64_cbcenc.c deleted file mode 100644 index 03ca04980..000000000 --- a/src/tls/bearssl/aes_ct64_cbcenc.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_block.h */ -void -br_aes_ct64_cbcenc_init(br_aes_ct64_cbcenc_keys *ctx, - const void *key, size_t len) -{ - ctx->vtable = &br_aes_ct64_cbcenc_vtable; - ctx->num_rounds = br_aes_ct64_keysched(ctx->skey, key, len); -} - -/* see bearssl_block.h */ -void -br_aes_ct64_cbcenc_run(const br_aes_ct64_cbcenc_keys *ctx, - void *iv, void *data, size_t len) -{ - unsigned char *buf; - uint64_t sk_exp[120]; - uint32_t ivw[4]; - - br_aes_ct64_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); - br_range_dec32le(ivw, 4, iv); - buf = data; - while (len > 0) { - uint32_t w[4]; - uint64_t q[8]; - - w[0] = ivw[0] ^ br_dec32le(buf); - w[1] = ivw[1] ^ br_dec32le(buf + 4); - w[2] = ivw[2] ^ br_dec32le(buf + 8); - w[3] = ivw[3] ^ br_dec32le(buf + 12); - br_aes_ct64_interleave_in(&q[0], &q[4], w); - br_aes_ct64_ortho(q); - br_aes_ct64_bitslice_encrypt(ctx->num_rounds, sk_exp, q); - br_aes_ct64_ortho(q); - br_aes_ct64_interleave_out(w, q[0], q[4]); - memcpy(ivw, w, sizeof w); - br_enc32le(buf, w[0]); - br_enc32le(buf + 4, w[1]); - br_enc32le(buf + 8, w[2]); - br_enc32le(buf + 12, w[3]); - buf += 16; - len -= 16; - } - br_range_enc32le(iv, ivw, 4); -} - -/* see bearssl_block.h */ -const br_block_cbcenc_class br_aes_ct64_cbcenc_vtable = { - sizeof(br_aes_ct64_cbcenc_keys), - 16, - 4, - (void (*)(const br_block_cbcenc_class **, const void *, size_t)) - &br_aes_ct64_cbcenc_init, - (void (*)(const br_block_cbcenc_class *const *, void *, void *, size_t)) - &br_aes_ct64_cbcenc_run -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/aes_ct64_ctr.c b/src/tls/bearssl/aes_ct64_ctr.c deleted file mode 100644 index e5e8bd01c..000000000 --- a/src/tls/bearssl/aes_ct64_ctr.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_block.h */ -void -br_aes_ct64_ctr_init(br_aes_ct64_ctr_keys *ctx, - const void *key, size_t len) -{ - ctx->vtable = &br_aes_ct64_ctr_vtable; - ctx->num_rounds = br_aes_ct64_keysched(ctx->skey, key, len); -} - -static void -xorbuf(void *dst, const void *src, size_t len) -{ - unsigned char *d; - const unsigned char *s; - - d = dst; - s = src; - while (len -- > 0) { - *d ++ ^= *s ++; - } -} - -/* see bearssl_block.h */ -uint32_t -br_aes_ct64_ctr_run(const br_aes_ct64_ctr_keys *ctx, - const void *iv, uint32_t cc, void *data, size_t len) -{ - unsigned char *buf; - uint32_t ivw[16]; - uint64_t sk_exp[120]; - - br_aes_ct64_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); - br_range_dec32le(ivw, 3, iv); - memcpy(ivw + 4, ivw, 3 * sizeof(uint32_t)); - memcpy(ivw + 8, ivw, 3 * sizeof(uint32_t)); - memcpy(ivw + 12, ivw, 3 * sizeof(uint32_t)); - buf = data; - while (len > 0) { - uint64_t q[8]; - uint32_t w[16]; - unsigned char tmp[64]; - int i; - - /* - * TODO: see if we can save on the first br_aes_ct64_ortho() - * call, since iv0/iv1/iv2 are constant for the whole run. - */ - memcpy(w, ivw, sizeof ivw); - w[3] = br_swap32(cc); - w[7] = br_swap32(cc + 1); - w[11] = br_swap32(cc + 2); - w[15] = br_swap32(cc + 3); - for (i = 0; i < 4; i ++) { - br_aes_ct64_interleave_in( - &q[i], &q[i + 4], w + (i << 2)); - } - br_aes_ct64_ortho(q); - br_aes_ct64_bitslice_encrypt(ctx->num_rounds, sk_exp, q); - br_aes_ct64_ortho(q); - for (i = 0; i < 4; i ++) { - br_aes_ct64_interleave_out( - w + (i << 2), q[i], q[i + 4]); - } - br_range_enc32le(tmp, w, 16); - if (len <= 64) { - xorbuf(buf, tmp, len); - cc += (uint32_t)len >> 4; - break; - } - xorbuf(buf, tmp, 64); - buf += 64; - len -= 64; - cc += 4; - } - return cc; -} - -/* see bearssl_block.h */ -const br_block_ctr_class br_aes_ct64_ctr_vtable = { - sizeof(br_aes_ct64_ctr_keys), - 16, - 4, - (void (*)(const br_block_ctr_class **, const void *, size_t)) - &br_aes_ct64_ctr_init, - (uint32_t (*)(const br_block_ctr_class *const *, - const void *, uint32_t, void *, size_t)) - &br_aes_ct64_ctr_run -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/aes_ct64_ctrcbc.c b/src/tls/bearssl/aes_ct64_ctrcbc.c deleted file mode 100644 index 6930a78a1..000000000 --- a/src/tls/bearssl/aes_ct64_ctrcbc.c +++ /dev/null @@ -1,438 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_block.h */ -void -br_aes_ct64_ctrcbc_init(br_aes_ct64_ctrcbc_keys *ctx, - const void *key, size_t len) -{ - ctx->vtable = &br_aes_ct64_ctrcbc_vtable; - ctx->num_rounds = br_aes_ct64_keysched(ctx->skey, key, len); -} - -static void -xorbuf(void *dst, const void *src, size_t len) -{ - unsigned char *d; - const unsigned char *s; - - d = dst; - s = src; - while (len -- > 0) { - *d ++ ^= *s ++; - } -} - -/* see bearssl_block.h */ -void -br_aes_ct64_ctrcbc_ctr(const br_aes_ct64_ctrcbc_keys *ctx, - void *ctr, void *data, size_t len) -{ - unsigned char *buf; - unsigned char *ivbuf; - uint32_t iv0, iv1, iv2, iv3; - uint64_t sk_exp[120]; - - br_aes_ct64_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); - - /* - * We keep the counter as four 32-bit values, with big-endian - * convention, because that's what is expected for purposes of - * incrementing the counter value. - */ - ivbuf = ctr; - iv0 = br_dec32be(ivbuf + 0); - iv1 = br_dec32be(ivbuf + 4); - iv2 = br_dec32be(ivbuf + 8); - iv3 = br_dec32be(ivbuf + 12); - - buf = data; - while (len > 0) { - uint64_t q[8]; - uint32_t w[16]; - unsigned char tmp[64]; - int i, j; - - /* - * The bitslice implementation expects values in - * little-endian convention, so we have to byteswap them. - */ - j = (len >= 64) ? 16 : (int)(len >> 2); - for (i = 0; i < j; i += 4) { - uint32_t carry; - - w[i + 0] = br_swap32(iv0); - w[i + 1] = br_swap32(iv1); - w[i + 2] = br_swap32(iv2); - w[i + 3] = br_swap32(iv3); - iv3 ++; - carry = ~(iv3 | -iv3) >> 31; - iv2 += carry; - carry &= -(~(iv2 | -iv2) >> 31); - iv1 += carry; - carry &= -(~(iv1 | -iv1) >> 31); - iv0 += carry; - } - memset(w + i, 0, (16 - i) * sizeof(uint32_t)); - - for (i = 0; i < 4; i ++) { - br_aes_ct64_interleave_in( - &q[i], &q[i + 4], w + (i << 2)); - } - br_aes_ct64_ortho(q); - br_aes_ct64_bitslice_encrypt(ctx->num_rounds, sk_exp, q); - br_aes_ct64_ortho(q); - for (i = 0; i < 4; i ++) { - br_aes_ct64_interleave_out( - w + (i << 2), q[i], q[i + 4]); - } - - br_range_enc32le(tmp, w, 16); - if (len <= 64) { - xorbuf(buf, tmp, len); - break; - } - xorbuf(buf, tmp, 64); - buf += 64; - len -= 64; - } - br_enc32be(ivbuf + 0, iv0); - br_enc32be(ivbuf + 4, iv1); - br_enc32be(ivbuf + 8, iv2); - br_enc32be(ivbuf + 12, iv3); -} - -/* see bearssl_block.h */ -void -br_aes_ct64_ctrcbc_mac(const br_aes_ct64_ctrcbc_keys *ctx, - void *cbcmac, const void *data, size_t len) -{ - const unsigned char *buf; - uint32_t cm0, cm1, cm2, cm3; - uint64_t q[8]; - uint64_t sk_exp[120]; - - br_aes_ct64_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); - - cm0 = br_dec32le((unsigned char *)cbcmac + 0); - cm1 = br_dec32le((unsigned char *)cbcmac + 4); - cm2 = br_dec32le((unsigned char *)cbcmac + 8); - cm3 = br_dec32le((unsigned char *)cbcmac + 12); - - buf = data; - memset(q, 0, sizeof q); - while (len > 0) { - uint32_t w[4]; - - w[0] = cm0 ^ br_dec32le(buf + 0); - w[1] = cm1 ^ br_dec32le(buf + 4); - w[2] = cm2 ^ br_dec32le(buf + 8); - w[3] = cm3 ^ br_dec32le(buf + 12); - - br_aes_ct64_interleave_in(&q[0], &q[4], w); - br_aes_ct64_ortho(q); - br_aes_ct64_bitslice_encrypt(ctx->num_rounds, sk_exp, q); - br_aes_ct64_ortho(q); - br_aes_ct64_interleave_out(w, q[0], q[4]); - - cm0 = w[0]; - cm1 = w[1]; - cm2 = w[2]; - cm3 = w[3]; - buf += 16; - len -= 16; - } - - br_enc32le((unsigned char *)cbcmac + 0, cm0); - br_enc32le((unsigned char *)cbcmac + 4, cm1); - br_enc32le((unsigned char *)cbcmac + 8, cm2); - br_enc32le((unsigned char *)cbcmac + 12, cm3); -} - -/* see bearssl_block.h */ -void -br_aes_ct64_ctrcbc_encrypt(const br_aes_ct64_ctrcbc_keys *ctx, - void *ctr, void *cbcmac, void *data, size_t len) -{ - /* - * When encrypting, the CBC-MAC processing must be lagging by - * one block, since it operates on the encrypted values, so - * it must wait for that encryption to complete. - */ - - unsigned char *buf; - unsigned char *ivbuf; - uint32_t iv0, iv1, iv2, iv3; - uint32_t cm0, cm1, cm2, cm3; - uint64_t sk_exp[120]; - uint64_t q[8]; - int first_iter; - - br_aes_ct64_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); - - /* - * We keep the counter as four 32-bit values, with big-endian - * convention, because that's what is expected for purposes of - * incrementing the counter value. - */ - ivbuf = ctr; - iv0 = br_dec32be(ivbuf + 0); - iv1 = br_dec32be(ivbuf + 4); - iv2 = br_dec32be(ivbuf + 8); - iv3 = br_dec32be(ivbuf + 12); - - /* - * The current CBC-MAC value is kept in little-endian convention. - */ - cm0 = br_dec32le((unsigned char *)cbcmac + 0); - cm1 = br_dec32le((unsigned char *)cbcmac + 4); - cm2 = br_dec32le((unsigned char *)cbcmac + 8); - cm3 = br_dec32le((unsigned char *)cbcmac + 12); - - buf = data; - first_iter = 1; - memset(q, 0, sizeof q); - while (len > 0) { - uint32_t w[8], carry; - - /* - * The bitslice implementation expects values in - * little-endian convention, so we have to byteswap them. - */ - w[0] = br_swap32(iv0); - w[1] = br_swap32(iv1); - w[2] = br_swap32(iv2); - w[3] = br_swap32(iv3); - iv3 ++; - carry = ~(iv3 | -iv3) >> 31; - iv2 += carry; - carry &= -(~(iv2 | -iv2) >> 31); - iv1 += carry; - carry &= -(~(iv1 | -iv1) >> 31); - iv0 += carry; - - /* - * The block for CBC-MAC. - */ - w[4] = cm0; - w[5] = cm1; - w[6] = cm2; - w[7] = cm3; - - br_aes_ct64_interleave_in(&q[0], &q[4], w); - br_aes_ct64_interleave_in(&q[1], &q[5], w + 4); - br_aes_ct64_ortho(q); - br_aes_ct64_bitslice_encrypt(ctx->num_rounds, sk_exp, q); - br_aes_ct64_ortho(q); - br_aes_ct64_interleave_out(w, q[0], q[4]); - br_aes_ct64_interleave_out(w + 4, q[1], q[5]); - - /* - * We do the XOR with the plaintext in 32-bit registers, - * so that the value are available for CBC-MAC processing - * as well. - */ - w[0] ^= br_dec32le(buf + 0); - w[1] ^= br_dec32le(buf + 4); - w[2] ^= br_dec32le(buf + 8); - w[3] ^= br_dec32le(buf + 12); - br_enc32le(buf + 0, w[0]); - br_enc32le(buf + 4, w[1]); - br_enc32le(buf + 8, w[2]); - br_enc32le(buf + 12, w[3]); - - buf += 16; - len -= 16; - - /* - * We set the cm* values to the block to encrypt in the - * next iteration. - */ - if (first_iter) { - first_iter = 0; - cm0 ^= w[0]; - cm1 ^= w[1]; - cm2 ^= w[2]; - cm3 ^= w[3]; - } else { - cm0 = w[0] ^ w[4]; - cm1 = w[1] ^ w[5]; - cm2 = w[2] ^ w[6]; - cm3 = w[3] ^ w[7]; - } - - /* - * If this was the last iteration, then compute the - * extra block encryption to complete CBC-MAC. - */ - if (len == 0) { - w[0] = cm0; - w[1] = cm1; - w[2] = cm2; - w[3] = cm3; - br_aes_ct64_interleave_in(&q[0], &q[4], w); - br_aes_ct64_ortho(q); - br_aes_ct64_bitslice_encrypt( - ctx->num_rounds, sk_exp, q); - br_aes_ct64_ortho(q); - br_aes_ct64_interleave_out(w, q[0], q[4]); - cm0 = w[0]; - cm1 = w[1]; - cm2 = w[2]; - cm3 = w[3]; - break; - } - } - - br_enc32be(ivbuf + 0, iv0); - br_enc32be(ivbuf + 4, iv1); - br_enc32be(ivbuf + 8, iv2); - br_enc32be(ivbuf + 12, iv3); - br_enc32le((unsigned char *)cbcmac + 0, cm0); - br_enc32le((unsigned char *)cbcmac + 4, cm1); - br_enc32le((unsigned char *)cbcmac + 8, cm2); - br_enc32le((unsigned char *)cbcmac + 12, cm3); -} - -/* see bearssl_block.h */ -void -br_aes_ct64_ctrcbc_decrypt(const br_aes_ct64_ctrcbc_keys *ctx, - void *ctr, void *cbcmac, void *data, size_t len) -{ - unsigned char *buf; - unsigned char *ivbuf; - uint32_t iv0, iv1, iv2, iv3; - uint32_t cm0, cm1, cm2, cm3; - uint64_t sk_exp[120]; - uint64_t q[8]; - - br_aes_ct64_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); - - /* - * We keep the counter as four 32-bit values, with big-endian - * convention, because that's what is expected for purposes of - * incrementing the counter value. - */ - ivbuf = ctr; - iv0 = br_dec32be(ivbuf + 0); - iv1 = br_dec32be(ivbuf + 4); - iv2 = br_dec32be(ivbuf + 8); - iv3 = br_dec32be(ivbuf + 12); - - /* - * The current CBC-MAC value is kept in little-endian convention. - */ - cm0 = br_dec32le((unsigned char *)cbcmac + 0); - cm1 = br_dec32le((unsigned char *)cbcmac + 4); - cm2 = br_dec32le((unsigned char *)cbcmac + 8); - cm3 = br_dec32le((unsigned char *)cbcmac + 12); - - buf = data; - memset(q, 0, sizeof q); - while (len > 0) { - uint32_t w[8], carry; - unsigned char tmp[16]; - - /* - * The bitslice implementation expects values in - * little-endian convention, so we have to byteswap them. - */ - w[0] = br_swap32(iv0); - w[1] = br_swap32(iv1); - w[2] = br_swap32(iv2); - w[3] = br_swap32(iv3); - iv3 ++; - carry = ~(iv3 | -iv3) >> 31; - iv2 += carry; - carry &= -(~(iv2 | -iv2) >> 31); - iv1 += carry; - carry &= -(~(iv1 | -iv1) >> 31); - iv0 += carry; - - /* - * The block for CBC-MAC. - */ - w[4] = cm0 ^ br_dec32le(buf + 0); - w[5] = cm1 ^ br_dec32le(buf + 4); - w[6] = cm2 ^ br_dec32le(buf + 8); - w[7] = cm3 ^ br_dec32le(buf + 12); - - br_aes_ct64_interleave_in(&q[0], &q[4], w); - br_aes_ct64_interleave_in(&q[1], &q[5], w + 4); - br_aes_ct64_ortho(q); - br_aes_ct64_bitslice_encrypt(ctx->num_rounds, sk_exp, q); - br_aes_ct64_ortho(q); - br_aes_ct64_interleave_out(w, q[0], q[4]); - br_aes_ct64_interleave_out(w + 4, q[1], q[5]); - - br_enc32le(tmp + 0, w[0]); - br_enc32le(tmp + 4, w[1]); - br_enc32le(tmp + 8, w[2]); - br_enc32le(tmp + 12, w[3]); - xorbuf(buf, tmp, 16); - cm0 = w[4]; - cm1 = w[5]; - cm2 = w[6]; - cm3 = w[7]; - buf += 16; - len -= 16; - } - - br_enc32be(ivbuf + 0, iv0); - br_enc32be(ivbuf + 4, iv1); - br_enc32be(ivbuf + 8, iv2); - br_enc32be(ivbuf + 12, iv3); - br_enc32le((unsigned char *)cbcmac + 0, cm0); - br_enc32le((unsigned char *)cbcmac + 4, cm1); - br_enc32le((unsigned char *)cbcmac + 8, cm2); - br_enc32le((unsigned char *)cbcmac + 12, cm3); -} - -/* see bearssl_block.h */ -const br_block_ctrcbc_class br_aes_ct64_ctrcbc_vtable = { - sizeof(br_aes_ct64_ctrcbc_keys), - 16, - 4, - (void (*)(const br_block_ctrcbc_class **, const void *, size_t)) - &br_aes_ct64_ctrcbc_init, - (void (*)(const br_block_ctrcbc_class *const *, - void *, void *, void *, size_t)) - &br_aes_ct64_ctrcbc_encrypt, - (void (*)(const br_block_ctrcbc_class *const *, - void *, void *, void *, size_t)) - &br_aes_ct64_ctrcbc_decrypt, - (void (*)(const br_block_ctrcbc_class *const *, - void *, void *, size_t)) - &br_aes_ct64_ctrcbc_ctr, - (void (*)(const br_block_ctrcbc_class *const *, - void *, const void *, size_t)) - &br_aes_ct64_ctrcbc_mac -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/aes_ct64_dec.c b/src/tls/bearssl/aes_ct64_dec.c deleted file mode 100644 index 971d380b8..000000000 --- a/src/tls/bearssl/aes_ct64_dec.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_aes_ct64_bitslice_invSbox(uint64_t *q) -{ - /* - * See br_aes_ct_bitslice_invSbox(). This is the natural extension - * to 64-bit registers. - */ - uint64_t q0, q1, q2, q3, q4, q5, q6, q7; - - q0 = ~q[0]; - q1 = ~q[1]; - q2 = q[2]; - q3 = q[3]; - q4 = q[4]; - q5 = ~q[5]; - q6 = ~q[6]; - q7 = q[7]; - q[7] = q1 ^ q4 ^ q6; - q[6] = q0 ^ q3 ^ q5; - q[5] = q7 ^ q2 ^ q4; - q[4] = q6 ^ q1 ^ q3; - q[3] = q5 ^ q0 ^ q2; - q[2] = q4 ^ q7 ^ q1; - q[1] = q3 ^ q6 ^ q0; - q[0] = q2 ^ q5 ^ q7; - - br_aes_ct64_bitslice_Sbox(q); - - q0 = ~q[0]; - q1 = ~q[1]; - q2 = q[2]; - q3 = q[3]; - q4 = q[4]; - q5 = ~q[5]; - q6 = ~q[6]; - q7 = q[7]; - q[7] = q1 ^ q4 ^ q6; - q[6] = q0 ^ q3 ^ q5; - q[5] = q7 ^ q2 ^ q4; - q[4] = q6 ^ q1 ^ q3; - q[3] = q5 ^ q0 ^ q2; - q[2] = q4 ^ q7 ^ q1; - q[1] = q3 ^ q6 ^ q0; - q[0] = q2 ^ q5 ^ q7; -} - -static void -add_round_key(uint64_t *q, const uint64_t *sk) -{ - int i; - - for (i = 0; i < 8; i ++) { - q[i] ^= sk[i]; - } -} - -static void -inv_shift_rows(uint64_t *q) -{ - int i; - - for (i = 0; i < 8; i ++) { - uint64_t x; - - x = q[i]; - q[i] = (x & (uint64_t)0x000000000000FFFF) - | ((x & (uint64_t)0x000000000FFF0000) << 4) - | ((x & (uint64_t)0x00000000F0000000) >> 12) - | ((x & (uint64_t)0x000000FF00000000) << 8) - | ((x & (uint64_t)0x0000FF0000000000) >> 8) - | ((x & (uint64_t)0x000F000000000000) << 12) - | ((x & (uint64_t)0xFFF0000000000000) >> 4); - } -} - -static inline uint64_t -rotr32(uint64_t x) -{ - return (x << 32) | (x >> 32); -} - -static void -inv_mix_columns(uint64_t *q) -{ - uint64_t q0, q1, q2, q3, q4, q5, q6, q7; - uint64_t r0, r1, r2, r3, r4, r5, r6, r7; - - q0 = q[0]; - q1 = q[1]; - q2 = q[2]; - q3 = q[3]; - q4 = q[4]; - q5 = q[5]; - q6 = q[6]; - q7 = q[7]; - r0 = (q0 >> 16) | (q0 << 48); - r1 = (q1 >> 16) | (q1 << 48); - r2 = (q2 >> 16) | (q2 << 48); - r3 = (q3 >> 16) | (q3 << 48); - r4 = (q4 >> 16) | (q4 << 48); - r5 = (q5 >> 16) | (q5 << 48); - r6 = (q6 >> 16) | (q6 << 48); - r7 = (q7 >> 16) | (q7 << 48); - - q[0] = q5 ^ q6 ^ q7 ^ r0 ^ r5 ^ r7 ^ rotr32(q0 ^ q5 ^ q6 ^ r0 ^ r5); - q[1] = q0 ^ q5 ^ r0 ^ r1 ^ r5 ^ r6 ^ r7 ^ rotr32(q1 ^ q5 ^ q7 ^ r1 ^ r5 ^ r6); - q[2] = q0 ^ q1 ^ q6 ^ r1 ^ r2 ^ r6 ^ r7 ^ rotr32(q0 ^ q2 ^ q6 ^ r2 ^ r6 ^ r7); - q[3] = q0 ^ q1 ^ q2 ^ q5 ^ q6 ^ r0 ^ r2 ^ r3 ^ r5 ^ rotr32(q0 ^ q1 ^ q3 ^ q5 ^ q6 ^ q7 ^ r0 ^ r3 ^ r5 ^ r7); - q[4] = q1 ^ q2 ^ q3 ^ q5 ^ r1 ^ r3 ^ r4 ^ r5 ^ r6 ^ r7 ^ rotr32(q1 ^ q2 ^ q4 ^ q5 ^ q7 ^ r1 ^ r4 ^ r5 ^ r6); - q[5] = q2 ^ q3 ^ q4 ^ q6 ^ r2 ^ r4 ^ r5 ^ r6 ^ r7 ^ rotr32(q2 ^ q3 ^ q5 ^ q6 ^ r2 ^ r5 ^ r6 ^ r7); - q[6] = q3 ^ q4 ^ q5 ^ q7 ^ r3 ^ r5 ^ r6 ^ r7 ^ rotr32(q3 ^ q4 ^ q6 ^ q7 ^ r3 ^ r6 ^ r7); - q[7] = q4 ^ q5 ^ q6 ^ r4 ^ r6 ^ r7 ^ rotr32(q4 ^ q5 ^ q7 ^ r4 ^ r7); -} - -/* see inner.h */ -void -br_aes_ct64_bitslice_decrypt(unsigned num_rounds, - const uint64_t *skey, uint64_t *q) -{ - unsigned u; - - add_round_key(q, skey + (num_rounds << 3)); - for (u = num_rounds - 1; u > 0; u --) { - inv_shift_rows(q); - br_aes_ct64_bitslice_invSbox(q); - add_round_key(q, skey + (u << 3)); - inv_mix_columns(q); - } - inv_shift_rows(q); - br_aes_ct64_bitslice_invSbox(q); - add_round_key(q, skey); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/aes_ct64_enc.c b/src/tls/bearssl/aes_ct64_enc.c deleted file mode 100644 index 6468f91e9..000000000 --- a/src/tls/bearssl/aes_ct64_enc.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -static inline void -add_round_key(uint64_t *q, const uint64_t *sk) -{ - q[0] ^= sk[0]; - q[1] ^= sk[1]; - q[2] ^= sk[2]; - q[3] ^= sk[3]; - q[4] ^= sk[4]; - q[5] ^= sk[5]; - q[6] ^= sk[6]; - q[7] ^= sk[7]; -} - -static inline void -shift_rows(uint64_t *q) -{ - int i; - - for (i = 0; i < 8; i ++) { - uint64_t x; - - x = q[i]; - q[i] = (x & (uint64_t)0x000000000000FFFF) - | ((x & (uint64_t)0x00000000FFF00000) >> 4) - | ((x & (uint64_t)0x00000000000F0000) << 12) - | ((x & (uint64_t)0x0000FF0000000000) >> 8) - | ((x & (uint64_t)0x000000FF00000000) << 8) - | ((x & (uint64_t)0xF000000000000000) >> 12) - | ((x & (uint64_t)0x0FFF000000000000) << 4); - } -} - -static inline uint64_t -rotr32(uint64_t x) -{ - return (x << 32) | (x >> 32); -} - -static inline void -mix_columns(uint64_t *q) -{ - uint64_t q0, q1, q2, q3, q4, q5, q6, q7; - uint64_t r0, r1, r2, r3, r4, r5, r6, r7; - - q0 = q[0]; - q1 = q[1]; - q2 = q[2]; - q3 = q[3]; - q4 = q[4]; - q5 = q[5]; - q6 = q[6]; - q7 = q[7]; - r0 = (q0 >> 16) | (q0 << 48); - r1 = (q1 >> 16) | (q1 << 48); - r2 = (q2 >> 16) | (q2 << 48); - r3 = (q3 >> 16) | (q3 << 48); - r4 = (q4 >> 16) | (q4 << 48); - r5 = (q5 >> 16) | (q5 << 48); - r6 = (q6 >> 16) | (q6 << 48); - r7 = (q7 >> 16) | (q7 << 48); - - q[0] = q7 ^ r7 ^ r0 ^ rotr32(q0 ^ r0); - q[1] = q0 ^ r0 ^ q7 ^ r7 ^ r1 ^ rotr32(q1 ^ r1); - q[2] = q1 ^ r1 ^ r2 ^ rotr32(q2 ^ r2); - q[3] = q2 ^ r2 ^ q7 ^ r7 ^ r3 ^ rotr32(q3 ^ r3); - q[4] = q3 ^ r3 ^ q7 ^ r7 ^ r4 ^ rotr32(q4 ^ r4); - q[5] = q4 ^ r4 ^ r5 ^ rotr32(q5 ^ r5); - q[6] = q5 ^ r5 ^ r6 ^ rotr32(q6 ^ r6); - q[7] = q6 ^ r6 ^ r7 ^ rotr32(q7 ^ r7); -} - -/* see inner.h */ -void -br_aes_ct64_bitslice_encrypt(unsigned num_rounds, - const uint64_t *skey, uint64_t *q) -{ - unsigned u; - - add_round_key(q, skey); - for (u = 1; u < num_rounds; u ++) { - br_aes_ct64_bitslice_Sbox(q); - shift_rows(q); - mix_columns(q); - add_round_key(q, skey + (u << 3)); - } - br_aes_ct64_bitslice_Sbox(q); - shift_rows(q); - add_round_key(q, skey + (num_rounds << 3)); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/aes_ct_cbcdec.c b/src/tls/bearssl/aes_ct_cbcdec.c deleted file mode 100644 index cb3d3ca72..000000000 --- a/src/tls/bearssl/aes_ct_cbcdec.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_block.h */ -void -br_aes_ct_cbcdec_init(br_aes_ct_cbcdec_keys *ctx, - const void *key, size_t len) -{ - ctx->vtable = &br_aes_ct_cbcdec_vtable; - ctx->num_rounds = br_aes_ct_keysched(ctx->skey, key, len); -} - -/* see bearssl_block.h */ -void -br_aes_ct_cbcdec_run(const br_aes_ct_cbcdec_keys *ctx, - void *iv, void *data, size_t len) -{ - unsigned char *buf, *ivbuf; - uint32_t iv0, iv1, iv2, iv3; - uint32_t sk_exp[120]; - - br_aes_ct_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); - ivbuf = iv; - iv0 = br_dec32le(ivbuf); - iv1 = br_dec32le(ivbuf + 4); - iv2 = br_dec32le(ivbuf + 8); - iv3 = br_dec32le(ivbuf + 12); - buf = data; - while (len > 0) { - uint32_t q[8], sq[8]; - - q[0] = br_dec32le(buf); - q[2] = br_dec32le(buf + 4); - q[4] = br_dec32le(buf + 8); - q[6] = br_dec32le(buf + 12); - if (len >= 32) { - q[1] = br_dec32le(buf + 16); - q[3] = br_dec32le(buf + 20); - q[5] = br_dec32le(buf + 24); - q[7] = br_dec32le(buf + 28); - } else { - q[1] = 0; - q[3] = 0; - q[5] = 0; - q[7] = 0; - } - memcpy(sq, q, sizeof q); - br_aes_ct_ortho(q); - br_aes_ct_bitslice_decrypt(ctx->num_rounds, sk_exp, q); - br_aes_ct_ortho(q); - br_enc32le(buf, q[0] ^ iv0); - br_enc32le(buf + 4, q[2] ^ iv1); - br_enc32le(buf + 8, q[4] ^ iv2); - br_enc32le(buf + 12, q[6] ^ iv3); - if (len < 32) { - iv0 = sq[0]; - iv1 = sq[2]; - iv2 = sq[4]; - iv3 = sq[6]; - break; - } - br_enc32le(buf + 16, q[1] ^ sq[0]); - br_enc32le(buf + 20, q[3] ^ sq[2]); - br_enc32le(buf + 24, q[5] ^ sq[4]); - br_enc32le(buf + 28, q[7] ^ sq[6]); - iv0 = sq[1]; - iv1 = sq[3]; - iv2 = sq[5]; - iv3 = sq[7]; - buf += 32; - len -= 32; - } - br_enc32le(ivbuf, iv0); - br_enc32le(ivbuf + 4, iv1); - br_enc32le(ivbuf + 8, iv2); - br_enc32le(ivbuf + 12, iv3); -} - -/* see bearssl_block.h */ -const br_block_cbcdec_class br_aes_ct_cbcdec_vtable = { - sizeof(br_aes_ct_cbcdec_keys), - 16, - 4, - (void (*)(const br_block_cbcdec_class **, const void *, size_t)) - &br_aes_ct_cbcdec_init, - (void (*)(const br_block_cbcdec_class *const *, void *, void *, size_t)) - &br_aes_ct_cbcdec_run -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/aes_ct_cbcenc.c b/src/tls/bearssl/aes_ct_cbcenc.c deleted file mode 100644 index 343db500b..000000000 --- a/src/tls/bearssl/aes_ct_cbcenc.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_block.h */ -void -br_aes_ct_cbcenc_init(br_aes_ct_cbcenc_keys *ctx, - const void *key, size_t len) -{ - ctx->vtable = &br_aes_ct_cbcenc_vtable; - ctx->num_rounds = br_aes_ct_keysched(ctx->skey, key, len); -} - -/* see bearssl_block.h */ -void -br_aes_ct_cbcenc_run(const br_aes_ct_cbcenc_keys *ctx, - void *iv, void *data, size_t len) -{ - unsigned char *buf, *ivbuf; - uint32_t q[8]; - uint32_t iv0, iv1, iv2, iv3; - uint32_t sk_exp[120]; - - q[1] = 0; - q[3] = 0; - q[5] = 0; - q[7] = 0; - br_aes_ct_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); - ivbuf = iv; - iv0 = br_dec32le(ivbuf); - iv1 = br_dec32le(ivbuf + 4); - iv2 = br_dec32le(ivbuf + 8); - iv3 = br_dec32le(ivbuf + 12); - buf = data; - while (len > 0) { - q[0] = iv0 ^ br_dec32le(buf); - q[2] = iv1 ^ br_dec32le(buf + 4); - q[4] = iv2 ^ br_dec32le(buf + 8); - q[6] = iv3 ^ br_dec32le(buf + 12); - br_aes_ct_ortho(q); - br_aes_ct_bitslice_encrypt(ctx->num_rounds, sk_exp, q); - br_aes_ct_ortho(q); - iv0 = q[0]; - iv1 = q[2]; - iv2 = q[4]; - iv3 = q[6]; - br_enc32le(buf, iv0); - br_enc32le(buf + 4, iv1); - br_enc32le(buf + 8, iv2); - br_enc32le(buf + 12, iv3); - buf += 16; - len -= 16; - } - br_enc32le(ivbuf, iv0); - br_enc32le(ivbuf + 4, iv1); - br_enc32le(ivbuf + 8, iv2); - br_enc32le(ivbuf + 12, iv3); -} - -/* see bearssl_block.h */ -const br_block_cbcenc_class br_aes_ct_cbcenc_vtable = { - sizeof(br_aes_ct_cbcenc_keys), - 16, - 4, - (void (*)(const br_block_cbcenc_class **, const void *, size_t)) - &br_aes_ct_cbcenc_init, - (void (*)(const br_block_cbcenc_class *const *, void *, void *, size_t)) - &br_aes_ct_cbcenc_run -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/aes_ct_ctr.c b/src/tls/bearssl/aes_ct_ctr.c deleted file mode 100644 index 820e595f0..000000000 --- a/src/tls/bearssl/aes_ct_ctr.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_block.h */ -void -br_aes_ct_ctr_init(br_aes_ct_ctr_keys *ctx, - const void *key, size_t len) -{ - ctx->vtable = &br_aes_ct_ctr_vtable; - ctx->num_rounds = br_aes_ct_keysched(ctx->skey, key, len); -} - -static void -xorbuf(void *dst, const void *src, size_t len) -{ - unsigned char *d; - const unsigned char *s; - - d = dst; - s = src; - while (len -- > 0) { - *d ++ ^= *s ++; - } -} - -/* see bearssl_block.h */ -uint32_t -br_aes_ct_ctr_run(const br_aes_ct_ctr_keys *ctx, - const void *iv, uint32_t cc, void *data, size_t len) -{ - unsigned char *buf; - const unsigned char *ivbuf; - uint32_t iv0, iv1, iv2; - uint32_t sk_exp[120]; - - br_aes_ct_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); - ivbuf = iv; - iv0 = br_dec32le(ivbuf); - iv1 = br_dec32le(ivbuf + 4); - iv2 = br_dec32le(ivbuf + 8); - buf = data; - while (len > 0) { - uint32_t q[8]; - unsigned char tmp[32]; - - /* - * TODO: see if we can save on the first br_aes_ct_ortho() - * call, since iv0/iv1/iv2 are constant for the whole run. - */ - q[0] = q[1] = iv0; - q[2] = q[3] = iv1; - q[4] = q[5] = iv2; - q[6] = br_swap32(cc); - q[7] = br_swap32(cc + 1); - br_aes_ct_ortho(q); - br_aes_ct_bitslice_encrypt(ctx->num_rounds, sk_exp, q); - br_aes_ct_ortho(q); - br_enc32le(tmp, q[0]); - br_enc32le(tmp + 4, q[2]); - br_enc32le(tmp + 8, q[4]); - br_enc32le(tmp + 12, q[6]); - br_enc32le(tmp + 16, q[1]); - br_enc32le(tmp + 20, q[3]); - br_enc32le(tmp + 24, q[5]); - br_enc32le(tmp + 28, q[7]); - - if (len <= 32) { - xorbuf(buf, tmp, len); - cc ++; - if (len > 16) { - cc ++; - } - break; - } - xorbuf(buf, tmp, 32); - buf += 32; - len -= 32; - cc += 2; - } - return cc; -} - -/* see bearssl_block.h */ -const br_block_ctr_class br_aes_ct_ctr_vtable = { - sizeof(br_aes_ct_ctr_keys), - 16, - 4, - (void (*)(const br_block_ctr_class **, const void *, size_t)) - &br_aes_ct_ctr_init, - (uint32_t (*)(const br_block_ctr_class *const *, - const void *, uint32_t, void *, size_t)) - &br_aes_ct_ctr_run -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/aes_ct_ctrcbc.c b/src/tls/bearssl/aes_ct_ctrcbc.c deleted file mode 100644 index e3a2d0df7..000000000 --- a/src/tls/bearssl/aes_ct_ctrcbc.c +++ /dev/null @@ -1,427 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_block.h */ -void -br_aes_ct_ctrcbc_init(br_aes_ct_ctrcbc_keys *ctx, - const void *key, size_t len) -{ - ctx->vtable = &br_aes_ct_ctrcbc_vtable; - ctx->num_rounds = br_aes_ct_keysched(ctx->skey, key, len); -} - -static void -xorbuf(void *dst, const void *src, size_t len) -{ - unsigned char *d; - const unsigned char *s; - - d = dst; - s = src; - while (len -- > 0) { - *d ++ ^= *s ++; - } -} - -/* see bearssl_block.h */ -void -br_aes_ct_ctrcbc_ctr(const br_aes_ct_ctrcbc_keys *ctx, - void *ctr, void *data, size_t len) -{ - unsigned char *buf; - unsigned char *ivbuf; - uint32_t iv0, iv1, iv2, iv3; - uint32_t sk_exp[120]; - - br_aes_ct_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); - - /* - * We keep the counter as four 32-bit values, with big-endian - * convention, because that's what is expected for purposes of - * incrementing the counter value. - */ - ivbuf = ctr; - iv0 = br_dec32be(ivbuf + 0); - iv1 = br_dec32be(ivbuf + 4); - iv2 = br_dec32be(ivbuf + 8); - iv3 = br_dec32be(ivbuf + 12); - - buf = data; - while (len > 0) { - uint32_t q[8], carry; - unsigned char tmp[32]; - - /* - * The bitslice implementation expects values in - * little-endian convention, so we have to byteswap them. - */ - q[0] = br_swap32(iv0); - q[2] = br_swap32(iv1); - q[4] = br_swap32(iv2); - q[6] = br_swap32(iv3); - iv3 ++; - carry = ~(iv3 | -iv3) >> 31; - iv2 += carry; - carry &= -(~(iv2 | -iv2) >> 31); - iv1 += carry; - carry &= -(~(iv1 | -iv1) >> 31); - iv0 += carry; - q[1] = br_swap32(iv0); - q[3] = br_swap32(iv1); - q[5] = br_swap32(iv2); - q[7] = br_swap32(iv3); - if (len > 16) { - iv3 ++; - carry = ~(iv3 | -iv3) >> 31; - iv2 += carry; - carry &= -(~(iv2 | -iv2) >> 31); - iv1 += carry; - carry &= -(~(iv1 | -iv1) >> 31); - iv0 += carry; - } - - br_aes_ct_ortho(q); - br_aes_ct_bitslice_encrypt(ctx->num_rounds, sk_exp, q); - br_aes_ct_ortho(q); - - br_enc32le(tmp, q[0]); - br_enc32le(tmp + 4, q[2]); - br_enc32le(tmp + 8, q[4]); - br_enc32le(tmp + 12, q[6]); - br_enc32le(tmp + 16, q[1]); - br_enc32le(tmp + 20, q[3]); - br_enc32le(tmp + 24, q[5]); - br_enc32le(tmp + 28, q[7]); - - if (len <= 32) { - xorbuf(buf, tmp, len); - break; - } - xorbuf(buf, tmp, 32); - buf += 32; - len -= 32; - } - br_enc32be(ivbuf + 0, iv0); - br_enc32be(ivbuf + 4, iv1); - br_enc32be(ivbuf + 8, iv2); - br_enc32be(ivbuf + 12, iv3); -} - -/* see bearssl_block.h */ -void -br_aes_ct_ctrcbc_mac(const br_aes_ct_ctrcbc_keys *ctx, - void *cbcmac, const void *data, size_t len) -{ - const unsigned char *buf; - uint32_t cm0, cm1, cm2, cm3; - uint32_t q[8]; - uint32_t sk_exp[120]; - - br_aes_ct_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); - - buf = data; - cm0 = br_dec32le((unsigned char *)cbcmac + 0); - cm1 = br_dec32le((unsigned char *)cbcmac + 4); - cm2 = br_dec32le((unsigned char *)cbcmac + 8); - cm3 = br_dec32le((unsigned char *)cbcmac + 12); - q[1] = 0; - q[3] = 0; - q[5] = 0; - q[7] = 0; - - while (len > 0) { - q[0] = cm0 ^ br_dec32le(buf + 0); - q[2] = cm1 ^ br_dec32le(buf + 4); - q[4] = cm2 ^ br_dec32le(buf + 8); - q[6] = cm3 ^ br_dec32le(buf + 12); - - br_aes_ct_ortho(q); - br_aes_ct_bitslice_encrypt(ctx->num_rounds, sk_exp, q); - br_aes_ct_ortho(q); - - cm0 = q[0]; - cm1 = q[2]; - cm2 = q[4]; - cm3 = q[6]; - buf += 16; - len -= 16; - } - - br_enc32le((unsigned char *)cbcmac + 0, cm0); - br_enc32le((unsigned char *)cbcmac + 4, cm1); - br_enc32le((unsigned char *)cbcmac + 8, cm2); - br_enc32le((unsigned char *)cbcmac + 12, cm3); -} - -/* see bearssl_block.h */ -void -br_aes_ct_ctrcbc_encrypt(const br_aes_ct_ctrcbc_keys *ctx, - void *ctr, void *cbcmac, void *data, size_t len) -{ - /* - * When encrypting, the CBC-MAC processing must be lagging by - * one block, since it operates on the encrypted values, so - * it must wait for that encryption to complete. - */ - - unsigned char *buf; - unsigned char *ivbuf; - uint32_t iv0, iv1, iv2, iv3; - uint32_t cm0, cm1, cm2, cm3; - uint32_t sk_exp[120]; - int first_iter; - - br_aes_ct_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); - - /* - * We keep the counter as four 32-bit values, with big-endian - * convention, because that's what is expected for purposes of - * incrementing the counter value. - */ - ivbuf = ctr; - iv0 = br_dec32be(ivbuf + 0); - iv1 = br_dec32be(ivbuf + 4); - iv2 = br_dec32be(ivbuf + 8); - iv3 = br_dec32be(ivbuf + 12); - - /* - * The current CBC-MAC value is kept in little-endian convention. - */ - cm0 = br_dec32le((unsigned char *)cbcmac + 0); - cm1 = br_dec32le((unsigned char *)cbcmac + 4); - cm2 = br_dec32le((unsigned char *)cbcmac + 8); - cm3 = br_dec32le((unsigned char *)cbcmac + 12); - - buf = data; - first_iter = 1; - while (len > 0) { - uint32_t q[8], carry; - - /* - * The bitslice implementation expects values in - * little-endian convention, so we have to byteswap them. - */ - q[0] = br_swap32(iv0); - q[2] = br_swap32(iv1); - q[4] = br_swap32(iv2); - q[6] = br_swap32(iv3); - iv3 ++; - carry = ~(iv3 | -iv3) >> 31; - iv2 += carry; - carry &= -(~(iv2 | -iv2) >> 31); - iv1 += carry; - carry &= -(~(iv1 | -iv1) >> 31); - iv0 += carry; - - /* - * The odd values are used for CBC-MAC. - */ - q[1] = cm0; - q[3] = cm1; - q[5] = cm2; - q[7] = cm3; - - br_aes_ct_ortho(q); - br_aes_ct_bitslice_encrypt(ctx->num_rounds, sk_exp, q); - br_aes_ct_ortho(q); - - /* - * We do the XOR with the plaintext in 32-bit registers, - * so that the value are available for CBC-MAC processing - * as well. - */ - q[0] ^= br_dec32le(buf + 0); - q[2] ^= br_dec32le(buf + 4); - q[4] ^= br_dec32le(buf + 8); - q[6] ^= br_dec32le(buf + 12); - br_enc32le(buf + 0, q[0]); - br_enc32le(buf + 4, q[2]); - br_enc32le(buf + 8, q[4]); - br_enc32le(buf + 12, q[6]); - - buf += 16; - len -= 16; - - /* - * We set the cm* values to the block to encrypt in the - * next iteration. - */ - if (first_iter) { - first_iter = 0; - cm0 ^= q[0]; - cm1 ^= q[2]; - cm2 ^= q[4]; - cm3 ^= q[6]; - } else { - cm0 = q[0] ^ q[1]; - cm1 = q[2] ^ q[3]; - cm2 = q[4] ^ q[5]; - cm3 = q[6] ^ q[7]; - } - - /* - * If this was the last iteration, then compute the - * extra block encryption to complete CBC-MAC. - */ - if (len == 0) { - q[0] = cm0; - q[2] = cm1; - q[4] = cm2; - q[6] = cm3; - br_aes_ct_ortho(q); - br_aes_ct_bitslice_encrypt(ctx->num_rounds, sk_exp, q); - br_aes_ct_ortho(q); - cm0 = q[0]; - cm1 = q[2]; - cm2 = q[4]; - cm3 = q[6]; - break; - } - } - - br_enc32be(ivbuf + 0, iv0); - br_enc32be(ivbuf + 4, iv1); - br_enc32be(ivbuf + 8, iv2); - br_enc32be(ivbuf + 12, iv3); - br_enc32le((unsigned char *)cbcmac + 0, cm0); - br_enc32le((unsigned char *)cbcmac + 4, cm1); - br_enc32le((unsigned char *)cbcmac + 8, cm2); - br_enc32le((unsigned char *)cbcmac + 12, cm3); -} - -/* see bearssl_block.h */ -void -br_aes_ct_ctrcbc_decrypt(const br_aes_ct_ctrcbc_keys *ctx, - void *ctr, void *cbcmac, void *data, size_t len) -{ - unsigned char *buf; - unsigned char *ivbuf; - uint32_t iv0, iv1, iv2, iv3; - uint32_t cm0, cm1, cm2, cm3; - uint32_t sk_exp[120]; - - br_aes_ct_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); - - /* - * We keep the counter as four 32-bit values, with big-endian - * convention, because that's what is expected for purposes of - * incrementing the counter value. - */ - ivbuf = ctr; - iv0 = br_dec32be(ivbuf + 0); - iv1 = br_dec32be(ivbuf + 4); - iv2 = br_dec32be(ivbuf + 8); - iv3 = br_dec32be(ivbuf + 12); - - /* - * The current CBC-MAC value is kept in little-endian convention. - */ - cm0 = br_dec32le((unsigned char *)cbcmac + 0); - cm1 = br_dec32le((unsigned char *)cbcmac + 4); - cm2 = br_dec32le((unsigned char *)cbcmac + 8); - cm3 = br_dec32le((unsigned char *)cbcmac + 12); - - buf = data; - while (len > 0) { - uint32_t q[8], carry; - unsigned char tmp[16]; - - /* - * The bitslice implementation expects values in - * little-endian convention, so we have to byteswap them. - */ - q[0] = br_swap32(iv0); - q[2] = br_swap32(iv1); - q[4] = br_swap32(iv2); - q[6] = br_swap32(iv3); - iv3 ++; - carry = ~(iv3 | -iv3) >> 31; - iv2 += carry; - carry &= -(~(iv2 | -iv2) >> 31); - iv1 += carry; - carry &= -(~(iv1 | -iv1) >> 31); - iv0 += carry; - - /* - * The odd values are used for CBC-MAC. - */ - q[1] = cm0 ^ br_dec32le(buf + 0); - q[3] = cm1 ^ br_dec32le(buf + 4); - q[5] = cm2 ^ br_dec32le(buf + 8); - q[7] = cm3 ^ br_dec32le(buf + 12); - - br_aes_ct_ortho(q); - br_aes_ct_bitslice_encrypt(ctx->num_rounds, sk_exp, q); - br_aes_ct_ortho(q); - - br_enc32le(tmp + 0, q[0]); - br_enc32le(tmp + 4, q[2]); - br_enc32le(tmp + 8, q[4]); - br_enc32le(tmp + 12, q[6]); - xorbuf(buf, tmp, 16); - cm0 = q[1]; - cm1 = q[3]; - cm2 = q[5]; - cm3 = q[7]; - buf += 16; - len -= 16; - } - - br_enc32be(ivbuf + 0, iv0); - br_enc32be(ivbuf + 4, iv1); - br_enc32be(ivbuf + 8, iv2); - br_enc32be(ivbuf + 12, iv3); - br_enc32le((unsigned char *)cbcmac + 0, cm0); - br_enc32le((unsigned char *)cbcmac + 4, cm1); - br_enc32le((unsigned char *)cbcmac + 8, cm2); - br_enc32le((unsigned char *)cbcmac + 12, cm3); -} - -/* see bearssl_block.h */ -const br_block_ctrcbc_class br_aes_ct_ctrcbc_vtable = { - sizeof(br_aes_ct_ctrcbc_keys), - 16, - 4, - (void (*)(const br_block_ctrcbc_class **, const void *, size_t)) - &br_aes_ct_ctrcbc_init, - (void (*)(const br_block_ctrcbc_class *const *, - void *, void *, void *, size_t)) - &br_aes_ct_ctrcbc_encrypt, - (void (*)(const br_block_ctrcbc_class *const *, - void *, void *, void *, size_t)) - &br_aes_ct_ctrcbc_decrypt, - (void (*)(const br_block_ctrcbc_class *const *, - void *, void *, size_t)) - &br_aes_ct_ctrcbc_ctr, - (void (*)(const br_block_ctrcbc_class *const *, - void *, const void *, size_t)) - &br_aes_ct_ctrcbc_mac -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/aes_ct_dec.c b/src/tls/bearssl/aes_ct_dec.c deleted file mode 100644 index 9564fd1bd..000000000 --- a/src/tls/bearssl/aes_ct_dec.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_aes_ct_bitslice_invSbox(uint32_t *q) -{ - /* - * AES S-box is: - * S(x) = A(I(x)) ^ 0x63 - * where I() is inversion in GF(256), and A() is a linear - * transform (0 is formally defined to be its own inverse). - * Since inversion is an involution, the inverse S-box can be - * computed from the S-box as: - * iS(x) = B(S(B(x ^ 0x63)) ^ 0x63) - * where B() is the inverse of A(). Indeed, for any y in GF(256): - * iS(S(y)) = B(A(I(B(A(I(y)) ^ 0x63 ^ 0x63))) ^ 0x63 ^ 0x63) = y - * - * Note: we reuse the implementation of the forward S-box, - * instead of duplicating it here, so that total code size is - * lower. By merging the B() transforms into the S-box circuit - * we could make faster CBC decryption, but CBC decryption is - * already quite faster than CBC encryption because we can - * process two blocks in parallel. - */ - uint32_t q0, q1, q2, q3, q4, q5, q6, q7; - - q0 = ~q[0]; - q1 = ~q[1]; - q2 = q[2]; - q3 = q[3]; - q4 = q[4]; - q5 = ~q[5]; - q6 = ~q[6]; - q7 = q[7]; - q[7] = q1 ^ q4 ^ q6; - q[6] = q0 ^ q3 ^ q5; - q[5] = q7 ^ q2 ^ q4; - q[4] = q6 ^ q1 ^ q3; - q[3] = q5 ^ q0 ^ q2; - q[2] = q4 ^ q7 ^ q1; - q[1] = q3 ^ q6 ^ q0; - q[0] = q2 ^ q5 ^ q7; - - br_aes_ct_bitslice_Sbox(q); - - q0 = ~q[0]; - q1 = ~q[1]; - q2 = q[2]; - q3 = q[3]; - q4 = q[4]; - q5 = ~q[5]; - q6 = ~q[6]; - q7 = q[7]; - q[7] = q1 ^ q4 ^ q6; - q[6] = q0 ^ q3 ^ q5; - q[5] = q7 ^ q2 ^ q4; - q[4] = q6 ^ q1 ^ q3; - q[3] = q5 ^ q0 ^ q2; - q[2] = q4 ^ q7 ^ q1; - q[1] = q3 ^ q6 ^ q0; - q[0] = q2 ^ q5 ^ q7; -} - -static void -add_round_key(uint32_t *q, const uint32_t *sk) -{ - int i; - - for (i = 0; i < 8; i ++) { - q[i] ^= sk[i]; - } -} - -static void -inv_shift_rows(uint32_t *q) -{ - int i; - - for (i = 0; i < 8; i ++) { - uint32_t x; - - x = q[i]; - q[i] = (x & 0x000000FF) - | ((x & 0x00003F00) << 2) | ((x & 0x0000C000) >> 6) - | ((x & 0x000F0000) << 4) | ((x & 0x00F00000) >> 4) - | ((x & 0x03000000) << 6) | ((x & 0xFC000000) >> 2); - } -} - -static inline uint32_t -rotr16(uint32_t x) -{ - return (x << 16) | (x >> 16); -} - -static void -inv_mix_columns(uint32_t *q) -{ - uint32_t q0, q1, q2, q3, q4, q5, q6, q7; - uint32_t r0, r1, r2, r3, r4, r5, r6, r7; - - q0 = q[0]; - q1 = q[1]; - q2 = q[2]; - q3 = q[3]; - q4 = q[4]; - q5 = q[5]; - q6 = q[6]; - q7 = q[7]; - r0 = (q0 >> 8) | (q0 << 24); - r1 = (q1 >> 8) | (q1 << 24); - r2 = (q2 >> 8) | (q2 << 24); - r3 = (q3 >> 8) | (q3 << 24); - r4 = (q4 >> 8) | (q4 << 24); - r5 = (q5 >> 8) | (q5 << 24); - r6 = (q6 >> 8) | (q6 << 24); - r7 = (q7 >> 8) | (q7 << 24); - - q[0] = q5 ^ q6 ^ q7 ^ r0 ^ r5 ^ r7 ^ rotr16(q0 ^ q5 ^ q6 ^ r0 ^ r5); - q[1] = q0 ^ q5 ^ r0 ^ r1 ^ r5 ^ r6 ^ r7 ^ rotr16(q1 ^ q5 ^ q7 ^ r1 ^ r5 ^ r6); - q[2] = q0 ^ q1 ^ q6 ^ r1 ^ r2 ^ r6 ^ r7 ^ rotr16(q0 ^ q2 ^ q6 ^ r2 ^ r6 ^ r7); - q[3] = q0 ^ q1 ^ q2 ^ q5 ^ q6 ^ r0 ^ r2 ^ r3 ^ r5 ^ rotr16(q0 ^ q1 ^ q3 ^ q5 ^ q6 ^ q7 ^ r0 ^ r3 ^ r5 ^ r7); - q[4] = q1 ^ q2 ^ q3 ^ q5 ^ r1 ^ r3 ^ r4 ^ r5 ^ r6 ^ r7 ^ rotr16(q1 ^ q2 ^ q4 ^ q5 ^ q7 ^ r1 ^ r4 ^ r5 ^ r6); - q[5] = q2 ^ q3 ^ q4 ^ q6 ^ r2 ^ r4 ^ r5 ^ r6 ^ r7 ^ rotr16(q2 ^ q3 ^ q5 ^ q6 ^ r2 ^ r5 ^ r6 ^ r7); - q[6] = q3 ^ q4 ^ q5 ^ q7 ^ r3 ^ r5 ^ r6 ^ r7 ^ rotr16(q3 ^ q4 ^ q6 ^ q7 ^ r3 ^ r6 ^ r7); - q[7] = q4 ^ q5 ^ q6 ^ r4 ^ r6 ^ r7 ^ rotr16(q4 ^ q5 ^ q7 ^ r4 ^ r7); -} - -/* see inner.h */ -void -br_aes_ct_bitslice_decrypt(unsigned num_rounds, - const uint32_t *skey, uint32_t *q) -{ - unsigned u; - - add_round_key(q, skey + (num_rounds << 3)); - for (u = num_rounds - 1; u > 0; u --) { - inv_shift_rows(q); - br_aes_ct_bitslice_invSbox(q); - add_round_key(q, skey + (u << 3)); - inv_mix_columns(q); - } - inv_shift_rows(q); - br_aes_ct_bitslice_invSbox(q); - add_round_key(q, skey); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/aes_ct_enc.c b/src/tls/bearssl/aes_ct_enc.c deleted file mode 100644 index a4cf32635..000000000 --- a/src/tls/bearssl/aes_ct_enc.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -static inline void -add_round_key(uint32_t *q, const uint32_t *sk) -{ - q[0] ^= sk[0]; - q[1] ^= sk[1]; - q[2] ^= sk[2]; - q[3] ^= sk[3]; - q[4] ^= sk[4]; - q[5] ^= sk[5]; - q[6] ^= sk[6]; - q[7] ^= sk[7]; -} - -static inline void -shift_rows(uint32_t *q) -{ - int i; - - for (i = 0; i < 8; i ++) { - uint32_t x; - - x = q[i]; - q[i] = (x & 0x000000FF) - | ((x & 0x0000FC00) >> 2) | ((x & 0x00000300) << 6) - | ((x & 0x00F00000) >> 4) | ((x & 0x000F0000) << 4) - | ((x & 0xC0000000) >> 6) | ((x & 0x3F000000) << 2); - } -} - -static inline uint32_t -rotr16(uint32_t x) -{ - return (x << 16) | (x >> 16); -} - -static inline void -mix_columns(uint32_t *q) -{ - uint32_t q0, q1, q2, q3, q4, q5, q6, q7; - uint32_t r0, r1, r2, r3, r4, r5, r6, r7; - - q0 = q[0]; - q1 = q[1]; - q2 = q[2]; - q3 = q[3]; - q4 = q[4]; - q5 = q[5]; - q6 = q[6]; - q7 = q[7]; - r0 = (q0 >> 8) | (q0 << 24); - r1 = (q1 >> 8) | (q1 << 24); - r2 = (q2 >> 8) | (q2 << 24); - r3 = (q3 >> 8) | (q3 << 24); - r4 = (q4 >> 8) | (q4 << 24); - r5 = (q5 >> 8) | (q5 << 24); - r6 = (q6 >> 8) | (q6 << 24); - r7 = (q7 >> 8) | (q7 << 24); - - q[0] = q7 ^ r7 ^ r0 ^ rotr16(q0 ^ r0); - q[1] = q0 ^ r0 ^ q7 ^ r7 ^ r1 ^ rotr16(q1 ^ r1); - q[2] = q1 ^ r1 ^ r2 ^ rotr16(q2 ^ r2); - q[3] = q2 ^ r2 ^ q7 ^ r7 ^ r3 ^ rotr16(q3 ^ r3); - q[4] = q3 ^ r3 ^ q7 ^ r7 ^ r4 ^ rotr16(q4 ^ r4); - q[5] = q4 ^ r4 ^ r5 ^ rotr16(q5 ^ r5); - q[6] = q5 ^ r5 ^ r6 ^ rotr16(q6 ^ r6); - q[7] = q6 ^ r6 ^ r7 ^ rotr16(q7 ^ r7); -} - -/* see inner.h */ -void -br_aes_ct_bitslice_encrypt(unsigned num_rounds, - const uint32_t *skey, uint32_t *q) -{ - unsigned u; - - add_round_key(q, skey); - for (u = 1; u < num_rounds; u ++) { - br_aes_ct_bitslice_Sbox(q); - shift_rows(q); - mix_columns(q); - add_round_key(q, skey + (u << 3)); - } - br_aes_ct_bitslice_Sbox(q); - shift_rows(q); - add_round_key(q, skey + (num_rounds << 3)); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/aes_pwr8.c b/src/tls/bearssl/aes_pwr8.c deleted file mode 100644 index eae3ce3b0..000000000 --- a/src/tls/bearssl/aes_pwr8.c +++ /dev/null @@ -1,451 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#define BR_POWER_ASM_MACROS 1 -#include "inner.h" - -/* - * This code contains the AES key schedule implementation using the - * POWER8 opcodes. - */ - -#if BR_POWER8 - -static void -key_schedule_128(unsigned char *sk, const unsigned char *key) -{ - long cc; - - static const uint32_t fmod[] = { 0x11B, 0x11B, 0x11B, 0x11B }; - -#if BR_POWER8_LE - static const uint32_t idx2be[] = { - 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C - }; -#endif - - cc = 0; - - /* - * We use the VSX instructions for loading and storing the - * key/subkeys, since they support unaligned accesses. The rest - * of the computation is VMX only. VMX register 0 is VSX - * register 32. - */ - asm volatile ( - - /* - * v0 = all-zero word - * v1 = constant -8 / +8, copied into four words - * v2 = current subkey - * v3 = Rcon (x4 words) - * v6 = constant 8, copied into four words - * v7 = constant 0x11B, copied into four words - * v8 = constant for byteswapping words - */ - vspltisw(0, 0) -#if BR_POWER8_LE - vspltisw(1, -8) -#else - vspltisw(1, 8) -#endif - lxvw4x(34, 0, %[key]) - vspltisw(3, 1) - vspltisw(6, 8) - lxvw4x(39, 0, %[fmod]) -#if BR_POWER8_LE - lxvw4x(40, 0, %[idx2be]) -#endif - - /* - * First subkey is a copy of the key itself. - */ -#if BR_POWER8_LE - vperm(4, 2, 2, 8) - stxvw4x(36, 0, %[sk]) -#else - stxvw4x(34, 0, %[sk]) -#endif - - /* - * Loop must run 10 times. - */ - li(%[cc], 10) - mtctr(%[cc]) - label(loop) - /* Increment subkey address */ - addi(%[sk], %[sk], 16) - - /* Compute SubWord(RotWord(temp)) xor Rcon (into v4, splat) */ - vrlw(4, 2, 1) - vsbox(4, 4) -#if BR_POWER8_LE - vxor(4, 4, 3) -#else - vsldoi(5, 3, 0, 3) - vxor(4, 4, 5) -#endif - vspltw(4, 4, 3) - - /* XOR words for next subkey */ - vsldoi(5, 0, 2, 12) - vxor(2, 2, 5) - vsldoi(5, 0, 2, 12) - vxor(2, 2, 5) - vsldoi(5, 0, 2, 12) - vxor(2, 2, 5) - vxor(2, 2, 4) - - /* Store next subkey */ -#if BR_POWER8_LE - vperm(4, 2, 2, 8) - stxvw4x(36, 0, %[sk]) -#else - stxvw4x(34, 0, %[sk]) -#endif - - /* Update Rcon */ - vadduwm(3, 3, 3) - vsrw(4, 3, 6) - vsubuwm(4, 0, 4) - vand(4, 4, 7) - vxor(3, 3, 4) - - bdnz(loop) - -: [sk] "+b" (sk), [cc] "+b" (cc) -: [key] "b" (key), [fmod] "b" (fmod) -#if BR_POWER8_LE - , [idx2be] "b" (idx2be) -#endif -: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "ctr", "memory" - ); -} - -static void -key_schedule_192(unsigned char *sk, const unsigned char *key) -{ - long cc; - -#if BR_POWER8_LE - static const uint32_t idx2be[] = { - 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C - }; -#endif - - cc = 0; - - /* - * We use the VSX instructions for loading and storing the - * key/subkeys, since they support unaligned accesses. The rest - * of the computation is VMX only. VMX register 0 is VSX - * register 32. - */ - asm volatile ( - - /* - * v0 = all-zero word - * v1 = constant -8 / +8, copied into four words - * v2, v3 = current subkey - * v5 = Rcon (x4 words) (already shifted on big-endian) - * v6 = constant 8, copied into four words - * v8 = constant for byteswapping words - * - * The left two words of v3 are ignored. - */ - vspltisw(0, 0) -#if BR_POWER8_LE - vspltisw(1, -8) -#else - vspltisw(1, 8) -#endif - li(%[cc], 8) - lxvw4x(34, 0, %[key]) - lxvw4x(35, %[cc], %[key]) - vsldoi(3, 3, 0, 8) - vspltisw(5, 1) -#if !BR_POWER8_LE - vsldoi(5, 5, 0, 3) -#endif - vspltisw(6, 8) -#if BR_POWER8_LE - lxvw4x(40, 0, %[idx2be]) -#endif - - /* - * Loop must run 8 times. Each iteration produces 256 - * bits of subkeys, with a 64-bit overlap. - */ - li(%[cc], 8) - mtctr(%[cc]) - li(%[cc], 16) - label(loop) - - /* - * Last 6 words in v2:v3l. Compute next 6 words into - * v3r:v4. - */ - vrlw(10, 3, 1) - vsbox(10, 10) - vxor(10, 10, 5) - vspltw(10, 10, 1) - vsldoi(11, 0, 10, 8) - - vsldoi(12, 0, 2, 12) - vxor(12, 2, 12) - vsldoi(13, 0, 12, 12) - vxor(12, 12, 13) - vsldoi(13, 0, 12, 12) - vxor(12, 12, 13) - - vspltw(13, 12, 3) - vxor(13, 13, 3) - vsldoi(14, 0, 3, 12) - vxor(13, 13, 14) - - vsldoi(4, 12, 13, 8) - vsldoi(14, 0, 3, 8) - vsldoi(3, 14, 12, 8) - - vxor(3, 3, 11) - vxor(4, 4, 10) - - /* - * Update Rcon. Since for a 192-bit key, we use only 8 - * such constants, we will not hit the field modulus, - * so a simple shift (addition) works well. - */ - vadduwm(5, 5, 5) - - /* - * Write out the two left 128-bit words - */ -#if BR_POWER8_LE - vperm(10, 2, 2, 8) - vperm(11, 3, 3, 8) - stxvw4x(42, 0, %[sk]) - stxvw4x(43, %[cc], %[sk]) -#else - stxvw4x(34, 0, %[sk]) - stxvw4x(35, %[cc], %[sk]) -#endif - addi(%[sk], %[sk], 24) - - /* - * Shift words for next iteration. - */ - vsldoi(2, 3, 4, 8) - vsldoi(3, 4, 0, 8) - - bdnz(loop) - - /* - * The loop wrote the first 50 subkey words, but we need - * to produce 52, so we must do one last write. - */ -#if BR_POWER8_LE - vperm(10, 2, 2, 8) - stxvw4x(42, 0, %[sk]) -#else - stxvw4x(34, 0, %[sk]) -#endif - -: [sk] "+b" (sk), [cc] "+b" (cc) -: [key] "b" (key) -#if BR_POWER8_LE - , [idx2be] "b" (idx2be) -#endif -: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", - "v8", "v9", "v10", "v11", "v12", "v13", "v14", "ctr", "memory" - ); -} - -static void -key_schedule_256(unsigned char *sk, const unsigned char *key) -{ - long cc; - -#if BR_POWER8_LE - static const uint32_t idx2be[] = { - 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C - }; -#endif - - cc = 0; - - /* - * We use the VSX instructions for loading and storing the - * key/subkeys, since they support unaligned accesses. The rest - * of the computation is VMX only. VMX register 0 is VSX - * register 32. - */ - asm volatile ( - - /* - * v0 = all-zero word - * v1 = constant -8 / +8, copied into four words - * v2, v3 = current subkey - * v6 = Rcon (x4 words) (already shifted on big-endian) - * v7 = constant 8, copied into four words - * v8 = constant for byteswapping words - * - * The left two words of v3 are ignored. - */ - vspltisw(0, 0) -#if BR_POWER8_LE - vspltisw(1, -8) -#else - vspltisw(1, 8) -#endif - li(%[cc], 16) - lxvw4x(34, 0, %[key]) - lxvw4x(35, %[cc], %[key]) - vspltisw(6, 1) -#if !BR_POWER8_LE - vsldoi(6, 6, 0, 3) -#endif - vspltisw(7, 8) -#if BR_POWER8_LE - lxvw4x(40, 0, %[idx2be]) -#endif - - /* - * Loop must run 7 times. Each iteration produces two - * subkeys. - */ - li(%[cc], 7) - mtctr(%[cc]) - li(%[cc], 16) - label(loop) - - /* - * Current words are in v2:v3. Compute next word in v4. - */ - vrlw(10, 3, 1) - vsbox(10, 10) - vxor(10, 10, 6) - vspltw(10, 10, 3) - - vsldoi(4, 0, 2, 12) - vxor(4, 2, 4) - vsldoi(5, 0, 4, 12) - vxor(4, 4, 5) - vsldoi(5, 0, 4, 12) - vxor(4, 4, 5) - vxor(4, 4, 10) - - /* - * Then other word in v5. - */ - vsbox(10, 4) - vspltw(10, 10, 3) - - vsldoi(5, 0, 3, 12) - vxor(5, 3, 5) - vsldoi(11, 0, 5, 12) - vxor(5, 5, 11) - vsldoi(11, 0, 5, 12) - vxor(5, 5, 11) - vxor(5, 5, 10) - - /* - * Update Rcon. Since for a 256-bit key, we use only 7 - * such constants, we will not hit the field modulus, - * so a simple shift (addition) works well. - */ - vadduwm(6, 6, 6) - - /* - * Write out the two left 128-bit words - */ -#if BR_POWER8_LE - vperm(10, 2, 2, 8) - vperm(11, 3, 3, 8) - stxvw4x(42, 0, %[sk]) - stxvw4x(43, %[cc], %[sk]) -#else - stxvw4x(34, 0, %[sk]) - stxvw4x(35, %[cc], %[sk]) -#endif - addi(%[sk], %[sk], 32) - - /* - * Replace v2:v3 with v4:v5. - */ - vxor(2, 0, 4) - vxor(3, 0, 5) - - bdnz(loop) - - /* - * The loop wrote the first 14 subkeys, but we need 15, - * so we must do an extra write. - */ -#if BR_POWER8_LE - vperm(10, 2, 2, 8) - stxvw4x(42, 0, %[sk]) -#else - stxvw4x(34, 0, %[sk]) -#endif - -: [sk] "+b" (sk), [cc] "+b" (cc) -: [key] "b" (key) -#if BR_POWER8_LE - , [idx2be] "b" (idx2be) -#endif -: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", - "v8", "v9", "v10", "v11", "v12", "v13", "v14", "ctr", "memory" - ); -} - -/* see inner.h */ -int -br_aes_pwr8_supported(void) -{ - return 1; -} - -/* see inner.h */ -unsigned -br_aes_pwr8_keysched(unsigned char *sk, const void *key, size_t len) -{ - switch (len) { - case 16: - key_schedule_128(sk, key); - return 10; - case 24: - key_schedule_192(sk, key); - return 12; - default: - key_schedule_256(sk, key); - return 14; - } -} - -#endif - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/aes_pwr8_cbcdec.c b/src/tls/bearssl/aes_pwr8_cbcdec.c deleted file mode 100644 index 272665eaf..000000000 --- a/src/tls/bearssl/aes_pwr8_cbcdec.c +++ /dev/null @@ -1,676 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#define BR_POWER_ASM_MACROS 1 -#include "inner.h" - -#if BR_POWER8 - -/* see bearssl_block.h */ -void -br_aes_pwr8_cbcdec_init(br_aes_pwr8_cbcdec_keys *ctx, - const void *key, size_t len) -{ - ctx->vtable = &br_aes_pwr8_cbcdec_vtable; - ctx->num_rounds = br_aes_pwr8_keysched(ctx->skey.skni, key, len); -} - -static void -cbcdec_128(const unsigned char *sk, - const unsigned char *iv, unsigned char *buf, size_t num_blocks) -{ - long cc0, cc1, cc2, cc3; - -#if BR_POWER8_LE - static const uint32_t idx2be[] = { - 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C - }; -#endif - - cc0 = 0; - cc1 = 16; - cc2 = 32; - cc3 = 48; - asm volatile ( - - /* - * Load subkeys into v0..v10 - */ - lxvw4x(32, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(33, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(34, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(35, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(36, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(37, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(38, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(39, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(40, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(41, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(42, %[cc0], %[sk]) - li(%[cc0], 0) - -#if BR_POWER8_LE - /* - * v15 = constant for byteswapping words - */ - lxvw4x(47, 0, %[idx2be]) -#endif - /* - * Load IV into v24. - */ - lxvw4x(56, 0, %[iv]) -#if BR_POWER8_LE - vperm(24, 24, 24, 15) -#endif - - mtctr(%[num_blocks]) - label(loop) - /* - * Load next ciphertext words in v16..v19. Also save them - * in v20..v23. - */ - lxvw4x(48, %[cc0], %[buf]) - lxvw4x(49, %[cc1], %[buf]) - lxvw4x(50, %[cc2], %[buf]) - lxvw4x(51, %[cc3], %[buf]) -#if BR_POWER8_LE - vperm(16, 16, 16, 15) - vperm(17, 17, 17, 15) - vperm(18, 18, 18, 15) - vperm(19, 19, 19, 15) -#endif - vand(20, 16, 16) - vand(21, 17, 17) - vand(22, 18, 18) - vand(23, 19, 19) - - /* - * Decrypt the blocks. - */ - vxor(16, 16, 10) - vxor(17, 17, 10) - vxor(18, 18, 10) - vxor(19, 19, 10) - vncipher(16, 16, 9) - vncipher(17, 17, 9) - vncipher(18, 18, 9) - vncipher(19, 19, 9) - vncipher(16, 16, 8) - vncipher(17, 17, 8) - vncipher(18, 18, 8) - vncipher(19, 19, 8) - vncipher(16, 16, 7) - vncipher(17, 17, 7) - vncipher(18, 18, 7) - vncipher(19, 19, 7) - vncipher(16, 16, 6) - vncipher(17, 17, 6) - vncipher(18, 18, 6) - vncipher(19, 19, 6) - vncipher(16, 16, 5) - vncipher(17, 17, 5) - vncipher(18, 18, 5) - vncipher(19, 19, 5) - vncipher(16, 16, 4) - vncipher(17, 17, 4) - vncipher(18, 18, 4) - vncipher(19, 19, 4) - vncipher(16, 16, 3) - vncipher(17, 17, 3) - vncipher(18, 18, 3) - vncipher(19, 19, 3) - vncipher(16, 16, 2) - vncipher(17, 17, 2) - vncipher(18, 18, 2) - vncipher(19, 19, 2) - vncipher(16, 16, 1) - vncipher(17, 17, 1) - vncipher(18, 18, 1) - vncipher(19, 19, 1) - vncipherlast(16, 16, 0) - vncipherlast(17, 17, 0) - vncipherlast(18, 18, 0) - vncipherlast(19, 19, 0) - - /* - * XOR decrypted blocks with IV / previous block. - */ - vxor(16, 16, 24) - vxor(17, 17, 20) - vxor(18, 18, 21) - vxor(19, 19, 22) - - /* - * Store back result (with byteswap) - */ -#if BR_POWER8_LE - vperm(16, 16, 16, 15) - vperm(17, 17, 17, 15) - vperm(18, 18, 18, 15) - vperm(19, 19, 19, 15) -#endif - stxvw4x(48, %[cc0], %[buf]) - stxvw4x(49, %[cc1], %[buf]) - stxvw4x(50, %[cc2], %[buf]) - stxvw4x(51, %[cc3], %[buf]) - - /* - * Fourth encrypted block is IV for next run. - */ - vand(24, 23, 23) - - addi(%[buf], %[buf], 64) - - bdnz(loop) - -: [cc0] "+b" (cc0), [cc1] "+b" (cc1), [cc2] "+b" (cc2), [cc3] "+b" (cc3), - [buf] "+b" (buf) -: [sk] "b" (sk), [iv] "b" (iv), [num_blocks] "b" (num_blocks >> 2) -#if BR_POWER8_LE - , [idx2be] "b" (idx2be) -#endif -: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", - "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", - "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", - "ctr", "memory" - ); -} - -static void -cbcdec_192(const unsigned char *sk, - const unsigned char *iv, unsigned char *buf, size_t num_blocks) -{ - long cc0, cc1, cc2, cc3; - -#if BR_POWER8_LE - static const uint32_t idx2be[] = { - 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C - }; -#endif - - cc0 = 0; - cc1 = 16; - cc2 = 32; - cc3 = 48; - asm volatile ( - - /* - * Load subkeys into v0..v12 - */ - lxvw4x(32, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(33, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(34, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(35, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(36, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(37, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(38, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(39, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(40, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(41, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(42, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(43, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(44, %[cc0], %[sk]) - li(%[cc0], 0) - -#if BR_POWER8_LE - /* - * v15 = constant for byteswapping words - */ - lxvw4x(47, 0, %[idx2be]) -#endif - /* - * Load IV into v24. - */ - lxvw4x(56, 0, %[iv]) -#if BR_POWER8_LE - vperm(24, 24, 24, 15) -#endif - - mtctr(%[num_blocks]) - label(loop) - /* - * Load next ciphertext words in v16..v19. Also save them - * in v20..v23. - */ - lxvw4x(48, %[cc0], %[buf]) - lxvw4x(49, %[cc1], %[buf]) - lxvw4x(50, %[cc2], %[buf]) - lxvw4x(51, %[cc3], %[buf]) -#if BR_POWER8_LE - vperm(16, 16, 16, 15) - vperm(17, 17, 17, 15) - vperm(18, 18, 18, 15) - vperm(19, 19, 19, 15) -#endif - vand(20, 16, 16) - vand(21, 17, 17) - vand(22, 18, 18) - vand(23, 19, 19) - - /* - * Decrypt the blocks. - */ - vxor(16, 16, 12) - vxor(17, 17, 12) - vxor(18, 18, 12) - vxor(19, 19, 12) - vncipher(16, 16, 11) - vncipher(17, 17, 11) - vncipher(18, 18, 11) - vncipher(19, 19, 11) - vncipher(16, 16, 10) - vncipher(17, 17, 10) - vncipher(18, 18, 10) - vncipher(19, 19, 10) - vncipher(16, 16, 9) - vncipher(17, 17, 9) - vncipher(18, 18, 9) - vncipher(19, 19, 9) - vncipher(16, 16, 8) - vncipher(17, 17, 8) - vncipher(18, 18, 8) - vncipher(19, 19, 8) - vncipher(16, 16, 7) - vncipher(17, 17, 7) - vncipher(18, 18, 7) - vncipher(19, 19, 7) - vncipher(16, 16, 6) - vncipher(17, 17, 6) - vncipher(18, 18, 6) - vncipher(19, 19, 6) - vncipher(16, 16, 5) - vncipher(17, 17, 5) - vncipher(18, 18, 5) - vncipher(19, 19, 5) - vncipher(16, 16, 4) - vncipher(17, 17, 4) - vncipher(18, 18, 4) - vncipher(19, 19, 4) - vncipher(16, 16, 3) - vncipher(17, 17, 3) - vncipher(18, 18, 3) - vncipher(19, 19, 3) - vncipher(16, 16, 2) - vncipher(17, 17, 2) - vncipher(18, 18, 2) - vncipher(19, 19, 2) - vncipher(16, 16, 1) - vncipher(17, 17, 1) - vncipher(18, 18, 1) - vncipher(19, 19, 1) - vncipherlast(16, 16, 0) - vncipherlast(17, 17, 0) - vncipherlast(18, 18, 0) - vncipherlast(19, 19, 0) - - /* - * XOR decrypted blocks with IV / previous block. - */ - vxor(16, 16, 24) - vxor(17, 17, 20) - vxor(18, 18, 21) - vxor(19, 19, 22) - - /* - * Store back result (with byteswap) - */ -#if BR_POWER8_LE - vperm(16, 16, 16, 15) - vperm(17, 17, 17, 15) - vperm(18, 18, 18, 15) - vperm(19, 19, 19, 15) -#endif - stxvw4x(48, %[cc0], %[buf]) - stxvw4x(49, %[cc1], %[buf]) - stxvw4x(50, %[cc2], %[buf]) - stxvw4x(51, %[cc3], %[buf]) - - /* - * Fourth encrypted block is IV for next run. - */ - vand(24, 23, 23) - - addi(%[buf], %[buf], 64) - - bdnz(loop) - -: [cc0] "+b" (cc0), [cc1] "+b" (cc1), [cc2] "+b" (cc2), [cc3] "+b" (cc3), - [buf] "+b" (buf) -: [sk] "b" (sk), [iv] "b" (iv), [num_blocks] "b" (num_blocks >> 2) -#if BR_POWER8_LE - , [idx2be] "b" (idx2be) -#endif -: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", - "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", - "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", - "ctr", "memory" - ); -} - -static void -cbcdec_256(const unsigned char *sk, - const unsigned char *iv, unsigned char *buf, size_t num_blocks) -{ - long cc0, cc1, cc2, cc3; - -#if BR_POWER8_LE - static const uint32_t idx2be[] = { - 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C - }; - -#endif - - cc0 = 0; - cc1 = 16; - cc2 = 32; - cc3 = 48; - asm volatile ( - - /* - * Load subkeys into v0..v14 - */ - lxvw4x(32, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(33, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(34, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(35, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(36, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(37, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(38, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(39, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(40, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(41, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(42, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(43, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(44, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(45, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(46, %[cc0], %[sk]) - li(%[cc0], 0) - -#if BR_POWER8_LE - /* - * v15 = constant for byteswapping words - */ - lxvw4x(47, 0, %[idx2be]) -#endif - /* - * Load IV into v24. - */ - lxvw4x(56, 0, %[iv]) -#if BR_POWER8_LE - vperm(24, 24, 24, 15) -#endif - - mtctr(%[num_blocks]) - label(loop) - /* - * Load next ciphertext words in v16..v19. Also save them - * in v20..v23. - */ - lxvw4x(48, %[cc0], %[buf]) - lxvw4x(49, %[cc1], %[buf]) - lxvw4x(50, %[cc2], %[buf]) - lxvw4x(51, %[cc3], %[buf]) -#if BR_POWER8_LE - vperm(16, 16, 16, 15) - vperm(17, 17, 17, 15) - vperm(18, 18, 18, 15) - vperm(19, 19, 19, 15) -#endif - vand(20, 16, 16) - vand(21, 17, 17) - vand(22, 18, 18) - vand(23, 19, 19) - - /* - * Decrypt the blocks. - */ - vxor(16, 16, 14) - vxor(17, 17, 14) - vxor(18, 18, 14) - vxor(19, 19, 14) - vncipher(16, 16, 13) - vncipher(17, 17, 13) - vncipher(18, 18, 13) - vncipher(19, 19, 13) - vncipher(16, 16, 12) - vncipher(17, 17, 12) - vncipher(18, 18, 12) - vncipher(19, 19, 12) - vncipher(16, 16, 11) - vncipher(17, 17, 11) - vncipher(18, 18, 11) - vncipher(19, 19, 11) - vncipher(16, 16, 10) - vncipher(17, 17, 10) - vncipher(18, 18, 10) - vncipher(19, 19, 10) - vncipher(16, 16, 9) - vncipher(17, 17, 9) - vncipher(18, 18, 9) - vncipher(19, 19, 9) - vncipher(16, 16, 8) - vncipher(17, 17, 8) - vncipher(18, 18, 8) - vncipher(19, 19, 8) - vncipher(16, 16, 7) - vncipher(17, 17, 7) - vncipher(18, 18, 7) - vncipher(19, 19, 7) - vncipher(16, 16, 6) - vncipher(17, 17, 6) - vncipher(18, 18, 6) - vncipher(19, 19, 6) - vncipher(16, 16, 5) - vncipher(17, 17, 5) - vncipher(18, 18, 5) - vncipher(19, 19, 5) - vncipher(16, 16, 4) - vncipher(17, 17, 4) - vncipher(18, 18, 4) - vncipher(19, 19, 4) - vncipher(16, 16, 3) - vncipher(17, 17, 3) - vncipher(18, 18, 3) - vncipher(19, 19, 3) - vncipher(16, 16, 2) - vncipher(17, 17, 2) - vncipher(18, 18, 2) - vncipher(19, 19, 2) - vncipher(16, 16, 1) - vncipher(17, 17, 1) - vncipher(18, 18, 1) - vncipher(19, 19, 1) - vncipherlast(16, 16, 0) - vncipherlast(17, 17, 0) - vncipherlast(18, 18, 0) - vncipherlast(19, 19, 0) - - /* - * XOR decrypted blocks with IV / previous block. - */ - vxor(16, 16, 24) - vxor(17, 17, 20) - vxor(18, 18, 21) - vxor(19, 19, 22) - - /* - * Store back result (with byteswap) - */ -#if BR_POWER8_LE - vperm(16, 16, 16, 15) - vperm(17, 17, 17, 15) - vperm(18, 18, 18, 15) - vperm(19, 19, 19, 15) -#endif - stxvw4x(48, %[cc0], %[buf]) - stxvw4x(49, %[cc1], %[buf]) - stxvw4x(50, %[cc2], %[buf]) - stxvw4x(51, %[cc3], %[buf]) - - /* - * Fourth encrypted block is IV for next run. - */ - vand(24, 23, 23) - - addi(%[buf], %[buf], 64) - - bdnz(loop) - -: [cc0] "+b" (cc0), [cc1] "+b" (cc1), [cc2] "+b" (cc2), [cc3] "+b" (cc3), - [buf] "+b" (buf) -: [sk] "b" (sk), [iv] "b" (iv), [num_blocks] "b" (num_blocks >> 2) -#if BR_POWER8_LE - , [idx2be] "b" (idx2be) -#endif -: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", - "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", - "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", - "ctr", "memory" - ); -} - -/* see bearssl_block.h */ -void -br_aes_pwr8_cbcdec_run(const br_aes_pwr8_cbcdec_keys *ctx, - void *iv, void *data, size_t len) -{ - unsigned char nextiv[16]; - unsigned char *buf; - - if (len == 0) { - return; - } - buf = data; - memcpy(nextiv, buf + len - 16, 16); - if (len >= 64) { - size_t num_blocks; - unsigned char tmp[16]; - - num_blocks = (len >> 4) & ~(size_t)3; - memcpy(tmp, buf + (num_blocks << 4) - 16, 16); - switch (ctx->num_rounds) { - case 10: - cbcdec_128(ctx->skey.skni, iv, buf, num_blocks); - break; - case 12: - cbcdec_192(ctx->skey.skni, iv, buf, num_blocks); - break; - default: - cbcdec_256(ctx->skey.skni, iv, buf, num_blocks); - break; - } - buf += num_blocks << 4; - len &= 63; - memcpy(iv, tmp, 16); - } - if (len > 0) { - unsigned char tmp[64]; - - memcpy(tmp, buf, len); - memset(tmp + len, 0, (sizeof tmp) - len); - switch (ctx->num_rounds) { - case 10: - cbcdec_128(ctx->skey.skni, iv, tmp, 4); - break; - case 12: - cbcdec_192(ctx->skey.skni, iv, tmp, 4); - break; - default: - cbcdec_256(ctx->skey.skni, iv, tmp, 4); - break; - } - memcpy(buf, tmp, len); - } - memcpy(iv, nextiv, 16); -} - -/* see bearssl_block.h */ -const br_block_cbcdec_class br_aes_pwr8_cbcdec_vtable = { - sizeof(br_aes_pwr8_cbcdec_keys), - 16, - 4, - (void (*)(const br_block_cbcdec_class **, const void *, size_t)) - &br_aes_pwr8_cbcdec_init, - (void (*)(const br_block_cbcdec_class *const *, void *, void *, size_t)) - &br_aes_pwr8_cbcdec_run -}; - -/* see bearssl_block.h */ -const br_block_cbcdec_class * -br_aes_pwr8_cbcdec_get_vtable(void) -{ - return br_aes_pwr8_supported() ? &br_aes_pwr8_cbcdec_vtable : NULL; -} - -#else - -/* see bearssl_block.h */ -const br_block_cbcdec_class * -br_aes_pwr8_cbcdec_get_vtable(void) -{ - return NULL; -} - -#endif - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/aes_pwr8_cbcenc.c b/src/tls/bearssl/aes_pwr8_cbcenc.c deleted file mode 100644 index 4f14ec6e4..000000000 --- a/src/tls/bearssl/aes_pwr8_cbcenc.c +++ /dev/null @@ -1,422 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#define BR_POWER_ASM_MACROS 1 -#include "inner.h" - -#if BR_POWER8 - -/* see bearssl_block.h */ -void -br_aes_pwr8_cbcenc_init(br_aes_pwr8_cbcenc_keys *ctx, - const void *key, size_t len) -{ - ctx->vtable = &br_aes_pwr8_cbcenc_vtable; - ctx->num_rounds = br_aes_pwr8_keysched(ctx->skey.skni, key, len); -} - -static void -cbcenc_128(const unsigned char *sk, - const unsigned char *iv, unsigned char *buf, size_t len) -{ - long cc; - -#if BR_POWER8_LE - static const uint32_t idx2be[] = { - 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C - }; -#endif - - cc = 0; - asm volatile ( - - /* - * Load subkeys into v0..v10 - */ - lxvw4x(32, %[cc], %[sk]) - addi(%[cc], %[cc], 16) - lxvw4x(33, %[cc], %[sk]) - addi(%[cc], %[cc], 16) - lxvw4x(34, %[cc], %[sk]) - addi(%[cc], %[cc], 16) - lxvw4x(35, %[cc], %[sk]) - addi(%[cc], %[cc], 16) - lxvw4x(36, %[cc], %[sk]) - addi(%[cc], %[cc], 16) - lxvw4x(37, %[cc], %[sk]) - addi(%[cc], %[cc], 16) - lxvw4x(38, %[cc], %[sk]) - addi(%[cc], %[cc], 16) - lxvw4x(39, %[cc], %[sk]) - addi(%[cc], %[cc], 16) - lxvw4x(40, %[cc], %[sk]) - addi(%[cc], %[cc], 16) - lxvw4x(41, %[cc], %[sk]) - addi(%[cc], %[cc], 16) - lxvw4x(42, %[cc], %[sk]) - -#if BR_POWER8_LE - /* - * v15 = constant for byteswapping words - */ - lxvw4x(47, 0, %[idx2be]) -#endif - /* - * Load IV into v16. - */ - lxvw4x(48, 0, %[iv]) -#if BR_POWER8_LE - vperm(16, 16, 16, 15) -#endif - - mtctr(%[num_blocks]) - label(loop) - /* - * Load next plaintext word and XOR with current IV. - */ - lxvw4x(49, 0, %[buf]) -#if BR_POWER8_LE - vperm(17, 17, 17, 15) -#endif - vxor(16, 16, 17) - - /* - * Encrypt the block. - */ - vxor(16, 16, 0) - vcipher(16, 16, 1) - vcipher(16, 16, 2) - vcipher(16, 16, 3) - vcipher(16, 16, 4) - vcipher(16, 16, 5) - vcipher(16, 16, 6) - vcipher(16, 16, 7) - vcipher(16, 16, 8) - vcipher(16, 16, 9) - vcipherlast(16, 16, 10) - - /* - * Store back result (with byteswap) - */ -#if BR_POWER8_LE - vperm(17, 16, 16, 15) - stxvw4x(49, 0, %[buf]) -#else - stxvw4x(48, 0, %[buf]) -#endif - addi(%[buf], %[buf], 16) - - bdnz(loop) - -: [cc] "+b" (cc), [buf] "+b" (buf) -: [sk] "b" (sk), [iv] "b" (iv), [num_blocks] "b" (len >> 4) -#if BR_POWER8_LE - , [idx2be] "b" (idx2be) -#endif -: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", - "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", - "ctr", "memory" - ); -} - -static void -cbcenc_192(const unsigned char *sk, - const unsigned char *iv, unsigned char *buf, size_t len) -{ - long cc; - -#if BR_POWER8_LE - static const uint32_t idx2be[] = { - 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C - }; -#endif - - cc = 0; - asm volatile ( - - /* - * Load subkeys into v0..v12 - */ - lxvw4x(32, %[cc], %[sk]) - addi(%[cc], %[cc], 16) - lxvw4x(33, %[cc], %[sk]) - addi(%[cc], %[cc], 16) - lxvw4x(34, %[cc], %[sk]) - addi(%[cc], %[cc], 16) - lxvw4x(35, %[cc], %[sk]) - addi(%[cc], %[cc], 16) - lxvw4x(36, %[cc], %[sk]) - addi(%[cc], %[cc], 16) - lxvw4x(37, %[cc], %[sk]) - addi(%[cc], %[cc], 16) - lxvw4x(38, %[cc], %[sk]) - addi(%[cc], %[cc], 16) - lxvw4x(39, %[cc], %[sk]) - addi(%[cc], %[cc], 16) - lxvw4x(40, %[cc], %[sk]) - addi(%[cc], %[cc], 16) - lxvw4x(41, %[cc], %[sk]) - addi(%[cc], %[cc], 16) - lxvw4x(42, %[cc], %[sk]) - addi(%[cc], %[cc], 16) - lxvw4x(43, %[cc], %[sk]) - addi(%[cc], %[cc], 16) - lxvw4x(44, %[cc], %[sk]) - -#if BR_POWER8_LE - /* - * v15 = constant for byteswapping words - */ - lxvw4x(47, 0, %[idx2be]) -#endif - /* - * Load IV into v16. - */ - lxvw4x(48, 0, %[iv]) -#if BR_POWER8_LE - vperm(16, 16, 16, 15) -#endif - - mtctr(%[num_blocks]) - label(loop) - /* - * Load next plaintext word and XOR with current IV. - */ - lxvw4x(49, 0, %[buf]) -#if BR_POWER8_LE - vperm(17, 17, 17, 15) -#endif - vxor(16, 16, 17) - - /* - * Encrypt the block. - */ - vxor(16, 16, 0) - vcipher(16, 16, 1) - vcipher(16, 16, 2) - vcipher(16, 16, 3) - vcipher(16, 16, 4) - vcipher(16, 16, 5) - vcipher(16, 16, 6) - vcipher(16, 16, 7) - vcipher(16, 16, 8) - vcipher(16, 16, 9) - vcipher(16, 16, 10) - vcipher(16, 16, 11) - vcipherlast(16, 16, 12) - - /* - * Store back result (with byteswap) - */ -#if BR_POWER8_LE - vperm(17, 16, 16, 15) - stxvw4x(49, 0, %[buf]) -#else - stxvw4x(48, 0, %[buf]) -#endif - addi(%[buf], %[buf], 16) - - bdnz(loop) - -: [cc] "+b" (cc), [buf] "+b" (buf) -: [sk] "b" (sk), [iv] "b" (iv), [num_blocks] "b" (len >> 4) -#if BR_POWER8_LE - , [idx2be] "b" (idx2be) -#endif -: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", - "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", - "ctr", "memory" - ); -} - -static void -cbcenc_256(const unsigned char *sk, - const unsigned char *iv, unsigned char *buf, size_t len) -{ - long cc; - -#if BR_POWER8_LE - static const uint32_t idx2be[] = { - 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C - }; -#endif - - cc = 0; - asm volatile ( - - /* - * Load subkeys into v0..v14 - */ - lxvw4x(32, %[cc], %[sk]) - addi(%[cc], %[cc], 16) - lxvw4x(33, %[cc], %[sk]) - addi(%[cc], %[cc], 16) - lxvw4x(34, %[cc], %[sk]) - addi(%[cc], %[cc], 16) - lxvw4x(35, %[cc], %[sk]) - addi(%[cc], %[cc], 16) - lxvw4x(36, %[cc], %[sk]) - addi(%[cc], %[cc], 16) - lxvw4x(37, %[cc], %[sk]) - addi(%[cc], %[cc], 16) - lxvw4x(38, %[cc], %[sk]) - addi(%[cc], %[cc], 16) - lxvw4x(39, %[cc], %[sk]) - addi(%[cc], %[cc], 16) - lxvw4x(40, %[cc], %[sk]) - addi(%[cc], %[cc], 16) - lxvw4x(41, %[cc], %[sk]) - addi(%[cc], %[cc], 16) - lxvw4x(42, %[cc], %[sk]) - addi(%[cc], %[cc], 16) - lxvw4x(43, %[cc], %[sk]) - addi(%[cc], %[cc], 16) - lxvw4x(44, %[cc], %[sk]) - addi(%[cc], %[cc], 16) - lxvw4x(45, %[cc], %[sk]) - addi(%[cc], %[cc], 16) - lxvw4x(46, %[cc], %[sk]) - -#if BR_POWER8_LE - /* - * v15 = constant for byteswapping words - */ - lxvw4x(47, 0, %[idx2be]) -#endif - /* - * Load IV into v16. - */ - lxvw4x(48, 0, %[iv]) -#if BR_POWER8_LE - vperm(16, 16, 16, 15) -#endif - - mtctr(%[num_blocks]) - label(loop) - /* - * Load next plaintext word and XOR with current IV. - */ - lxvw4x(49, 0, %[buf]) -#if BR_POWER8_LE - vperm(17, 17, 17, 15) -#endif - vxor(16, 16, 17) - - /* - * Encrypt the block. - */ - vxor(16, 16, 0) - vcipher(16, 16, 1) - vcipher(16, 16, 2) - vcipher(16, 16, 3) - vcipher(16, 16, 4) - vcipher(16, 16, 5) - vcipher(16, 16, 6) - vcipher(16, 16, 7) - vcipher(16, 16, 8) - vcipher(16, 16, 9) - vcipher(16, 16, 10) - vcipher(16, 16, 11) - vcipher(16, 16, 12) - vcipher(16, 16, 13) - vcipherlast(16, 16, 14) - - /* - * Store back result (with byteswap) - */ -#if BR_POWER8_LE - vperm(17, 16, 16, 15) - stxvw4x(49, 0, %[buf]) -#else - stxvw4x(48, 0, %[buf]) -#endif - addi(%[buf], %[buf], 16) - - bdnz(loop) - -: [cc] "+b" (cc), [buf] "+b" (buf) -: [sk] "b" (sk), [iv] "b" (iv), [num_blocks] "b" (len >> 4) -#if BR_POWER8_LE - , [idx2be] "b" (idx2be) -#endif -: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", - "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", - "ctr", "memory" - ); -} - -/* see bearssl_block.h */ -void -br_aes_pwr8_cbcenc_run(const br_aes_pwr8_cbcenc_keys *ctx, - void *iv, void *data, size_t len) -{ - if (len > 0) { - switch (ctx->num_rounds) { - case 10: - cbcenc_128(ctx->skey.skni, iv, data, len); - break; - case 12: - cbcenc_192(ctx->skey.skni, iv, data, len); - break; - default: - cbcenc_256(ctx->skey.skni, iv, data, len); - break; - } - memcpy(iv, (unsigned char *)data + (len - 16), 16); - } -} - -/* see bearssl_block.h */ -const br_block_cbcenc_class br_aes_pwr8_cbcenc_vtable = { - sizeof(br_aes_pwr8_cbcenc_keys), - 16, - 4, - (void (*)(const br_block_cbcenc_class **, const void *, size_t)) - &br_aes_pwr8_cbcenc_init, - (void (*)(const br_block_cbcenc_class *const *, void *, void *, size_t)) - &br_aes_pwr8_cbcenc_run -}; - -/* see bearssl_block.h */ -const br_block_cbcenc_class * -br_aes_pwr8_cbcenc_get_vtable(void) -{ - return br_aes_pwr8_supported() ? &br_aes_pwr8_cbcenc_vtable : NULL; -} - -#else - -/* see bearssl_block.h */ -const br_block_cbcenc_class * -br_aes_pwr8_cbcenc_get_vtable(void) -{ - return NULL; -} - -#endif - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/aes_pwr8_ctr.c b/src/tls/bearssl/aes_pwr8_ctr.c deleted file mode 100644 index 49babbf0a..000000000 --- a/src/tls/bearssl/aes_pwr8_ctr.c +++ /dev/null @@ -1,723 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#define BR_POWER_ASM_MACROS 1 -#include "inner.h" - -#if BR_POWER8 - -/* see bearssl_block.h */ -void -br_aes_pwr8_ctr_init(br_aes_pwr8_ctr_keys *ctx, - const void *key, size_t len) -{ - ctx->vtable = &br_aes_pwr8_ctr_vtable; - ctx->num_rounds = br_aes_pwr8_keysched(ctx->skey.skni, key, len); -} - -static void -ctr_128(const unsigned char *sk, const unsigned char *ivbuf, - unsigned char *buf, size_t num_blocks) -{ - long cc0, cc1, cc2, cc3; - -#if BR_POWER8_LE - static const uint32_t idx2be[] = { - 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C - }; -#endif - static const uint32_t ctrinc[] = { - 0, 0, 0, 4 - }; - - cc0 = 0; - cc1 = 16; - cc2 = 32; - cc3 = 48; - asm volatile ( - - /* - * Load subkeys into v0..v10 - */ - lxvw4x(32, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(33, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(34, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(35, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(36, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(37, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(38, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(39, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(40, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(41, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(42, %[cc0], %[sk]) - li(%[cc0], 0) - -#if BR_POWER8_LE - /* - * v15 = constant for byteswapping words - */ - lxvw4x(47, 0, %[idx2be]) -#endif - /* - * v28 = increment for IV counter. - */ - lxvw4x(60, 0, %[ctrinc]) - - /* - * Load IV into v16..v19 - */ - lxvw4x(48, %[cc0], %[ivbuf]) - lxvw4x(49, %[cc1], %[ivbuf]) - lxvw4x(50, %[cc2], %[ivbuf]) - lxvw4x(51, %[cc3], %[ivbuf]) -#if BR_POWER8_LE - vperm(16, 16, 16, 15) - vperm(17, 17, 17, 15) - vperm(18, 18, 18, 15) - vperm(19, 19, 19, 15) -#endif - - mtctr(%[num_blocks]) - label(loop) - /* - * Compute next IV into v24..v27 - */ - vadduwm(24, 16, 28) - vadduwm(25, 17, 28) - vadduwm(26, 18, 28) - vadduwm(27, 19, 28) - - /* - * Load next data blocks. We do this early on but we - * won't need them until IV encryption is done. - */ - lxvw4x(52, %[cc0], %[buf]) - lxvw4x(53, %[cc1], %[buf]) - lxvw4x(54, %[cc2], %[buf]) - lxvw4x(55, %[cc3], %[buf]) - - /* - * Encrypt the current IV. - */ - vxor(16, 16, 0) - vxor(17, 17, 0) - vxor(18, 18, 0) - vxor(19, 19, 0) - vcipher(16, 16, 1) - vcipher(17, 17, 1) - vcipher(18, 18, 1) - vcipher(19, 19, 1) - vcipher(16, 16, 2) - vcipher(17, 17, 2) - vcipher(18, 18, 2) - vcipher(19, 19, 2) - vcipher(16, 16, 3) - vcipher(17, 17, 3) - vcipher(18, 18, 3) - vcipher(19, 19, 3) - vcipher(16, 16, 4) - vcipher(17, 17, 4) - vcipher(18, 18, 4) - vcipher(19, 19, 4) - vcipher(16, 16, 5) - vcipher(17, 17, 5) - vcipher(18, 18, 5) - vcipher(19, 19, 5) - vcipher(16, 16, 6) - vcipher(17, 17, 6) - vcipher(18, 18, 6) - vcipher(19, 19, 6) - vcipher(16, 16, 7) - vcipher(17, 17, 7) - vcipher(18, 18, 7) - vcipher(19, 19, 7) - vcipher(16, 16, 8) - vcipher(17, 17, 8) - vcipher(18, 18, 8) - vcipher(19, 19, 8) - vcipher(16, 16, 9) - vcipher(17, 17, 9) - vcipher(18, 18, 9) - vcipher(19, 19, 9) - vcipherlast(16, 16, 10) - vcipherlast(17, 17, 10) - vcipherlast(18, 18, 10) - vcipherlast(19, 19, 10) - -#if BR_POWER8_LE - vperm(16, 16, 16, 15) - vperm(17, 17, 17, 15) - vperm(18, 18, 18, 15) - vperm(19, 19, 19, 15) -#endif - - /* - * Load next plaintext word and XOR with encrypted IV. - */ - vxor(16, 20, 16) - vxor(17, 21, 17) - vxor(18, 22, 18) - vxor(19, 23, 19) - stxvw4x(48, %[cc0], %[buf]) - stxvw4x(49, %[cc1], %[buf]) - stxvw4x(50, %[cc2], %[buf]) - stxvw4x(51, %[cc3], %[buf]) - - addi(%[buf], %[buf], 64) - - /* - * Update IV. - */ - vand(16, 24, 24) - vand(17, 25, 25) - vand(18, 26, 26) - vand(19, 27, 27) - - bdnz(loop) - -: [cc0] "+b" (cc0), [cc1] "+b" (cc1), [cc2] "+b" (cc2), [cc3] "+b" (cc3), - [buf] "+b" (buf) -: [sk] "b" (sk), [ivbuf] "b" (ivbuf), [num_blocks] "b" (num_blocks >> 2), - [ctrinc] "b" (ctrinc) -#if BR_POWER8_LE - , [idx2be] "b" (idx2be) -#endif -: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", - "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", - "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", - "ctr", "memory" - ); -} - -static void -ctr_192(const unsigned char *sk, const unsigned char *ivbuf, - unsigned char *buf, size_t num_blocks) -{ - long cc0, cc1, cc2, cc3; - -#if BR_POWER8_LE - static const uint32_t idx2be[] = { - 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C - }; -#endif - static const uint32_t ctrinc[] = { - 0, 0, 0, 4 - }; - - cc0 = 0; - cc1 = 16; - cc2 = 32; - cc3 = 48; - asm volatile ( - - /* - * Load subkeys into v0..v12 - */ - lxvw4x(32, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(33, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(34, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(35, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(36, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(37, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(38, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(39, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(40, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(41, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(42, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(43, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(44, %[cc0], %[sk]) - li(%[cc0], 0) - -#if BR_POWER8_LE - /* - * v15 = constant for byteswapping words - */ - lxvw4x(47, 0, %[idx2be]) -#endif - /* - * v28 = increment for IV counter. - */ - lxvw4x(60, 0, %[ctrinc]) - - /* - * Load IV into v16..v19 - */ - lxvw4x(48, %[cc0], %[ivbuf]) - lxvw4x(49, %[cc1], %[ivbuf]) - lxvw4x(50, %[cc2], %[ivbuf]) - lxvw4x(51, %[cc3], %[ivbuf]) -#if BR_POWER8_LE - vperm(16, 16, 16, 15) - vperm(17, 17, 17, 15) - vperm(18, 18, 18, 15) - vperm(19, 19, 19, 15) -#endif - - mtctr(%[num_blocks]) - label(loop) - /* - * Compute next IV into v24..v27 - */ - vadduwm(24, 16, 28) - vadduwm(25, 17, 28) - vadduwm(26, 18, 28) - vadduwm(27, 19, 28) - - /* - * Load next data blocks. We do this early on but we - * won't need them until IV encryption is done. - */ - lxvw4x(52, %[cc0], %[buf]) - lxvw4x(53, %[cc1], %[buf]) - lxvw4x(54, %[cc2], %[buf]) - lxvw4x(55, %[cc3], %[buf]) - - /* - * Encrypt the current IV. - */ - vxor(16, 16, 0) - vxor(17, 17, 0) - vxor(18, 18, 0) - vxor(19, 19, 0) - vcipher(16, 16, 1) - vcipher(17, 17, 1) - vcipher(18, 18, 1) - vcipher(19, 19, 1) - vcipher(16, 16, 2) - vcipher(17, 17, 2) - vcipher(18, 18, 2) - vcipher(19, 19, 2) - vcipher(16, 16, 3) - vcipher(17, 17, 3) - vcipher(18, 18, 3) - vcipher(19, 19, 3) - vcipher(16, 16, 4) - vcipher(17, 17, 4) - vcipher(18, 18, 4) - vcipher(19, 19, 4) - vcipher(16, 16, 5) - vcipher(17, 17, 5) - vcipher(18, 18, 5) - vcipher(19, 19, 5) - vcipher(16, 16, 6) - vcipher(17, 17, 6) - vcipher(18, 18, 6) - vcipher(19, 19, 6) - vcipher(16, 16, 7) - vcipher(17, 17, 7) - vcipher(18, 18, 7) - vcipher(19, 19, 7) - vcipher(16, 16, 8) - vcipher(17, 17, 8) - vcipher(18, 18, 8) - vcipher(19, 19, 8) - vcipher(16, 16, 9) - vcipher(17, 17, 9) - vcipher(18, 18, 9) - vcipher(19, 19, 9) - vcipher(16, 16, 10) - vcipher(17, 17, 10) - vcipher(18, 18, 10) - vcipher(19, 19, 10) - vcipher(16, 16, 11) - vcipher(17, 17, 11) - vcipher(18, 18, 11) - vcipher(19, 19, 11) - vcipherlast(16, 16, 12) - vcipherlast(17, 17, 12) - vcipherlast(18, 18, 12) - vcipherlast(19, 19, 12) - -#if BR_POWER8_LE - vperm(16, 16, 16, 15) - vperm(17, 17, 17, 15) - vperm(18, 18, 18, 15) - vperm(19, 19, 19, 15) -#endif - - /* - * Load next plaintext word and XOR with encrypted IV. - */ - vxor(16, 20, 16) - vxor(17, 21, 17) - vxor(18, 22, 18) - vxor(19, 23, 19) - stxvw4x(48, %[cc0], %[buf]) - stxvw4x(49, %[cc1], %[buf]) - stxvw4x(50, %[cc2], %[buf]) - stxvw4x(51, %[cc3], %[buf]) - - addi(%[buf], %[buf], 64) - - /* - * Update IV. - */ - vand(16, 24, 24) - vand(17, 25, 25) - vand(18, 26, 26) - vand(19, 27, 27) - - bdnz(loop) - -: [cc0] "+b" (cc0), [cc1] "+b" (cc1), [cc2] "+b" (cc2), [cc3] "+b" (cc3), - [buf] "+b" (buf) -: [sk] "b" (sk), [ivbuf] "b" (ivbuf), [num_blocks] "b" (num_blocks >> 2), - [ctrinc] "b" (ctrinc) -#if BR_POWER8_LE - , [idx2be] "b" (idx2be) -#endif -: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", - "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", - "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", - "ctr", "memory" - ); -} - -static void -ctr_256(const unsigned char *sk, const unsigned char *ivbuf, - unsigned char *buf, size_t num_blocks) -{ - long cc0, cc1, cc2, cc3; - -#if BR_POWER8_LE - static const uint32_t idx2be[] = { - 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C - }; -#endif - static const uint32_t ctrinc[] = { - 0, 0, 0, 4 - }; - - cc0 = 0; - cc1 = 16; - cc2 = 32; - cc3 = 48; - asm volatile ( - - /* - * Load subkeys into v0..v14 - */ - lxvw4x(32, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(33, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(34, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(35, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(36, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(37, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(38, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(39, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(40, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(41, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(42, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(43, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(44, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(45, %[cc0], %[sk]) - addi(%[cc0], %[cc0], 16) - lxvw4x(46, %[cc0], %[sk]) - li(%[cc0], 0) - -#if BR_POWER8_LE - /* - * v15 = constant for byteswapping words - */ - lxvw4x(47, 0, %[idx2be]) -#endif - /* - * v28 = increment for IV counter. - */ - lxvw4x(60, 0, %[ctrinc]) - - /* - * Load IV into v16..v19 - */ - lxvw4x(48, %[cc0], %[ivbuf]) - lxvw4x(49, %[cc1], %[ivbuf]) - lxvw4x(50, %[cc2], %[ivbuf]) - lxvw4x(51, %[cc3], %[ivbuf]) -#if BR_POWER8_LE - vperm(16, 16, 16, 15) - vperm(17, 17, 17, 15) - vperm(18, 18, 18, 15) - vperm(19, 19, 19, 15) -#endif - - mtctr(%[num_blocks]) - label(loop) - /* - * Compute next IV into v24..v27 - */ - vadduwm(24, 16, 28) - vadduwm(25, 17, 28) - vadduwm(26, 18, 28) - vadduwm(27, 19, 28) - - /* - * Load next data blocks. We do this early on but we - * won't need them until IV encryption is done. - */ - lxvw4x(52, %[cc0], %[buf]) - lxvw4x(53, %[cc1], %[buf]) - lxvw4x(54, %[cc2], %[buf]) - lxvw4x(55, %[cc3], %[buf]) - - /* - * Encrypt the current IV. - */ - vxor(16, 16, 0) - vxor(17, 17, 0) - vxor(18, 18, 0) - vxor(19, 19, 0) - vcipher(16, 16, 1) - vcipher(17, 17, 1) - vcipher(18, 18, 1) - vcipher(19, 19, 1) - vcipher(16, 16, 2) - vcipher(17, 17, 2) - vcipher(18, 18, 2) - vcipher(19, 19, 2) - vcipher(16, 16, 3) - vcipher(17, 17, 3) - vcipher(18, 18, 3) - vcipher(19, 19, 3) - vcipher(16, 16, 4) - vcipher(17, 17, 4) - vcipher(18, 18, 4) - vcipher(19, 19, 4) - vcipher(16, 16, 5) - vcipher(17, 17, 5) - vcipher(18, 18, 5) - vcipher(19, 19, 5) - vcipher(16, 16, 6) - vcipher(17, 17, 6) - vcipher(18, 18, 6) - vcipher(19, 19, 6) - vcipher(16, 16, 7) - vcipher(17, 17, 7) - vcipher(18, 18, 7) - vcipher(19, 19, 7) - vcipher(16, 16, 8) - vcipher(17, 17, 8) - vcipher(18, 18, 8) - vcipher(19, 19, 8) - vcipher(16, 16, 9) - vcipher(17, 17, 9) - vcipher(18, 18, 9) - vcipher(19, 19, 9) - vcipher(16, 16, 10) - vcipher(17, 17, 10) - vcipher(18, 18, 10) - vcipher(19, 19, 10) - vcipher(16, 16, 11) - vcipher(17, 17, 11) - vcipher(18, 18, 11) - vcipher(19, 19, 11) - vcipher(16, 16, 12) - vcipher(17, 17, 12) - vcipher(18, 18, 12) - vcipher(19, 19, 12) - vcipher(16, 16, 13) - vcipher(17, 17, 13) - vcipher(18, 18, 13) - vcipher(19, 19, 13) - vcipherlast(16, 16, 14) - vcipherlast(17, 17, 14) - vcipherlast(18, 18, 14) - vcipherlast(19, 19, 14) - -#if BR_POWER8_LE - vperm(16, 16, 16, 15) - vperm(17, 17, 17, 15) - vperm(18, 18, 18, 15) - vperm(19, 19, 19, 15) -#endif - - /* - * Load next plaintext word and XOR with encrypted IV. - */ - vxor(16, 20, 16) - vxor(17, 21, 17) - vxor(18, 22, 18) - vxor(19, 23, 19) - stxvw4x(48, %[cc0], %[buf]) - stxvw4x(49, %[cc1], %[buf]) - stxvw4x(50, %[cc2], %[buf]) - stxvw4x(51, %[cc3], %[buf]) - - addi(%[buf], %[buf], 64) - - /* - * Update IV. - */ - vand(16, 24, 24) - vand(17, 25, 25) - vand(18, 26, 26) - vand(19, 27, 27) - - bdnz(loop) - -: [cc0] "+b" (cc0), [cc1] "+b" (cc1), [cc2] "+b" (cc2), [cc3] "+b" (cc3), - [buf] "+b" (buf) -: [sk] "b" (sk), [ivbuf] "b" (ivbuf), [num_blocks] "b" (num_blocks >> 2), - [ctrinc] "b" (ctrinc) -#if BR_POWER8_LE - , [idx2be] "b" (idx2be) -#endif -: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", - "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", - "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", - "ctr", "memory" - ); -} - -/* see bearssl_block.h */ -uint32_t -br_aes_pwr8_ctr_run(const br_aes_pwr8_ctr_keys *ctx, - const void *iv, uint32_t cc, void *data, size_t len) -{ - unsigned char *buf; - unsigned char ivbuf[64]; - - buf = data; - memcpy(ivbuf + 0, iv, 12); - memcpy(ivbuf + 16, iv, 12); - memcpy(ivbuf + 32, iv, 12); - memcpy(ivbuf + 48, iv, 12); - if (len >= 64) { - br_enc32be(ivbuf + 12, cc + 0); - br_enc32be(ivbuf + 28, cc + 1); - br_enc32be(ivbuf + 44, cc + 2); - br_enc32be(ivbuf + 60, cc + 3); - switch (ctx->num_rounds) { - case 10: - ctr_128(ctx->skey.skni, ivbuf, buf, - (len >> 4) & ~(size_t)3); - break; - case 12: - ctr_192(ctx->skey.skni, ivbuf, buf, - (len >> 4) & ~(size_t)3); - break; - default: - ctr_256(ctx->skey.skni, ivbuf, buf, - (len >> 4) & ~(size_t)3); - break; - } - cc += (len >> 4) & ~(size_t)3; - buf += len & ~(size_t)63; - len &= 63; - } - if (len > 0) { - unsigned char tmp[64]; - - memcpy(tmp, buf, len); - memset(tmp + len, 0, (sizeof tmp) - len); - br_enc32be(ivbuf + 12, cc + 0); - br_enc32be(ivbuf + 28, cc + 1); - br_enc32be(ivbuf + 44, cc + 2); - br_enc32be(ivbuf + 60, cc + 3); - switch (ctx->num_rounds) { - case 10: - ctr_128(ctx->skey.skni, ivbuf, tmp, 4); - break; - case 12: - ctr_192(ctx->skey.skni, ivbuf, tmp, 4); - break; - default: - ctr_256(ctx->skey.skni, ivbuf, tmp, 4); - break; - } - memcpy(buf, tmp, len); - cc += (len + 15) >> 4; - } - return cc; -} - -/* see bearssl_block.h */ -const br_block_ctr_class br_aes_pwr8_ctr_vtable = { - sizeof(br_aes_pwr8_ctr_keys), - 16, - 4, - (void (*)(const br_block_ctr_class **, const void *, size_t)) - &br_aes_pwr8_ctr_init, - (uint32_t (*)(const br_block_ctr_class *const *, - const void *, uint32_t, void *, size_t)) - &br_aes_pwr8_ctr_run -}; - - -/* see bearssl_block.h */ -const br_block_ctr_class * -br_aes_pwr8_ctr_get_vtable(void) -{ - return br_aes_pwr8_supported() ? &br_aes_pwr8_ctr_vtable : NULL; -} - -#else - -/* see bearssl_block.h */ -const br_block_ctr_class * -br_aes_pwr8_ctr_get_vtable(void) -{ - return NULL; -} - -#endif - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/aes_pwr8_ctrcbc.c b/src/tls/bearssl/aes_pwr8_ctrcbc.c deleted file mode 100644 index 2afd9b461..000000000 --- a/src/tls/bearssl/aes_pwr8_ctrcbc.c +++ /dev/null @@ -1,954 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#define BR_POWER_ASM_MACROS 1 -#include "inner.h" - -#if BR_POWER8 - -/* see bearssl_block.h */ -const br_block_ctrcbc_class * -br_aes_pwr8_ctrcbc_get_vtable(void) -{ - return br_aes_pwr8_supported() ? &br_aes_pwr8_ctrcbc_vtable : NULL; -} - -/* see bearssl_block.h */ -void -br_aes_pwr8_ctrcbc_init(br_aes_pwr8_ctrcbc_keys *ctx, - const void *key, size_t len) -{ - ctx->vtable = &br_aes_pwr8_ctrcbc_vtable; - ctx->num_rounds = br_aes_pwr8_keysched(ctx->skey.skni, key, len); -} - -/* - * Register conventions for CTR + CBC-MAC: - * - * AES subkeys are in registers 0 to 10/12/14 (depending on keys size) - * Register v15 contains the byteswap index register (little-endian only) - * Register v16 contains the CTR counter value - * Register v17 contains the CBC-MAC current value - * Registers v18 to v27 are scratch - * Counter increment uses v28, v29 and v30 - * - * For CTR alone: - * - * AES subkeys are in registers 0 to 10/12/14 (depending on keys size) - * Register v15 contains the byteswap index register (little-endian only) - * Registers v16 to v19 contain the CTR counter values (four blocks) - * Registers v20 to v27 are scratch - * Counter increment uses v28, v29 and v30 - */ - -#define LOAD_SUBKEYS_128 \ - lxvw4x(32, %[cc], %[sk]) \ - addi(%[cc], %[cc], 16) \ - lxvw4x(33, %[cc], %[sk]) \ - addi(%[cc], %[cc], 16) \ - lxvw4x(34, %[cc], %[sk]) \ - addi(%[cc], %[cc], 16) \ - lxvw4x(35, %[cc], %[sk]) \ - addi(%[cc], %[cc], 16) \ - lxvw4x(36, %[cc], %[sk]) \ - addi(%[cc], %[cc], 16) \ - lxvw4x(37, %[cc], %[sk]) \ - addi(%[cc], %[cc], 16) \ - lxvw4x(38, %[cc], %[sk]) \ - addi(%[cc], %[cc], 16) \ - lxvw4x(39, %[cc], %[sk]) \ - addi(%[cc], %[cc], 16) \ - lxvw4x(40, %[cc], %[sk]) \ - addi(%[cc], %[cc], 16) \ - lxvw4x(41, %[cc], %[sk]) \ - addi(%[cc], %[cc], 16) \ - lxvw4x(42, %[cc], %[sk]) - -#define LOAD_SUBKEYS_192 \ - LOAD_SUBKEYS_128 \ - addi(%[cc], %[cc], 16) \ - lxvw4x(43, %[cc], %[sk]) \ - addi(%[cc], %[cc], 16) \ - lxvw4x(44, %[cc], %[sk]) - -#define LOAD_SUBKEYS_256 \ - LOAD_SUBKEYS_192 \ - addi(%[cc], %[cc], 16) \ - lxvw4x(45, %[cc], %[sk]) \ - addi(%[cc], %[cc], 16) \ - lxvw4x(46, %[cc], %[sk]) - -#define BLOCK_ENCRYPT_128(x) \ - vxor(x, x, 0) \ - vcipher(x, x, 1) \ - vcipher(x, x, 2) \ - vcipher(x, x, 3) \ - vcipher(x, x, 4) \ - vcipher(x, x, 5) \ - vcipher(x, x, 6) \ - vcipher(x, x, 7) \ - vcipher(x, x, 8) \ - vcipher(x, x, 9) \ - vcipherlast(x, x, 10) - -#define BLOCK_ENCRYPT_192(x) \ - vxor(x, x, 0) \ - vcipher(x, x, 1) \ - vcipher(x, x, 2) \ - vcipher(x, x, 3) \ - vcipher(x, x, 4) \ - vcipher(x, x, 5) \ - vcipher(x, x, 6) \ - vcipher(x, x, 7) \ - vcipher(x, x, 8) \ - vcipher(x, x, 9) \ - vcipher(x, x, 10) \ - vcipher(x, x, 11) \ - vcipherlast(x, x, 12) - -#define BLOCK_ENCRYPT_256(x) \ - vxor(x, x, 0) \ - vcipher(x, x, 1) \ - vcipher(x, x, 2) \ - vcipher(x, x, 3) \ - vcipher(x, x, 4) \ - vcipher(x, x, 5) \ - vcipher(x, x, 6) \ - vcipher(x, x, 7) \ - vcipher(x, x, 8) \ - vcipher(x, x, 9) \ - vcipher(x, x, 10) \ - vcipher(x, x, 11) \ - vcipher(x, x, 12) \ - vcipher(x, x, 13) \ - vcipherlast(x, x, 14) - -#define BLOCK_ENCRYPT_X2_128(x, y) \ - vxor(x, x, 0) \ - vxor(y, y, 0) \ - vcipher(x, x, 1) \ - vcipher(y, y, 1) \ - vcipher(x, x, 2) \ - vcipher(y, y, 2) \ - vcipher(x, x, 3) \ - vcipher(y, y, 3) \ - vcipher(x, x, 4) \ - vcipher(y, y, 4) \ - vcipher(x, x, 5) \ - vcipher(y, y, 5) \ - vcipher(x, x, 6) \ - vcipher(y, y, 6) \ - vcipher(x, x, 7) \ - vcipher(y, y, 7) \ - vcipher(x, x, 8) \ - vcipher(y, y, 8) \ - vcipher(x, x, 9) \ - vcipher(y, y, 9) \ - vcipherlast(x, x, 10) \ - vcipherlast(y, y, 10) - -#define BLOCK_ENCRYPT_X2_192(x, y) \ - vxor(x, x, 0) \ - vxor(y, y, 0) \ - vcipher(x, x, 1) \ - vcipher(y, y, 1) \ - vcipher(x, x, 2) \ - vcipher(y, y, 2) \ - vcipher(x, x, 3) \ - vcipher(y, y, 3) \ - vcipher(x, x, 4) \ - vcipher(y, y, 4) \ - vcipher(x, x, 5) \ - vcipher(y, y, 5) \ - vcipher(x, x, 6) \ - vcipher(y, y, 6) \ - vcipher(x, x, 7) \ - vcipher(y, y, 7) \ - vcipher(x, x, 8) \ - vcipher(y, y, 8) \ - vcipher(x, x, 9) \ - vcipher(y, y, 9) \ - vcipher(x, x, 10) \ - vcipher(y, y, 10) \ - vcipher(x, x, 11) \ - vcipher(y, y, 11) \ - vcipherlast(x, x, 12) \ - vcipherlast(y, y, 12) - -#define BLOCK_ENCRYPT_X2_256(x, y) \ - vxor(x, x, 0) \ - vxor(y, y, 0) \ - vcipher(x, x, 1) \ - vcipher(y, y, 1) \ - vcipher(x, x, 2) \ - vcipher(y, y, 2) \ - vcipher(x, x, 3) \ - vcipher(y, y, 3) \ - vcipher(x, x, 4) \ - vcipher(y, y, 4) \ - vcipher(x, x, 5) \ - vcipher(y, y, 5) \ - vcipher(x, x, 6) \ - vcipher(y, y, 6) \ - vcipher(x, x, 7) \ - vcipher(y, y, 7) \ - vcipher(x, x, 8) \ - vcipher(y, y, 8) \ - vcipher(x, x, 9) \ - vcipher(y, y, 9) \ - vcipher(x, x, 10) \ - vcipher(y, y, 10) \ - vcipher(x, x, 11) \ - vcipher(y, y, 11) \ - vcipher(x, x, 12) \ - vcipher(y, y, 12) \ - vcipher(x, x, 13) \ - vcipher(y, y, 13) \ - vcipherlast(x, x, 14) \ - vcipherlast(y, y, 14) - -#define BLOCK_ENCRYPT_X4_128(x0, x1, x2, x3) \ - vxor(x0, x0, 0) \ - vxor(x1, x1, 0) \ - vxor(x2, x2, 0) \ - vxor(x3, x3, 0) \ - vcipher(x0, x0, 1) \ - vcipher(x1, x1, 1) \ - vcipher(x2, x2, 1) \ - vcipher(x3, x3, 1) \ - vcipher(x0, x0, 2) \ - vcipher(x1, x1, 2) \ - vcipher(x2, x2, 2) \ - vcipher(x3, x3, 2) \ - vcipher(x0, x0, 3) \ - vcipher(x1, x1, 3) \ - vcipher(x2, x2, 3) \ - vcipher(x3, x3, 3) \ - vcipher(x0, x0, 4) \ - vcipher(x1, x1, 4) \ - vcipher(x2, x2, 4) \ - vcipher(x3, x3, 4) \ - vcipher(x0, x0, 5) \ - vcipher(x1, x1, 5) \ - vcipher(x2, x2, 5) \ - vcipher(x3, x3, 5) \ - vcipher(x0, x0, 6) \ - vcipher(x1, x1, 6) \ - vcipher(x2, x2, 6) \ - vcipher(x3, x3, 6) \ - vcipher(x0, x0, 7) \ - vcipher(x1, x1, 7) \ - vcipher(x2, x2, 7) \ - vcipher(x3, x3, 7) \ - vcipher(x0, x0, 8) \ - vcipher(x1, x1, 8) \ - vcipher(x2, x2, 8) \ - vcipher(x3, x3, 8) \ - vcipher(x0, x0, 9) \ - vcipher(x1, x1, 9) \ - vcipher(x2, x2, 9) \ - vcipher(x3, x3, 9) \ - vcipherlast(x0, x0, 10) \ - vcipherlast(x1, x1, 10) \ - vcipherlast(x2, x2, 10) \ - vcipherlast(x3, x3, 10) - -#define BLOCK_ENCRYPT_X4_192(x0, x1, x2, x3) \ - vxor(x0, x0, 0) \ - vxor(x1, x1, 0) \ - vxor(x2, x2, 0) \ - vxor(x3, x3, 0) \ - vcipher(x0, x0, 1) \ - vcipher(x1, x1, 1) \ - vcipher(x2, x2, 1) \ - vcipher(x3, x3, 1) \ - vcipher(x0, x0, 2) \ - vcipher(x1, x1, 2) \ - vcipher(x2, x2, 2) \ - vcipher(x3, x3, 2) \ - vcipher(x0, x0, 3) \ - vcipher(x1, x1, 3) \ - vcipher(x2, x2, 3) \ - vcipher(x3, x3, 3) \ - vcipher(x0, x0, 4) \ - vcipher(x1, x1, 4) \ - vcipher(x2, x2, 4) \ - vcipher(x3, x3, 4) \ - vcipher(x0, x0, 5) \ - vcipher(x1, x1, 5) \ - vcipher(x2, x2, 5) \ - vcipher(x3, x3, 5) \ - vcipher(x0, x0, 6) \ - vcipher(x1, x1, 6) \ - vcipher(x2, x2, 6) \ - vcipher(x3, x3, 6) \ - vcipher(x0, x0, 7) \ - vcipher(x1, x1, 7) \ - vcipher(x2, x2, 7) \ - vcipher(x3, x3, 7) \ - vcipher(x0, x0, 8) \ - vcipher(x1, x1, 8) \ - vcipher(x2, x2, 8) \ - vcipher(x3, x3, 8) \ - vcipher(x0, x0, 9) \ - vcipher(x1, x1, 9) \ - vcipher(x2, x2, 9) \ - vcipher(x3, x3, 9) \ - vcipher(x0, x0, 10) \ - vcipher(x1, x1, 10) \ - vcipher(x2, x2, 10) \ - vcipher(x3, x3, 10) \ - vcipher(x0, x0, 11) \ - vcipher(x1, x1, 11) \ - vcipher(x2, x2, 11) \ - vcipher(x3, x3, 11) \ - vcipherlast(x0, x0, 12) \ - vcipherlast(x1, x1, 12) \ - vcipherlast(x2, x2, 12) \ - vcipherlast(x3, x3, 12) - -#define BLOCK_ENCRYPT_X4_256(x0, x1, x2, x3) \ - vxor(x0, x0, 0) \ - vxor(x1, x1, 0) \ - vxor(x2, x2, 0) \ - vxor(x3, x3, 0) \ - vcipher(x0, x0, 1) \ - vcipher(x1, x1, 1) \ - vcipher(x2, x2, 1) \ - vcipher(x3, x3, 1) \ - vcipher(x0, x0, 2) \ - vcipher(x1, x1, 2) \ - vcipher(x2, x2, 2) \ - vcipher(x3, x3, 2) \ - vcipher(x0, x0, 3) \ - vcipher(x1, x1, 3) \ - vcipher(x2, x2, 3) \ - vcipher(x3, x3, 3) \ - vcipher(x0, x0, 4) \ - vcipher(x1, x1, 4) \ - vcipher(x2, x2, 4) \ - vcipher(x3, x3, 4) \ - vcipher(x0, x0, 5) \ - vcipher(x1, x1, 5) \ - vcipher(x2, x2, 5) \ - vcipher(x3, x3, 5) \ - vcipher(x0, x0, 6) \ - vcipher(x1, x1, 6) \ - vcipher(x2, x2, 6) \ - vcipher(x3, x3, 6) \ - vcipher(x0, x0, 7) \ - vcipher(x1, x1, 7) \ - vcipher(x2, x2, 7) \ - vcipher(x3, x3, 7) \ - vcipher(x0, x0, 8) \ - vcipher(x1, x1, 8) \ - vcipher(x2, x2, 8) \ - vcipher(x3, x3, 8) \ - vcipher(x0, x0, 9) \ - vcipher(x1, x1, 9) \ - vcipher(x2, x2, 9) \ - vcipher(x3, x3, 9) \ - vcipher(x0, x0, 10) \ - vcipher(x1, x1, 10) \ - vcipher(x2, x2, 10) \ - vcipher(x3, x3, 10) \ - vcipher(x0, x0, 11) \ - vcipher(x1, x1, 11) \ - vcipher(x2, x2, 11) \ - vcipher(x3, x3, 11) \ - vcipher(x0, x0, 12) \ - vcipher(x1, x1, 12) \ - vcipher(x2, x2, 12) \ - vcipher(x3, x3, 12) \ - vcipher(x0, x0, 13) \ - vcipher(x1, x1, 13) \ - vcipher(x2, x2, 13) \ - vcipher(x3, x3, 13) \ - vcipherlast(x0, x0, 14) \ - vcipherlast(x1, x1, 14) \ - vcipherlast(x2, x2, 14) \ - vcipherlast(x3, x3, 14) - -#if BR_POWER8_LE -static const uint32_t idx2be[] = { - 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C -}; - -#define BYTESWAP_INIT lxvw4x(47, 0, %[idx2be]) -#define BYTESWAP(x) vperm(x, x, x, 15) -#define BYTESWAPX(d, s) vperm(d, s, s, 15) -#define BYTESWAP_REG , [idx2be] "b" (idx2be) -#else -#define BYTESWAP_INIT -#define BYTESWAP(x) -#define BYTESWAPX(d, s) vand(d, s, s) -#define BYTESWAP_REG -#endif - -static const uint32_t ctrinc[] = { - 0, 0, 0, 1 -}; - -static const uint32_t ctrinc_x4[] = { - 0, 0, 0, 4 -}; - -#define INCR_128_INIT lxvw4x(60, 0, %[ctrinc]) -#define INCR_128_X4_INIT lxvw4x(60, 0, %[ctrinc_x4]) -#define INCR_128(d, s) \ - vaddcuw(29, s, 28) \ - vadduwm(d, s, 28) \ - vsldoi(30, 29, 29, 4) \ - vaddcuw(29, d, 30) \ - vadduwm(d, d, 30) \ - vsldoi(30, 29, 29, 4) \ - vaddcuw(29, d, 30) \ - vadduwm(d, d, 30) \ - vsldoi(30, 29, 29, 4) \ - vadduwm(d, d, 30) - -#define MKCTR(size) \ -static void \ -ctr_ ## size(const unsigned char *sk, \ - unsigned char *ctrbuf, unsigned char *buf, size_t num_blocks_x4) \ -{ \ - long cc, cc0, cc1, cc2, cc3; \ - \ - cc = 0; \ - cc0 = 0; \ - cc1 = 16; \ - cc2 = 32; \ - cc3 = 48; \ - asm volatile ( \ - \ - /* \ - * Load subkeys into v0..v10 \ - */ \ - LOAD_SUBKEYS_ ## size \ - li(%[cc], 0) \ - \ - BYTESWAP_INIT \ - INCR_128_X4_INIT \ - \ - /* \ - * Load current CTR counters into v16 to v19. \ - */ \ - lxvw4x(48, %[cc0], %[ctrbuf]) \ - lxvw4x(49, %[cc1], %[ctrbuf]) \ - lxvw4x(50, %[cc2], %[ctrbuf]) \ - lxvw4x(51, %[cc3], %[ctrbuf]) \ - BYTESWAP(16) \ - BYTESWAP(17) \ - BYTESWAP(18) \ - BYTESWAP(19) \ - \ - mtctr(%[num_blocks_x4]) \ - \ - label(loop) \ - /* \ - * Compute next counter values into v20..v23. \ - */ \ - INCR_128(20, 16) \ - INCR_128(21, 17) \ - INCR_128(22, 18) \ - INCR_128(23, 19) \ - \ - /* \ - * Encrypt counter values and XOR into next data blocks. \ - */ \ - lxvw4x(56, %[cc0], %[buf]) \ - lxvw4x(57, %[cc1], %[buf]) \ - lxvw4x(58, %[cc2], %[buf]) \ - lxvw4x(59, %[cc3], %[buf]) \ - BYTESWAP(24) \ - BYTESWAP(25) \ - BYTESWAP(26) \ - BYTESWAP(27) \ - BLOCK_ENCRYPT_X4_ ## size(16, 17, 18, 19) \ - vxor(16, 16, 24) \ - vxor(17, 17, 25) \ - vxor(18, 18, 26) \ - vxor(19, 19, 27) \ - BYTESWAP(16) \ - BYTESWAP(17) \ - BYTESWAP(18) \ - BYTESWAP(19) \ - stxvw4x(48, %[cc0], %[buf]) \ - stxvw4x(49, %[cc1], %[buf]) \ - stxvw4x(50, %[cc2], %[buf]) \ - stxvw4x(51, %[cc3], %[buf]) \ - \ - /* \ - * Update counters and data pointer. \ - */ \ - vand(16, 20, 20) \ - vand(17, 21, 21) \ - vand(18, 22, 22) \ - vand(19, 23, 23) \ - addi(%[buf], %[buf], 64) \ - \ - bdnz(loop) \ - \ - /* \ - * Write back new counter values. \ - */ \ - BYTESWAP(16) \ - BYTESWAP(17) \ - BYTESWAP(18) \ - BYTESWAP(19) \ - stxvw4x(48, %[cc0], %[ctrbuf]) \ - stxvw4x(49, %[cc1], %[ctrbuf]) \ - stxvw4x(50, %[cc2], %[ctrbuf]) \ - stxvw4x(51, %[cc3], %[ctrbuf]) \ - \ -: [cc] "+b" (cc), [buf] "+b" (buf), \ - [cc0] "+b" (cc0), [cc1] "+b" (cc1), [cc2] "+b" (cc2), [cc3] "+b" (cc3) \ -: [sk] "b" (sk), [ctrbuf] "b" (ctrbuf), \ - [num_blocks_x4] "b" (num_blocks_x4), [ctrinc_x4] "b" (ctrinc_x4) \ - BYTESWAP_REG \ -: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", \ - "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", \ - "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", \ - "v30", "ctr", "memory" \ - ); \ -} - -MKCTR(128) -MKCTR(192) -MKCTR(256) - -#define MKCBCMAC(size) \ -static void \ -cbcmac_ ## size(const unsigned char *sk, \ - unsigned char *cbcmac, const unsigned char *buf, size_t num_blocks) \ -{ \ - long cc; \ - \ - cc = 0; \ - asm volatile ( \ - \ - /* \ - * Load subkeys into v0..v10 \ - */ \ - LOAD_SUBKEYS_ ## size \ - li(%[cc], 0) \ - \ - BYTESWAP_INIT \ - \ - /* \ - * Load current CBC-MAC value into v16. \ - */ \ - lxvw4x(48, %[cc], %[cbcmac]) \ - BYTESWAP(16) \ - \ - mtctr(%[num_blocks]) \ - \ - label(loop) \ - /* \ - * Load next block, XOR into current CBC-MAC value, \ - * and then encrypt it. \ - */ \ - lxvw4x(49, %[cc], %[buf]) \ - BYTESWAP(17) \ - vxor(16, 16, 17) \ - BLOCK_ENCRYPT_ ## size(16) \ - addi(%[buf], %[buf], 16) \ - \ - bdnz(loop) \ - \ - /* \ - * Write back new CBC-MAC value. \ - */ \ - BYTESWAP(16) \ - stxvw4x(48, %[cc], %[cbcmac]) \ - \ -: [cc] "+b" (cc), [buf] "+b" (buf) \ -: [sk] "b" (sk), [cbcmac] "b" (cbcmac), [num_blocks] "b" (num_blocks) \ - BYTESWAP_REG \ -: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", \ - "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", \ - "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", \ - "v30", "ctr", "memory" \ - ); \ -} - -MKCBCMAC(128) -MKCBCMAC(192) -MKCBCMAC(256) - -#define MKENCRYPT(size) \ -static void \ -ctrcbc_ ## size ## _encrypt(const unsigned char *sk, \ - unsigned char *ctr, unsigned char *cbcmac, unsigned char *buf, \ - size_t num_blocks) \ -{ \ - long cc; \ - \ - cc = 0; \ - asm volatile ( \ - \ - /* \ - * Load subkeys into v0..v10 \ - */ \ - LOAD_SUBKEYS_ ## size \ - li(%[cc], 0) \ - \ - BYTESWAP_INIT \ - INCR_128_INIT \ - \ - /* \ - * Load current CTR counter into v16, and current \ - * CBC-MAC IV into v17. \ - */ \ - lxvw4x(48, %[cc], %[ctr]) \ - lxvw4x(49, %[cc], %[cbcmac]) \ - BYTESWAP(16) \ - BYTESWAP(17) \ - \ - /* \ - * At each iteration, we do two parallel encryption: \ - * - new counter value for encryption of the next block; \ - * - CBC-MAC over the previous encrypted block. \ - * Thus, each plaintext block implies two AES instances, \ - * over two successive iterations. This requires a single \ - * counter encryption before the loop, and a single \ - * CBC-MAC encryption after the loop. \ - */ \ - \ - /* \ - * Encrypt first block (into v20). \ - */ \ - lxvw4x(52, %[cc], %[buf]) \ - BYTESWAP(20) \ - INCR_128(22, 16) \ - BLOCK_ENCRYPT_ ## size(16) \ - vxor(20, 20, 16) \ - BYTESWAPX(21, 20) \ - stxvw4x(53, %[cc], %[buf]) \ - vand(16, 22, 22) \ - addi(%[buf], %[buf], 16) \ - \ - /* \ - * Load loop counter; skip the loop if there is only \ - * one block in total (already handled by the boundary \ - * conditions). \ - */ \ - mtctr(%[num_blocks]) \ - bdz(fastexit) \ - \ - label(loop) \ - /* \ - * Upon loop entry: \ - * v16 counter value for next block \ - * v17 current CBC-MAC value \ - * v20 encrypted previous block \ - */ \ - vxor(17, 17, 20) \ - INCR_128(22, 16) \ - lxvw4x(52, %[cc], %[buf]) \ - BYTESWAP(20) \ - BLOCK_ENCRYPT_X2_ ## size(16, 17) \ - vxor(20, 20, 16) \ - BYTESWAPX(21, 20) \ - stxvw4x(53, %[cc], %[buf]) \ - addi(%[buf], %[buf], 16) \ - vand(16, 22, 22) \ - \ - bdnz(loop) \ - \ - label(fastexit) \ - vxor(17, 17, 20) \ - BLOCK_ENCRYPT_ ## size(17) \ - BYTESWAP(16) \ - BYTESWAP(17) \ - stxvw4x(48, %[cc], %[ctr]) \ - stxvw4x(49, %[cc], %[cbcmac]) \ - \ -: [cc] "+b" (cc), [buf] "+b" (buf) \ -: [sk] "b" (sk), [ctr] "b" (ctr), [cbcmac] "b" (cbcmac), \ - [num_blocks] "b" (num_blocks), [ctrinc] "b" (ctrinc) \ - BYTESWAP_REG \ -: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", \ - "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", \ - "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", \ - "v30", "ctr", "memory" \ - ); \ -} - -MKENCRYPT(128) -MKENCRYPT(192) -MKENCRYPT(256) - -#define MKDECRYPT(size) \ -static void \ -ctrcbc_ ## size ## _decrypt(const unsigned char *sk, \ - unsigned char *ctr, unsigned char *cbcmac, unsigned char *buf, \ - size_t num_blocks) \ -{ \ - long cc; \ - \ - cc = 0; \ - asm volatile ( \ - \ - /* \ - * Load subkeys into v0..v10 \ - */ \ - LOAD_SUBKEYS_ ## size \ - li(%[cc], 0) \ - \ - BYTESWAP_INIT \ - INCR_128_INIT \ - \ - /* \ - * Load current CTR counter into v16, and current \ - * CBC-MAC IV into v17. \ - */ \ - lxvw4x(48, %[cc], %[ctr]) \ - lxvw4x(49, %[cc], %[cbcmac]) \ - BYTESWAP(16) \ - BYTESWAP(17) \ - \ - /* \ - * At each iteration, we do two parallel encryption: \ - * - new counter value for decryption of the next block; \ - * - CBC-MAC over the next encrypted block. \ - * Each iteration performs the two AES instances related \ - * to the current block; there is thus no need for some \ - * extra pre-loop and post-loop work as in encryption. \ - */ \ - \ - mtctr(%[num_blocks]) \ - \ - label(loop) \ - /* \ - * Upon loop entry: \ - * v16 counter value for next block \ - * v17 current CBC-MAC value \ - */ \ - lxvw4x(52, %[cc], %[buf]) \ - BYTESWAP(20) \ - vxor(17, 17, 20) \ - INCR_128(22, 16) \ - BLOCK_ENCRYPT_X2_ ## size(16, 17) \ - vxor(20, 20, 16) \ - BYTESWAPX(21, 20) \ - stxvw4x(53, %[cc], %[buf]) \ - addi(%[buf], %[buf], 16) \ - vand(16, 22, 22) \ - \ - bdnz(loop) \ - \ - /* \ - * Store back counter and CBC-MAC value. \ - */ \ - BYTESWAP(16) \ - BYTESWAP(17) \ - stxvw4x(48, %[cc], %[ctr]) \ - stxvw4x(49, %[cc], %[cbcmac]) \ - \ -: [cc] "+b" (cc), [buf] "+b" (buf) \ -: [sk] "b" (sk), [ctr] "b" (ctr), [cbcmac] "b" (cbcmac), \ - [num_blocks] "b" (num_blocks), [ctrinc] "b" (ctrinc) \ - BYTESWAP_REG \ -: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", \ - "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", \ - "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", \ - "v30", "ctr", "memory" \ - ); \ -} - -MKDECRYPT(128) -MKDECRYPT(192) -MKDECRYPT(256) - -/* see bearssl_block.h */ -void -br_aes_pwr8_ctrcbc_encrypt(const br_aes_pwr8_ctrcbc_keys *ctx, - void *ctr, void *cbcmac, void *data, size_t len) -{ - if (len == 0) { - return; - } - switch (ctx->num_rounds) { - case 10: - ctrcbc_128_encrypt(ctx->skey.skni, ctr, cbcmac, data, len >> 4); - break; - case 12: - ctrcbc_192_encrypt(ctx->skey.skni, ctr, cbcmac, data, len >> 4); - break; - default: - ctrcbc_256_encrypt(ctx->skey.skni, ctr, cbcmac, data, len >> 4); - break; - } -} - -/* see bearssl_block.h */ -void -br_aes_pwr8_ctrcbc_decrypt(const br_aes_pwr8_ctrcbc_keys *ctx, - void *ctr, void *cbcmac, void *data, size_t len) -{ - if (len == 0) { - return; - } - switch (ctx->num_rounds) { - case 10: - ctrcbc_128_decrypt(ctx->skey.skni, ctr, cbcmac, data, len >> 4); - break; - case 12: - ctrcbc_192_decrypt(ctx->skey.skni, ctr, cbcmac, data, len >> 4); - break; - default: - ctrcbc_256_decrypt(ctx->skey.skni, ctr, cbcmac, data, len >> 4); - break; - } -} - -static inline void -incr_ctr(void *dst, const void *src) -{ - uint64_t hi, lo; - - hi = br_dec64be(src); - lo = br_dec64be((const unsigned char *)src + 8); - lo ++; - hi += ((lo | -lo) >> 63) ^ (uint64_t)1; - br_enc64be(dst, hi); - br_enc64be((unsigned char *)dst + 8, lo); -} - -/* see bearssl_block.h */ -void -br_aes_pwr8_ctrcbc_ctr(const br_aes_pwr8_ctrcbc_keys *ctx, - void *ctr, void *data, size_t len) -{ - unsigned char ctrbuf[64]; - - memcpy(ctrbuf, ctr, 16); - incr_ctr(ctrbuf + 16, ctrbuf); - incr_ctr(ctrbuf + 32, ctrbuf + 16); - incr_ctr(ctrbuf + 48, ctrbuf + 32); - if (len >= 64) { - switch (ctx->num_rounds) { - case 10: - ctr_128(ctx->skey.skni, ctrbuf, data, len >> 6); - break; - case 12: - ctr_192(ctx->skey.skni, ctrbuf, data, len >> 6); - break; - default: - ctr_256(ctx->skey.skni, ctrbuf, data, len >> 6); - break; - } - data = (unsigned char *)data + (len & ~(size_t)63); - len &= 63; - } - if (len > 0) { - unsigned char tmp[64]; - - if (len >= 32) { - if (len >= 48) { - memcpy(ctr, ctrbuf + 48, 16); - } else { - memcpy(ctr, ctrbuf + 32, 16); - } - } else { - if (len >= 16) { - memcpy(ctr, ctrbuf + 16, 16); - } - } - memcpy(tmp, data, len); - memset(tmp + len, 0, (sizeof tmp) - len); - switch (ctx->num_rounds) { - case 10: - ctr_128(ctx->skey.skni, ctrbuf, tmp, 1); - break; - case 12: - ctr_192(ctx->skey.skni, ctrbuf, tmp, 1); - break; - default: - ctr_256(ctx->skey.skni, ctrbuf, tmp, 1); - break; - } - memcpy(data, tmp, len); - } else { - memcpy(ctr, ctrbuf, 16); - } -} - -/* see bearssl_block.h */ -void -br_aes_pwr8_ctrcbc_mac(const br_aes_pwr8_ctrcbc_keys *ctx, - void *cbcmac, const void *data, size_t len) -{ - if (len > 0) { - switch (ctx->num_rounds) { - case 10: - cbcmac_128(ctx->skey.skni, cbcmac, data, len >> 4); - break; - case 12: - cbcmac_192(ctx->skey.skni, cbcmac, data, len >> 4); - break; - default: - cbcmac_256(ctx->skey.skni, cbcmac, data, len >> 4); - break; - } - } -} - -/* see bearssl_block.h */ -const br_block_ctrcbc_class br_aes_pwr8_ctrcbc_vtable = { - sizeof(br_aes_pwr8_ctrcbc_keys), - 16, - 4, - (void (*)(const br_block_ctrcbc_class **, const void *, size_t)) - &br_aes_pwr8_ctrcbc_init, - (void (*)(const br_block_ctrcbc_class *const *, - void *, void *, void *, size_t)) - &br_aes_pwr8_ctrcbc_encrypt, - (void (*)(const br_block_ctrcbc_class *const *, - void *, void *, void *, size_t)) - &br_aes_pwr8_ctrcbc_decrypt, - (void (*)(const br_block_ctrcbc_class *const *, - void *, void *, size_t)) - &br_aes_pwr8_ctrcbc_ctr, - (void (*)(const br_block_ctrcbc_class *const *, - void *, const void *, size_t)) - &br_aes_pwr8_ctrcbc_mac -}; - -#else - -/* see bearssl_block.h */ -const br_block_ctrcbc_class * -br_aes_pwr8_ctrcbc_get_vtable(void) -{ - return NULL; -} - -#endif - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/aes_small_cbcdec.c b/src/tls/bearssl/aes_small_cbcdec.c deleted file mode 100644 index 795841b04..000000000 --- a/src/tls/bearssl/aes_small_cbcdec.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_block.h */ -void -br_aes_small_cbcdec_init(br_aes_small_cbcdec_keys *ctx, - const void *key, size_t len) -{ - ctx->vtable = &br_aes_small_cbcdec_vtable; - ctx->num_rounds = br_aes_keysched(ctx->skey, key, len); -} - -/* see bearssl_block.h */ -void -br_aes_small_cbcdec_run(const br_aes_small_cbcdec_keys *ctx, - void *iv, void *data, size_t len) -{ - unsigned char *buf, *ivbuf; - - ivbuf = iv; - buf = data; - while (len > 0) { - unsigned char tmp[16]; - int i; - - memcpy(tmp, buf, 16); - br_aes_small_decrypt(ctx->num_rounds, ctx->skey, buf); - for (i = 0; i < 16; i ++) { - buf[i] ^= ivbuf[i]; - } - memcpy(ivbuf, tmp, 16); - buf += 16; - len -= 16; - } -} - -/* see bearssl_block.h */ -const br_block_cbcdec_class br_aes_small_cbcdec_vtable = { - sizeof(br_aes_small_cbcdec_keys), - 16, - 4, - (void (*)(const br_block_cbcdec_class **, const void *, size_t)) - &br_aes_small_cbcdec_init, - (void (*)(const br_block_cbcdec_class *const *, void *, void *, size_t)) - &br_aes_small_cbcdec_run -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/aes_small_cbcenc.c b/src/tls/bearssl/aes_small_cbcenc.c deleted file mode 100644 index bd38b32cf..000000000 --- a/src/tls/bearssl/aes_small_cbcenc.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_block.h */ -void -br_aes_small_cbcenc_init(br_aes_small_cbcenc_keys *ctx, - const void *key, size_t len) -{ - ctx->vtable = &br_aes_small_cbcenc_vtable; - ctx->num_rounds = br_aes_keysched(ctx->skey, key, len); -} - -/* see bearssl_block.h */ -void -br_aes_small_cbcenc_run(const br_aes_small_cbcenc_keys *ctx, - void *iv, void *data, size_t len) -{ - unsigned char *buf, *ivbuf; - - ivbuf = iv; - buf = data; - while (len > 0) { - int i; - - for (i = 0; i < 16; i ++) { - buf[i] ^= ivbuf[i]; - } - br_aes_small_encrypt(ctx->num_rounds, ctx->skey, buf); - memcpy(ivbuf, buf, 16); - buf += 16; - len -= 16; - } -} - -/* see bearssl_block.h */ -const br_block_cbcenc_class br_aes_small_cbcenc_vtable = { - sizeof(br_aes_small_cbcenc_keys), - 16, - 4, - (void (*)(const br_block_cbcenc_class **, const void *, size_t)) - &br_aes_small_cbcenc_init, - (void (*)(const br_block_cbcenc_class *const *, void *, void *, size_t)) - &br_aes_small_cbcenc_run -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/aes_small_ctr.c b/src/tls/bearssl/aes_small_ctr.c deleted file mode 100644 index 52531c2a5..000000000 --- a/src/tls/bearssl/aes_small_ctr.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_block.h */ -void -br_aes_small_ctr_init(br_aes_small_ctr_keys *ctx, - const void *key, size_t len) -{ - ctx->vtable = &br_aes_small_ctr_vtable; - ctx->num_rounds = br_aes_keysched(ctx->skey, key, len); -} - -static void -xorbuf(void *dst, const void *src, size_t len) -{ - unsigned char *d; - const unsigned char *s; - - d = dst; - s = src; - while (len -- > 0) { - *d ++ ^= *s ++; - } -} - -/* see bearssl_block.h */ -uint32_t -br_aes_small_ctr_run(const br_aes_small_ctr_keys *ctx, - const void *iv, uint32_t cc, void *data, size_t len) -{ - unsigned char *buf; - - buf = data; - while (len > 0) { - unsigned char tmp[16]; - - memcpy(tmp, iv, 12); - br_enc32be(tmp + 12, cc ++); - br_aes_small_encrypt(ctx->num_rounds, ctx->skey, tmp); - if (len <= 16) { - xorbuf(buf, tmp, len); - break; - } - xorbuf(buf, tmp, 16); - buf += 16; - len -= 16; - } - return cc; -} - -/* see bearssl_block.h */ -const br_block_ctr_class br_aes_small_ctr_vtable = { - sizeof(br_aes_small_ctr_keys), - 16, - 4, - (void (*)(const br_block_ctr_class **, const void *, size_t)) - &br_aes_small_ctr_init, - (uint32_t (*)(const br_block_ctr_class *const *, - const void *, uint32_t, void *, size_t)) - &br_aes_small_ctr_run -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/aes_small_ctrcbc.c b/src/tls/bearssl/aes_small_ctrcbc.c deleted file mode 100644 index 519f858a4..000000000 --- a/src/tls/bearssl/aes_small_ctrcbc.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_block.h */ -void -br_aes_small_ctrcbc_init(br_aes_small_ctrcbc_keys *ctx, - const void *key, size_t len) -{ - ctx->vtable = &br_aes_small_ctrcbc_vtable; - ctx->num_rounds = br_aes_keysched(ctx->skey, key, len); -} - -static void -xorbuf(void *dst, const void *src, size_t len) -{ - unsigned char *d; - const unsigned char *s; - - d = dst; - s = src; - while (len -- > 0) { - *d ++ ^= *s ++; - } -} - -/* see bearssl_block.h */ -void -br_aes_small_ctrcbc_ctr(const br_aes_small_ctrcbc_keys *ctx, - void *ctr, void *data, size_t len) -{ - unsigned char *buf, *bctr; - uint32_t cc0, cc1, cc2, cc3; - - buf = data; - bctr = ctr; - cc3 = br_dec32be(bctr + 0); - cc2 = br_dec32be(bctr + 4); - cc1 = br_dec32be(bctr + 8); - cc0 = br_dec32be(bctr + 12); - while (len > 0) { - unsigned char tmp[16]; - uint32_t carry; - - br_enc32be(tmp + 0, cc3); - br_enc32be(tmp + 4, cc2); - br_enc32be(tmp + 8, cc1); - br_enc32be(tmp + 12, cc0); - br_aes_small_encrypt(ctx->num_rounds, ctx->skey, tmp); - xorbuf(buf, tmp, 16); - buf += 16; - len -= 16; - cc0 ++; - carry = (~(cc0 | -cc0)) >> 31; - cc1 += carry; - carry &= (~(cc1 | -cc1)) >> 31; - cc2 += carry; - carry &= (~(cc2 | -cc2)) >> 31; - cc3 += carry; - } - br_enc32be(bctr + 0, cc3); - br_enc32be(bctr + 4, cc2); - br_enc32be(bctr + 8, cc1); - br_enc32be(bctr + 12, cc0); -} - -/* see bearssl_block.h */ -void -br_aes_small_ctrcbc_mac(const br_aes_small_ctrcbc_keys *ctx, - void *cbcmac, const void *data, size_t len) -{ - const unsigned char *buf; - - buf = data; - while (len > 0) { - xorbuf(cbcmac, buf, 16); - br_aes_small_encrypt(ctx->num_rounds, ctx->skey, cbcmac); - buf += 16; - len -= 16; - } -} - -/* see bearssl_block.h */ -void -br_aes_small_ctrcbc_encrypt(const br_aes_small_ctrcbc_keys *ctx, - void *ctr, void *cbcmac, void *data, size_t len) -{ - br_aes_small_ctrcbc_ctr(ctx, ctr, data, len); - br_aes_small_ctrcbc_mac(ctx, cbcmac, data, len); -} - -/* see bearssl_block.h */ -void -br_aes_small_ctrcbc_decrypt(const br_aes_small_ctrcbc_keys *ctx, - void *ctr, void *cbcmac, void *data, size_t len) -{ - br_aes_small_ctrcbc_mac(ctx, cbcmac, data, len); - br_aes_small_ctrcbc_ctr(ctx, ctr, data, len); -} - -/* see bearssl_block.h */ -const br_block_ctrcbc_class br_aes_small_ctrcbc_vtable = { - sizeof(br_aes_small_ctrcbc_keys), - 16, - 4, - (void (*)(const br_block_ctrcbc_class **, const void *, size_t)) - &br_aes_small_ctrcbc_init, - (void (*)(const br_block_ctrcbc_class *const *, - void *, void *, void *, size_t)) - &br_aes_small_ctrcbc_encrypt, - (void (*)(const br_block_ctrcbc_class *const *, - void *, void *, void *, size_t)) - &br_aes_small_ctrcbc_decrypt, - (void (*)(const br_block_ctrcbc_class *const *, - void *, void *, size_t)) - &br_aes_small_ctrcbc_ctr, - (void (*)(const br_block_ctrcbc_class *const *, - void *, const void *, size_t)) - &br_aes_small_ctrcbc_mac -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/aes_small_dec.c b/src/tls/bearssl/aes_small_dec.c deleted file mode 100644 index 0a6f0337e..000000000 --- a/src/tls/bearssl/aes_small_dec.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * Inverse S-box. - */ -static const unsigned char iS[] = { - 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, - 0x81, 0xF3, 0xD7, 0xFB, 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, - 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 0x54, 0x7B, 0x94, 0x32, - 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, - 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, - 0x6D, 0x8B, 0xD1, 0x25, 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, - 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 0x6C, 0x70, 0x48, 0x50, - 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, - 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, - 0xB8, 0xB3, 0x45, 0x06, 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, - 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 0x3A, 0x91, 0x11, 0x41, - 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, - 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, - 0x1C, 0x75, 0xDF, 0x6E, 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, - 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 0xFC, 0x56, 0x3E, 0x4B, - 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, - 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, - 0x27, 0x80, 0xEC, 0x5F, 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, - 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 0xA0, 0xE0, 0x3B, 0x4D, - 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, - 0x55, 0x21, 0x0C, 0x7D -}; - -static void -add_round_key(unsigned *state, const uint32_t *skeys) -{ - int i; - - for (i = 0; i < 16; i += 4) { - uint32_t k; - - k = *skeys ++; - state[i + 0] ^= (unsigned)(k >> 24); - state[i + 1] ^= (unsigned)(k >> 16) & 0xFF; - state[i + 2] ^= (unsigned)(k >> 8) & 0xFF; - state[i + 3] ^= (unsigned)k & 0xFF; - } -} - -static void -inv_sub_bytes(unsigned *state) -{ - int i; - - for (i = 0; i < 16; i ++) { - state[i] = iS[state[i]]; - } -} - -static void -inv_shift_rows(unsigned *state) -{ - unsigned tmp; - - tmp = state[13]; - state[13] = state[9]; - state[9] = state[5]; - state[5] = state[1]; - state[1] = tmp; - - tmp = state[2]; - state[2] = state[10]; - state[10] = tmp; - tmp = state[6]; - state[6] = state[14]; - state[14] = tmp; - - tmp = state[3]; - state[3] = state[7]; - state[7] = state[11]; - state[11] = state[15]; - state[15] = tmp; -} - -static inline unsigned -gf256red(unsigned x) -{ - unsigned y; - - y = x >> 8; - return (x ^ y ^ (y << 1) ^ (y << 3) ^ (y << 4)) & 0xFF; -} - -static void -inv_mix_columns(unsigned *state) -{ - int i; - - for (i = 0; i < 16; i += 4) { - unsigned s0, s1, s2, s3; - unsigned t0, t1, t2, t3; - - s0 = state[i + 0]; - s1 = state[i + 1]; - s2 = state[i + 2]; - s3 = state[i + 3]; - t0 = (s0 << 1) ^ (s0 << 2) ^ (s0 << 3) - ^ s1 ^ (s1 << 1) ^ (s1 << 3) - ^ s2 ^ (s2 << 2) ^ (s2 << 3) - ^ s3 ^ (s3 << 3); - t1 = s0 ^ (s0 << 3) - ^ (s1 << 1) ^ (s1 << 2) ^ (s1 << 3) - ^ s2 ^ (s2 << 1) ^ (s2 << 3) - ^ s3 ^ (s3 << 2) ^ (s3 << 3); - t2 = s0 ^ (s0 << 2) ^ (s0 << 3) - ^ s1 ^ (s1 << 3) - ^ (s2 << 1) ^ (s2 << 2) ^ (s2 << 3) - ^ s3 ^ (s3 << 1) ^ (s3 << 3); - t3 = s0 ^ (s0 << 1) ^ (s0 << 3) - ^ s1 ^ (s1 << 2) ^ (s1 << 3) - ^ s2 ^ (s2 << 3) - ^ (s3 << 1) ^ (s3 << 2) ^ (s3 << 3); - state[i + 0] = gf256red(t0); - state[i + 1] = gf256red(t1); - state[i + 2] = gf256red(t2); - state[i + 3] = gf256red(t3); - } -} - -/* see inner.h */ -void -br_aes_small_decrypt(unsigned num_rounds, const uint32_t *skey, void *data) -{ - unsigned char *buf; - unsigned state[16]; - unsigned u; - - buf = data; - for (u = 0; u < 16; u ++) { - state[u] = buf[u]; - } - add_round_key(state, skey + (num_rounds << 2)); - for (u = num_rounds - 1; u > 0; u --) { - inv_shift_rows(state); - inv_sub_bytes(state); - add_round_key(state, skey + (u << 2)); - inv_mix_columns(state); - } - inv_shift_rows(state); - inv_sub_bytes(state); - add_round_key(state, skey); - for (u = 0; u < 16; u ++) { - buf[u] = state[u]; - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/aes_small_enc.c b/src/tls/bearssl/aes_small_enc.c deleted file mode 100644 index a52a64a7e..000000000 --- a/src/tls/bearssl/aes_small_enc.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -#define S br_aes_S - -static void -add_round_key(unsigned *state, const uint32_t *skeys) -{ - int i; - - for (i = 0; i < 16; i += 4) { - uint32_t k; - - k = *skeys ++; - state[i + 0] ^= (unsigned)(k >> 24); - state[i + 1] ^= (unsigned)(k >> 16) & 0xFF; - state[i + 2] ^= (unsigned)(k >> 8) & 0xFF; - state[i + 3] ^= (unsigned)k & 0xFF; - } -} - -static void -sub_bytes(unsigned *state) -{ - int i; - - for (i = 0; i < 16; i ++) { - state[i] = S[state[i]]; - } -} - -static void -shift_rows(unsigned *state) -{ - unsigned tmp; - - tmp = state[1]; - state[1] = state[5]; - state[5] = state[9]; - state[9] = state[13]; - state[13] = tmp; - - tmp = state[2]; - state[2] = state[10]; - state[10] = tmp; - tmp = state[6]; - state[6] = state[14]; - state[14] = tmp; - - tmp = state[15]; - state[15] = state[11]; - state[11] = state[7]; - state[7] = state[3]; - state[3] = tmp; -} - -static void -mix_columns(unsigned *state) -{ - int i; - - for (i = 0; i < 16; i += 4) { - unsigned s0, s1, s2, s3; - unsigned t0, t1, t2, t3; - - s0 = state[i + 0]; - s1 = state[i + 1]; - s2 = state[i + 2]; - s3 = state[i + 3]; - t0 = (s0 << 1) ^ s1 ^ (s1 << 1) ^ s2 ^ s3; - t1 = s0 ^ (s1 << 1) ^ s2 ^ (s2 << 1) ^ s3; - t2 = s0 ^ s1 ^ (s2 << 1) ^ s3 ^ (s3 << 1); - t3 = s0 ^ (s0 << 1) ^ s1 ^ s2 ^ (s3 << 1); - state[i + 0] = t0 ^ ((unsigned)(-(int)(t0 >> 8)) & 0x11B); - state[i + 1] = t1 ^ ((unsigned)(-(int)(t1 >> 8)) & 0x11B); - state[i + 2] = t2 ^ ((unsigned)(-(int)(t2 >> 8)) & 0x11B); - state[i + 3] = t3 ^ ((unsigned)(-(int)(t3 >> 8)) & 0x11B); - } -} - -/* see inner.h */ -void -br_aes_small_encrypt(unsigned num_rounds, const uint32_t *skey, void *data) -{ - unsigned char *buf; - unsigned state[16]; - unsigned u; - - buf = data; - for (u = 0; u < 16; u ++) { - state[u] = buf[u]; - } - add_round_key(state, skey); - for (u = 1; u < num_rounds; u ++) { - sub_bytes(state); - shift_rows(state); - mix_columns(state); - add_round_key(state, skey + (u << 2)); - } - sub_bytes(state); - shift_rows(state); - add_round_key(state, skey + (num_rounds << 2)); - for (u = 0; u < 16; u ++) { - buf[u] = state[u]; - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/aes_x86ni.c b/src/tls/bearssl/aes_x86ni.c deleted file mode 100644 index ef1ea35a9..000000000 --- a/src/tls/bearssl/aes_x86ni.c +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * This code contains the AES key schedule implementation using the - * AES-NI opcodes. - */ - -#if BR_AES_X86NI - -#if BR_AES_X86NI_GCC -#if BR_AES_X86NI_GCC_OLD -#pragma GCC push_options -#pragma GCC target("sse2,sse4.1,aes,pclmul") -#endif -#include -#include -#if BR_AES_X86NI_GCC_OLD -#pragma GCC pop_options -#endif -#endif - -#if BR_AES_X86NI_MSC -#include -#endif - -/* see inner.h */ -int -br_aes_x86ni_supported(void) -{ - /* - * Bit mask for features in ECX: - * 19 SSE4.1 (used for _mm_insert_epi32(), for AES-CTR) - * 25 AES-NI - */ -#define MASK 0x02080000 - -#if BR_AES_X86NI_GCC - unsigned eax, ebx, ecx, edx; - - if (__get_cpuid(1, &eax, &ebx, &ecx, &edx)) { - return (ecx & MASK) == MASK; - } else { - return 0; - } -#elif BR_AES_X86NI_MSC - int info[4]; - - __cpuid(info, 1); - return ((uint32_t)info[2] & MASK) == MASK; -#else - return 0; -#endif - -#undef MASK -} - -/* - * Per-function attributes appear unreliable on old GCC, so we use the - * pragma for all remaining functions in this file. - */ -#if BR_AES_X86NI_GCC_OLD -#pragma GCC target("sse2,sse4.1,aes,pclmul") -#endif - -BR_TARGET("sse2,aes") -static inline __m128i -expand_step128(__m128i k, __m128i k2) -{ - k = _mm_xor_si128(k, _mm_slli_si128(k, 4)); - k = _mm_xor_si128(k, _mm_slli_si128(k, 4)); - k = _mm_xor_si128(k, _mm_slli_si128(k, 4)); - k2 = _mm_shuffle_epi32(k2, 0xFF); - return _mm_xor_si128(k, k2); -} - -BR_TARGET("sse2,aes") -static inline void -expand_step192(__m128i *t1, __m128i *t2, __m128i *t3) -{ - __m128i t4; - - *t2 = _mm_shuffle_epi32(*t2, 0x55); - t4 = _mm_slli_si128(*t1, 0x4); - *t1 = _mm_xor_si128(*t1, t4); - t4 = _mm_slli_si128(t4, 0x4); - *t1 = _mm_xor_si128(*t1, t4); - t4 = _mm_slli_si128(t4, 0x4); - *t1 = _mm_xor_si128(*t1, t4); - *t1 = _mm_xor_si128(*t1, *t2); - *t2 = _mm_shuffle_epi32(*t1, 0xFF); - t4 = _mm_slli_si128(*t3, 0x4); - *t3 = _mm_xor_si128(*t3, t4); - *t3 = _mm_xor_si128(*t3, *t2); -} - -BR_TARGET("sse2,aes") -static inline void -expand_step256_1(__m128i *t1, __m128i *t2) -{ - __m128i t4; - - *t2 = _mm_shuffle_epi32(*t2, 0xFF); - t4 = _mm_slli_si128(*t1, 0x4); - *t1 = _mm_xor_si128(*t1, t4); - t4 = _mm_slli_si128(t4, 0x4); - *t1 = _mm_xor_si128(*t1, t4); - t4 = _mm_slli_si128(t4, 0x4); - *t1 = _mm_xor_si128(*t1, t4); - *t1 = _mm_xor_si128(*t1, *t2); -} - -BR_TARGET("sse2,aes") -static inline void -expand_step256_2(__m128i *t1, __m128i *t3) -{ - __m128i t2, t4; - - t4 = _mm_aeskeygenassist_si128(*t1, 0x0); - t2 = _mm_shuffle_epi32(t4, 0xAA); - t4 = _mm_slli_si128(*t3, 0x4); - *t3 = _mm_xor_si128(*t3, t4); - t4 = _mm_slli_si128(t4, 0x4); - *t3 = _mm_xor_si128(*t3, t4); - t4 = _mm_slli_si128(t4, 0x4); - *t3 = _mm_xor_si128(*t3, t4); - *t3 = _mm_xor_si128(*t3, t2); -} - -/* - * Perform key schedule for AES, encryption direction. Subkeys are written - * in sk[], and the number of rounds is returned. Key length MUST be 16, - * 24 or 32 bytes. - */ -BR_TARGET("sse2,aes") -static unsigned -x86ni_keysched(__m128i *sk, const void *key, size_t len) -{ - const unsigned char *kb; - -#define KEXP128(k, i, rcon) do { \ - k = expand_step128(k, _mm_aeskeygenassist_si128(k, rcon)); \ - sk[i] = k; \ - } while (0) - -#define KEXP192(i, rcon1, rcon2) do { \ - sk[(i) + 0] = t1; \ - sk[(i) + 1] = t3; \ - t2 = _mm_aeskeygenassist_si128(t3, rcon1); \ - expand_step192(&t1, &t2, &t3); \ - sk[(i) + 1] = _mm_castpd_si128(_mm_shuffle_pd( \ - _mm_castsi128_pd(sk[(i) + 1]), \ - _mm_castsi128_pd(t1), 0)); \ - sk[(i) + 2] = _mm_castpd_si128(_mm_shuffle_pd( \ - _mm_castsi128_pd(t1), \ - _mm_castsi128_pd(t3), 1)); \ - t2 = _mm_aeskeygenassist_si128(t3, rcon2); \ - expand_step192(&t1, &t2, &t3); \ - } while (0) - -#define KEXP256(i, rcon) do { \ - sk[(i) + 0] = t3; \ - t2 = _mm_aeskeygenassist_si128(t3, rcon); \ - expand_step256_1(&t1, &t2); \ - sk[(i) + 1] = t1; \ - expand_step256_2(&t1, &t3); \ - } while (0) - - kb = key; - switch (len) { - __m128i t1, t2, t3; - - case 16: - t1 = _mm_loadu_si128((const void *)kb); - sk[0] = t1; - KEXP128(t1, 1, 0x01); - KEXP128(t1, 2, 0x02); - KEXP128(t1, 3, 0x04); - KEXP128(t1, 4, 0x08); - KEXP128(t1, 5, 0x10); - KEXP128(t1, 6, 0x20); - KEXP128(t1, 7, 0x40); - KEXP128(t1, 8, 0x80); - KEXP128(t1, 9, 0x1B); - KEXP128(t1, 10, 0x36); - return 10; - - case 24: - t1 = _mm_loadu_si128((const void *)kb); - t3 = _mm_loadu_si128((const void *)(kb + 8)); - t3 = _mm_shuffle_epi32(t3, 0x4E); - KEXP192(0, 0x01, 0x02); - KEXP192(3, 0x04, 0x08); - KEXP192(6, 0x10, 0x20); - KEXP192(9, 0x40, 0x80); - sk[12] = t1; - return 12; - - case 32: - t1 = _mm_loadu_si128((const void *)kb); - t3 = _mm_loadu_si128((const void *)(kb + 16)); - sk[0] = t1; - KEXP256( 1, 0x01); - KEXP256( 3, 0x02); - KEXP256( 5, 0x04); - KEXP256( 7, 0x08); - KEXP256( 9, 0x10); - KEXP256(11, 0x20); - sk[13] = t3; - t2 = _mm_aeskeygenassist_si128(t3, 0x40); - expand_step256_1(&t1, &t2); - sk[14] = t1; - return 14; - - default: - return 0; - } - -#undef KEXP128 -#undef KEXP192 -#undef KEXP256 -} - -/* see inner.h */ -BR_TARGET("sse2,aes") -unsigned -br_aes_x86ni_keysched_enc(unsigned char *skni, const void *key, size_t len) -{ - __m128i sk[15]; - unsigned num_rounds; - - num_rounds = x86ni_keysched(sk, key, len); - memcpy(skni, sk, (num_rounds + 1) << 4); - return num_rounds; -} - -/* see inner.h */ -BR_TARGET("sse2,aes") -unsigned -br_aes_x86ni_keysched_dec(unsigned char *skni, const void *key, size_t len) -{ - __m128i sk[15]; - unsigned u, num_rounds; - - num_rounds = x86ni_keysched(sk, key, len); - _mm_storeu_si128((void *)skni, sk[num_rounds]); - for (u = 1; u < num_rounds; u ++) { - _mm_storeu_si128((void *)(skni + (u << 4)), - _mm_aesimc_si128(sk[num_rounds - u])); - } - _mm_storeu_si128((void *)(skni + (num_rounds << 4)), sk[0]); - return num_rounds; -} - -#endif - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/aes_x86ni_cbcdec.c b/src/tls/bearssl/aes_x86ni_cbcdec.c deleted file mode 100644 index 7d7ec4ac9..000000000 --- a/src/tls/bearssl/aes_x86ni_cbcdec.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#define BR_ENABLE_INTRINSICS 1 -#include "inner.h" - -#if BR_AES_X86NI - -/* see bearssl_block.h */ -const br_block_cbcdec_class * -br_aes_x86ni_cbcdec_get_vtable(void) -{ - return br_aes_x86ni_supported() ? &br_aes_x86ni_cbcdec_vtable : NULL; -} - -/* see bearssl_block.h */ -void -br_aes_x86ni_cbcdec_init(br_aes_x86ni_cbcdec_keys *ctx, - const void *key, size_t len) -{ - ctx->vtable = &br_aes_x86ni_cbcdec_vtable; - ctx->num_rounds = br_aes_x86ni_keysched_dec(ctx->skey.skni, key, len); -} - -BR_TARGETS_X86_UP - -/* see bearssl_block.h */ -BR_TARGET("sse2,aes") -void -br_aes_x86ni_cbcdec_run(const br_aes_x86ni_cbcdec_keys *ctx, - void *iv, void *data, size_t len) -{ - unsigned char *buf; - unsigned num_rounds; - __m128i sk[15], ivx; - unsigned u; - - buf = data; - ivx = _mm_loadu_si128(iv); - num_rounds = ctx->num_rounds; - for (u = 0; u <= num_rounds; u ++) { - sk[u] = _mm_loadu_si128((void *)(ctx->skey.skni + (u << 4))); - } - while (len > 0) { - __m128i x0, x1, x2, x3, e0, e1, e2, e3; - - x0 = _mm_loadu_si128((void *)(buf + 0)); - if (len >= 64) { - x1 = _mm_loadu_si128((void *)(buf + 16)); - x2 = _mm_loadu_si128((void *)(buf + 32)); - x3 = _mm_loadu_si128((void *)(buf + 48)); - } else { - x0 = _mm_loadu_si128((void *)(buf + 0)); - if (len >= 32) { - x1 = _mm_loadu_si128((void *)(buf + 16)); - if (len >= 48) { - x2 = _mm_loadu_si128( - (void *)(buf + 32)); - x3 = x2; - } else { - x2 = x0; - x3 = x1; - } - } else { - x1 = x0; - x2 = x0; - x3 = x0; - } - } - e0 = x0; - e1 = x1; - e2 = x2; - e3 = x3; - x0 = _mm_xor_si128(x0, sk[0]); - x1 = _mm_xor_si128(x1, sk[0]); - x2 = _mm_xor_si128(x2, sk[0]); - x3 = _mm_xor_si128(x3, sk[0]); - x0 = _mm_aesdec_si128(x0, sk[1]); - x1 = _mm_aesdec_si128(x1, sk[1]); - x2 = _mm_aesdec_si128(x2, sk[1]); - x3 = _mm_aesdec_si128(x3, sk[1]); - x0 = _mm_aesdec_si128(x0, sk[2]); - x1 = _mm_aesdec_si128(x1, sk[2]); - x2 = _mm_aesdec_si128(x2, sk[2]); - x3 = _mm_aesdec_si128(x3, sk[2]); - x0 = _mm_aesdec_si128(x0, sk[3]); - x1 = _mm_aesdec_si128(x1, sk[3]); - x2 = _mm_aesdec_si128(x2, sk[3]); - x3 = _mm_aesdec_si128(x3, sk[3]); - x0 = _mm_aesdec_si128(x0, sk[4]); - x1 = _mm_aesdec_si128(x1, sk[4]); - x2 = _mm_aesdec_si128(x2, sk[4]); - x3 = _mm_aesdec_si128(x3, sk[4]); - x0 = _mm_aesdec_si128(x0, sk[5]); - x1 = _mm_aesdec_si128(x1, sk[5]); - x2 = _mm_aesdec_si128(x2, sk[5]); - x3 = _mm_aesdec_si128(x3, sk[5]); - x0 = _mm_aesdec_si128(x0, sk[6]); - x1 = _mm_aesdec_si128(x1, sk[6]); - x2 = _mm_aesdec_si128(x2, sk[6]); - x3 = _mm_aesdec_si128(x3, sk[6]); - x0 = _mm_aesdec_si128(x0, sk[7]); - x1 = _mm_aesdec_si128(x1, sk[7]); - x2 = _mm_aesdec_si128(x2, sk[7]); - x3 = _mm_aesdec_si128(x3, sk[7]); - x0 = _mm_aesdec_si128(x0, sk[8]); - x1 = _mm_aesdec_si128(x1, sk[8]); - x2 = _mm_aesdec_si128(x2, sk[8]); - x3 = _mm_aesdec_si128(x3, sk[8]); - x0 = _mm_aesdec_si128(x0, sk[9]); - x1 = _mm_aesdec_si128(x1, sk[9]); - x2 = _mm_aesdec_si128(x2, sk[9]); - x3 = _mm_aesdec_si128(x3, sk[9]); - if (num_rounds == 10) { - x0 = _mm_aesdeclast_si128(x0, sk[10]); - x1 = _mm_aesdeclast_si128(x1, sk[10]); - x2 = _mm_aesdeclast_si128(x2, sk[10]); - x3 = _mm_aesdeclast_si128(x3, sk[10]); - } else if (num_rounds == 12) { - x0 = _mm_aesdec_si128(x0, sk[10]); - x1 = _mm_aesdec_si128(x1, sk[10]); - x2 = _mm_aesdec_si128(x2, sk[10]); - x3 = _mm_aesdec_si128(x3, sk[10]); - x0 = _mm_aesdec_si128(x0, sk[11]); - x1 = _mm_aesdec_si128(x1, sk[11]); - x2 = _mm_aesdec_si128(x2, sk[11]); - x3 = _mm_aesdec_si128(x3, sk[11]); - x0 = _mm_aesdeclast_si128(x0, sk[12]); - x1 = _mm_aesdeclast_si128(x1, sk[12]); - x2 = _mm_aesdeclast_si128(x2, sk[12]); - x3 = _mm_aesdeclast_si128(x3, sk[12]); - } else { - x0 = _mm_aesdec_si128(x0, sk[10]); - x1 = _mm_aesdec_si128(x1, sk[10]); - x2 = _mm_aesdec_si128(x2, sk[10]); - x3 = _mm_aesdec_si128(x3, sk[10]); - x0 = _mm_aesdec_si128(x0, sk[11]); - x1 = _mm_aesdec_si128(x1, sk[11]); - x2 = _mm_aesdec_si128(x2, sk[11]); - x3 = _mm_aesdec_si128(x3, sk[11]); - x0 = _mm_aesdec_si128(x0, sk[12]); - x1 = _mm_aesdec_si128(x1, sk[12]); - x2 = _mm_aesdec_si128(x2, sk[12]); - x3 = _mm_aesdec_si128(x3, sk[12]); - x0 = _mm_aesdec_si128(x0, sk[13]); - x1 = _mm_aesdec_si128(x1, sk[13]); - x2 = _mm_aesdec_si128(x2, sk[13]); - x3 = _mm_aesdec_si128(x3, sk[13]); - x0 = _mm_aesdeclast_si128(x0, sk[14]); - x1 = _mm_aesdeclast_si128(x1, sk[14]); - x2 = _mm_aesdeclast_si128(x2, sk[14]); - x3 = _mm_aesdeclast_si128(x3, sk[14]); - } - x0 = _mm_xor_si128(x0, ivx); - x1 = _mm_xor_si128(x1, e0); - x2 = _mm_xor_si128(x2, e1); - x3 = _mm_xor_si128(x3, e2); - ivx = e3; - _mm_storeu_si128((void *)(buf + 0), x0); - if (len >= 64) { - _mm_storeu_si128((void *)(buf + 16), x1); - _mm_storeu_si128((void *)(buf + 32), x2); - _mm_storeu_si128((void *)(buf + 48), x3); - buf += 64; - len -= 64; - } else { - if (len >= 32) { - _mm_storeu_si128((void *)(buf + 16), x1); - if (len >= 48) { - _mm_storeu_si128( - (void *)(buf + 32), x2); - } - } - break; - } - } - _mm_storeu_si128(iv, ivx); -} - -BR_TARGETS_X86_DOWN - -/* see bearssl_block.h */ -const br_block_cbcdec_class br_aes_x86ni_cbcdec_vtable = { - sizeof(br_aes_x86ni_cbcdec_keys), - 16, - 4, - (void (*)(const br_block_cbcdec_class **, const void *, size_t)) - &br_aes_x86ni_cbcdec_init, - (void (*)(const br_block_cbcdec_class *const *, void *, void *, size_t)) - &br_aes_x86ni_cbcdec_run -}; - -#else - -/* see bearssl_block.h */ -const br_block_cbcdec_class * -br_aes_x86ni_cbcdec_get_vtable(void) -{ - return NULL; -} - -#endif - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/aes_x86ni_cbcenc.c b/src/tls/bearssl/aes_x86ni_cbcenc.c deleted file mode 100644 index f2e14f2e8..000000000 --- a/src/tls/bearssl/aes_x86ni_cbcenc.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -#if BR_AES_X86NI - -#if BR_AES_X86NI_GCC -#if BR_AES_X86NI_GCC_OLD -#pragma GCC target("sse2,sse4.1,aes,pclmul") -#endif -#include -#endif - -#if BR_AES_X86NI_MSC -#include -#endif - -/* see bearssl_block.h */ -void -br_aes_x86ni_cbcenc_init(br_aes_x86ni_cbcenc_keys *ctx, - const void *key, size_t len) -{ - ctx->vtable = &br_aes_x86ni_cbcenc_vtable; - ctx->num_rounds = br_aes_x86ni_keysched_enc(ctx->skey.skni, key, len); -} - -/* see bearssl_block.h */ -BR_TARGET("sse2,aes") -void -br_aes_x86ni_cbcenc_run(const br_aes_x86ni_cbcenc_keys *ctx, - void *iv, void *data, size_t len) -{ - unsigned char *buf; - unsigned num_rounds; - __m128i sk[15], ivx; - unsigned u; - - buf = data; - ivx = _mm_loadu_si128(iv); - num_rounds = ctx->num_rounds; - for (u = 0; u <= num_rounds; u ++) { - sk[u] = _mm_loadu_si128((void *)(ctx->skey.skni + (u << 4))); - } - while (len > 0) { - __m128i x; - - x = _mm_xor_si128(_mm_loadu_si128((void *)buf), ivx); - x = _mm_xor_si128(x, sk[0]); - x = _mm_aesenc_si128(x, sk[1]); - x = _mm_aesenc_si128(x, sk[2]); - x = _mm_aesenc_si128(x, sk[3]); - x = _mm_aesenc_si128(x, sk[4]); - x = _mm_aesenc_si128(x, sk[5]); - x = _mm_aesenc_si128(x, sk[6]); - x = _mm_aesenc_si128(x, sk[7]); - x = _mm_aesenc_si128(x, sk[8]); - x = _mm_aesenc_si128(x, sk[9]); - if (num_rounds == 10) { - x = _mm_aesenclast_si128(x, sk[10]); - } else if (num_rounds == 12) { - x = _mm_aesenc_si128(x, sk[10]); - x = _mm_aesenc_si128(x, sk[11]); - x = _mm_aesenclast_si128(x, sk[12]); - } else { - x = _mm_aesenc_si128(x, sk[10]); - x = _mm_aesenc_si128(x, sk[11]); - x = _mm_aesenc_si128(x, sk[12]); - x = _mm_aesenc_si128(x, sk[13]); - x = _mm_aesenclast_si128(x, sk[14]); - } - ivx = x; - _mm_storeu_si128((void *)buf, x); - buf += 16; - len -= 16; - } - _mm_storeu_si128(iv, ivx); -} - -/* see bearssl_block.h */ -const br_block_cbcenc_class br_aes_x86ni_cbcenc_vtable = { - sizeof(br_aes_x86ni_cbcenc_keys), - 16, - 4, - (void (*)(const br_block_cbcenc_class **, const void *, size_t)) - &br_aes_x86ni_cbcenc_init, - (void (*)(const br_block_cbcenc_class *const *, void *, void *, size_t)) - &br_aes_x86ni_cbcenc_run -}; - -/* see bearssl_block.h */ -const br_block_cbcenc_class * -br_aes_x86ni_cbcenc_get_vtable(void) -{ - return br_aes_x86ni_supported() ? &br_aes_x86ni_cbcenc_vtable : NULL; -} - -#else - -/* see bearssl_block.h */ -const br_block_cbcenc_class * -br_aes_x86ni_cbcenc_get_vtable(void) -{ - return NULL; -} - -#endif - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/aes_x86ni_ctr.c b/src/tls/bearssl/aes_x86ni_ctr.c deleted file mode 100644 index f26532743..000000000 --- a/src/tls/bearssl/aes_x86ni_ctr.c +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#define BR_ENABLE_INTRINSICS 1 -#include "inner.h" - -#if BR_AES_X86NI - -/* see bearssl_block.h */ -const br_block_ctr_class * -br_aes_x86ni_ctr_get_vtable(void) -{ - return br_aes_x86ni_supported() ? &br_aes_x86ni_ctr_vtable : NULL; -} - -/* see bearssl_block.h */ -void -br_aes_x86ni_ctr_init(br_aes_x86ni_ctr_keys *ctx, - const void *key, size_t len) -{ - ctx->vtable = &br_aes_x86ni_ctr_vtable; - ctx->num_rounds = br_aes_x86ni_keysched_enc(ctx->skey.skni, key, len); -} - -BR_TARGETS_X86_UP - -/* see bearssl_block.h */ -BR_TARGET("sse2,sse4.1,aes") -uint32_t -br_aes_x86ni_ctr_run(const br_aes_x86ni_ctr_keys *ctx, - const void *iv, uint32_t cc, void *data, size_t len) -{ - unsigned char *buf; - unsigned char ivbuf[16]; - unsigned num_rounds; - __m128i sk[15]; - __m128i ivx; - unsigned u; - - buf = data; - memcpy(ivbuf, iv, 12); - num_rounds = ctx->num_rounds; - for (u = 0; u <= num_rounds; u ++) { - sk[u] = _mm_loadu_si128((void *)(ctx->skey.skni + (u << 4))); - } - ivx = _mm_loadu_si128((void *)ivbuf); - while (len > 0) { - __m128i x0, x1, x2, x3; - - x0 = _mm_insert_epi32(ivx, br_bswap32(cc + 0), 3); - x1 = _mm_insert_epi32(ivx, br_bswap32(cc + 1), 3); - x2 = _mm_insert_epi32(ivx, br_bswap32(cc + 2), 3); - x3 = _mm_insert_epi32(ivx, br_bswap32(cc + 3), 3); - x0 = _mm_xor_si128(x0, sk[0]); - x1 = _mm_xor_si128(x1, sk[0]); - x2 = _mm_xor_si128(x2, sk[0]); - x3 = _mm_xor_si128(x3, sk[0]); - x0 = _mm_aesenc_si128(x0, sk[1]); - x1 = _mm_aesenc_si128(x1, sk[1]); - x2 = _mm_aesenc_si128(x2, sk[1]); - x3 = _mm_aesenc_si128(x3, sk[1]); - x0 = _mm_aesenc_si128(x0, sk[2]); - x1 = _mm_aesenc_si128(x1, sk[2]); - x2 = _mm_aesenc_si128(x2, sk[2]); - x3 = _mm_aesenc_si128(x3, sk[2]); - x0 = _mm_aesenc_si128(x0, sk[3]); - x1 = _mm_aesenc_si128(x1, sk[3]); - x2 = _mm_aesenc_si128(x2, sk[3]); - x3 = _mm_aesenc_si128(x3, sk[3]); - x0 = _mm_aesenc_si128(x0, sk[4]); - x1 = _mm_aesenc_si128(x1, sk[4]); - x2 = _mm_aesenc_si128(x2, sk[4]); - x3 = _mm_aesenc_si128(x3, sk[4]); - x0 = _mm_aesenc_si128(x0, sk[5]); - x1 = _mm_aesenc_si128(x1, sk[5]); - x2 = _mm_aesenc_si128(x2, sk[5]); - x3 = _mm_aesenc_si128(x3, sk[5]); - x0 = _mm_aesenc_si128(x0, sk[6]); - x1 = _mm_aesenc_si128(x1, sk[6]); - x2 = _mm_aesenc_si128(x2, sk[6]); - x3 = _mm_aesenc_si128(x3, sk[6]); - x0 = _mm_aesenc_si128(x0, sk[7]); - x1 = _mm_aesenc_si128(x1, sk[7]); - x2 = _mm_aesenc_si128(x2, sk[7]); - x3 = _mm_aesenc_si128(x3, sk[7]); - x0 = _mm_aesenc_si128(x0, sk[8]); - x1 = _mm_aesenc_si128(x1, sk[8]); - x2 = _mm_aesenc_si128(x2, sk[8]); - x3 = _mm_aesenc_si128(x3, sk[8]); - x0 = _mm_aesenc_si128(x0, sk[9]); - x1 = _mm_aesenc_si128(x1, sk[9]); - x2 = _mm_aesenc_si128(x2, sk[9]); - x3 = _mm_aesenc_si128(x3, sk[9]); - if (num_rounds == 10) { - x0 = _mm_aesenclast_si128(x0, sk[10]); - x1 = _mm_aesenclast_si128(x1, sk[10]); - x2 = _mm_aesenclast_si128(x2, sk[10]); - x3 = _mm_aesenclast_si128(x3, sk[10]); - } else if (num_rounds == 12) { - x0 = _mm_aesenc_si128(x0, sk[10]); - x1 = _mm_aesenc_si128(x1, sk[10]); - x2 = _mm_aesenc_si128(x2, sk[10]); - x3 = _mm_aesenc_si128(x3, sk[10]); - x0 = _mm_aesenc_si128(x0, sk[11]); - x1 = _mm_aesenc_si128(x1, sk[11]); - x2 = _mm_aesenc_si128(x2, sk[11]); - x3 = _mm_aesenc_si128(x3, sk[11]); - x0 = _mm_aesenclast_si128(x0, sk[12]); - x1 = _mm_aesenclast_si128(x1, sk[12]); - x2 = _mm_aesenclast_si128(x2, sk[12]); - x3 = _mm_aesenclast_si128(x3, sk[12]); - } else { - x0 = _mm_aesenc_si128(x0, sk[10]); - x1 = _mm_aesenc_si128(x1, sk[10]); - x2 = _mm_aesenc_si128(x2, sk[10]); - x3 = _mm_aesenc_si128(x3, sk[10]); - x0 = _mm_aesenc_si128(x0, sk[11]); - x1 = _mm_aesenc_si128(x1, sk[11]); - x2 = _mm_aesenc_si128(x2, sk[11]); - x3 = _mm_aesenc_si128(x3, sk[11]); - x0 = _mm_aesenc_si128(x0, sk[12]); - x1 = _mm_aesenc_si128(x1, sk[12]); - x2 = _mm_aesenc_si128(x2, sk[12]); - x3 = _mm_aesenc_si128(x3, sk[12]); - x0 = _mm_aesenc_si128(x0, sk[13]); - x1 = _mm_aesenc_si128(x1, sk[13]); - x2 = _mm_aesenc_si128(x2, sk[13]); - x3 = _mm_aesenc_si128(x3, sk[13]); - x0 = _mm_aesenclast_si128(x0, sk[14]); - x1 = _mm_aesenclast_si128(x1, sk[14]); - x2 = _mm_aesenclast_si128(x2, sk[14]); - x3 = _mm_aesenclast_si128(x3, sk[14]); - } - if (len >= 64) { - x0 = _mm_xor_si128(x0, - _mm_loadu_si128((void *)(buf + 0))); - x1 = _mm_xor_si128(x1, - _mm_loadu_si128((void *)(buf + 16))); - x2 = _mm_xor_si128(x2, - _mm_loadu_si128((void *)(buf + 32))); - x3 = _mm_xor_si128(x3, - _mm_loadu_si128((void *)(buf + 48))); - _mm_storeu_si128((void *)(buf + 0), x0); - _mm_storeu_si128((void *)(buf + 16), x1); - _mm_storeu_si128((void *)(buf + 32), x2); - _mm_storeu_si128((void *)(buf + 48), x3); - buf += 64; - len -= 64; - cc += 4; - } else { - unsigned char tmp[64]; - - _mm_storeu_si128((void *)(tmp + 0), x0); - _mm_storeu_si128((void *)(tmp + 16), x1); - _mm_storeu_si128((void *)(tmp + 32), x2); - _mm_storeu_si128((void *)(tmp + 48), x3); - for (u = 0; u < len; u ++) { - buf[u] ^= tmp[u]; - } - cc += (uint32_t)len >> 4; - break; - } - } - return cc; -} - -BR_TARGETS_X86_DOWN - -/* see bearssl_block.h */ -const br_block_ctr_class br_aes_x86ni_ctr_vtable = { - sizeof(br_aes_x86ni_ctr_keys), - 16, - 4, - (void (*)(const br_block_ctr_class **, const void *, size_t)) - &br_aes_x86ni_ctr_init, - (uint32_t (*)(const br_block_ctr_class *const *, - const void *, uint32_t, void *, size_t)) - &br_aes_x86ni_ctr_run -}; - -#else - -/* see bearssl_block.h */ -const br_block_ctr_class * -br_aes_x86ni_ctr_get_vtable(void) -{ - return NULL; -} - -#endif - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/aesctr_drbg.c b/src/tls/bearssl/aesctr_drbg.c deleted file mode 100644 index 3d2db024c..000000000 --- a/src/tls/bearssl/aesctr_drbg.c +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_rand.h */ -void -br_aesctr_drbg_init(br_aesctr_drbg_context *ctx, - const br_block_ctr_class *aesctr, - const void *seed, size_t len) -{ - unsigned char tmp[16]; - - ctx->vtable = &br_aesctr_drbg_vtable; - memset(tmp, 0, sizeof tmp); - aesctr->init(&ctx->sk.vtable, tmp, 16); - ctx->cc = 0; - br_aesctr_drbg_update(ctx, seed, len); -} - -/* see bearssl_rand.h */ -void -br_aesctr_drbg_generate(br_aesctr_drbg_context *ctx, void *out, size_t len) -{ - unsigned char *buf; - unsigned char iv[12]; - - buf = out; - memset(iv, 0, sizeof iv); - while (len > 0) { - size_t clen; - - /* - * We generate data by blocks of at most 65280 bytes. This - * allows for unambiguously testing the counter overflow - * condition; also, it should work on 16-bit architectures - * (where 'size_t' is 16 bits only). - */ - clen = len; - if (clen > 65280) { - clen = 65280; - } - - /* - * We make sure that the counter won't exceed the configured - * limit. - */ - if ((uint32_t)(ctx->cc + ((clen + 15) >> 4)) > 32768) { - clen = (32768 - ctx->cc) << 4; - if (clen > len) { - clen = len; - } - } - - /* - * Run CTR. - */ - memset(buf, 0, clen); - ctx->cc = ctx->sk.vtable->run(&ctx->sk.vtable, - iv, ctx->cc, buf, clen); - buf += clen; - len -= clen; - - /* - * Every 32768 blocks, we force a state update. - */ - if (ctx->cc >= 32768) { - br_aesctr_drbg_update(ctx, NULL, 0); - } - } -} - -/* see bearssl_rand.h */ -void -br_aesctr_drbg_update(br_aesctr_drbg_context *ctx, const void *seed, size_t len) -{ - /* - * We use a Hirose construction on AES-256 to make a hash function. - * Function definition: - * - running state consists in two 16-byte blocks G and H - * - initial values of G and H are conventional - * - there is a fixed block-sized constant C - * - for next data block m: - * set AES key to H||m - * G' = E(G) xor G - * H' = E(G xor C) xor G xor C - * G <- G', H <- H' - * - once all blocks have been processed, output is H||G - * - * Constants: - * G_init = B6 B6 ... B6 - * H_init = A5 A5 ... A5 - * C = 01 00 ... 00 - * - * With this hash function h(), we compute the new state as - * follows: - * - produce a state-dependent value s as encryption of an - * all-one block with AES and the current key - * - compute the new key as the first 128 bits of h(s||seed) - * - * Original Hirose article: - * https://www.iacr.org/archive/fse2006/40470213/40470213.pdf - */ - - unsigned char s[16], iv[12]; - unsigned char G[16], H[16]; - int first; - - /* - * Use an all-one IV to get a fresh output block that depends on the - * current seed. - */ - memset(iv, 0xFF, sizeof iv); - memset(s, 0, 16); - ctx->sk.vtable->run(&ctx->sk.vtable, iv, 0xFFFFFFFF, s, 16); - - /* - * Set G[] and H[] to conventional start values. - */ - memset(G, 0xB6, sizeof G); - memset(H, 0x5A, sizeof H); - - /* - * Process the concatenation of the current state and the seed - * with the custom hash function. - */ - first = 1; - for (;;) { - unsigned char tmp[32]; - unsigned char newG[16]; - - /* - * Assemble new key H||m into tmp[]. - */ - memcpy(tmp, H, 16); - if (first) { - memcpy(tmp + 16, s, 16); - first = 0; - } else { - size_t clen; - - if (len == 0) { - break; - } - clen = len < 16 ? len : 16; - memcpy(tmp + 16, seed, clen); - memset(tmp + 16 + clen, 0, 16 - clen); - seed = (const unsigned char *)seed + clen; - len -= clen; - } - ctx->sk.vtable->init(&ctx->sk.vtable, tmp, 32); - - /* - * Compute new G and H values. - */ - memcpy(iv, G, 12); - memcpy(newG, G, 16); - ctx->sk.vtable->run(&ctx->sk.vtable, iv, - br_dec32be(G + 12), newG, 16); - iv[0] ^= 0x01; - memcpy(H, G, 16); - H[0] ^= 0x01; - ctx->sk.vtable->run(&ctx->sk.vtable, iv, - br_dec32be(G + 12), H, 16); - memcpy(G, newG, 16); - } - - /* - * Output hash value is H||G. We truncate it to its first 128 bits, - * i.e. H; that's our new AES key. - */ - ctx->sk.vtable->init(&ctx->sk.vtable, H, 16); - ctx->cc = 0; -} - -/* see bearssl_rand.h */ -const br_prng_class br_aesctr_drbg_vtable = { - sizeof(br_aesctr_drbg_context), - (void (*)(const br_prng_class **, const void *, const void *, size_t)) - &br_aesctr_drbg_init, - (void (*)(const br_prng_class **, void *, size_t)) - &br_aesctr_drbg_generate, - (void (*)(const br_prng_class **, const void *, size_t)) - &br_aesctr_drbg_update -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/asn1enc.c b/src/tls/bearssl/asn1enc.c deleted file mode 100644 index c6a878113..000000000 --- a/src/tls/bearssl/asn1enc.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -br_asn1_uint -br_asn1_uint_prepare(const void *xdata, size_t xlen) -{ - const unsigned char *x; - br_asn1_uint t; - - x = xdata; - while (xlen > 0 && *x == 0) { - x ++; - xlen --; - } - t.data = x; - t.len = xlen; - t.asn1len = xlen; - if (xlen == 0 || x[0] >= 0x80) { - t.asn1len ++; - } - return t; -} - -/* see inner.h */ -size_t -br_asn1_encode_length(void *dest, size_t len) -{ - unsigned char *buf; - size_t z; - int i, j; - - buf = dest; - if (len < 0x80) { - if (buf != NULL) { - *buf = len; - } - return 1; - } - i = 0; - for (z = len; z != 0; z >>= 8) { - i ++; - } - if (buf != NULL) { - *buf ++ = 0x80 + i; - for (j = i - 1; j >= 0; j --) { - *buf ++ = len >> (j << 3); - } - } - return i + 1; -} - -/* see inner.h */ -size_t -br_asn1_encode_uint(void *dest, br_asn1_uint pp) -{ - unsigned char *buf; - size_t lenlen; - - if (dest == NULL) { - return 1 + br_asn1_encode_length(NULL, pp.asn1len) + pp.asn1len; - } - buf = dest; - *buf ++ = 0x02; - lenlen = br_asn1_encode_length(buf, pp.asn1len); - buf += lenlen; - *buf = 0x00; - memcpy(buf + pp.asn1len - pp.len, pp.data, pp.len); - return 1 + lenlen + pp.asn1len; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/bearssl.h b/src/tls/bearssl/bearssl.h deleted file mode 100644 index 4f4797cf7..000000000 --- a/src/tls/bearssl/bearssl.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef BR_BEARSSL_H__ -#define BR_BEARSSL_H__ - -#include -#include - -/** \mainpage BearSSL API - * - * # API Layout - * - * The functions and structures defined by the BearSSL API are located - * in various header files: - * - * | Header file | Elements | - * | :-------------- | :------------------------------------------------ | - * | bearssl_hash.h | Hash functions | - * | bearssl_hmac.h | HMAC | - * | bearssl_kdf.h | Key Derivation Functions | - * | bearssl_rand.h | Pseudorandom byte generators | - * | bearssl_prf.h | PRF implementations (for SSL/TLS) | - * | bearssl_block.h | Symmetric encryption | - * | bearssl_aead.h | AEAD algorithms (combined encryption + MAC) | - * | bearssl_rsa.h | RSA encryption and signatures | - * | bearssl_ec.h | Elliptic curves support (including ECDSA) | - * | bearssl_ssl.h | SSL/TLS engine interface | - * | bearssl_x509.h | X.509 certificate decoding and validation | - * | bearssl_pem.h | Base64/PEM decoding support functions | - * - * Applications using BearSSL are supposed to simply include `bearssl.h` - * as follows: - * - * #include - * - * The `bearssl.h` file itself includes all the other header files. It is - * possible to include specific header files, but it has no practical - * advantage for the application. The API is separated into separate - * header files only for documentation convenience. - * - * - * # Conventions - * - * ## MUST and SHALL - * - * In all descriptions, the usual "MUST", "SHALL", "MAY",... terminology - * is used. Failure to meet requirements expressed with a "MUST" or - * "SHALL" implies undefined behaviour, which means that segmentation - * faults, buffer overflows, and other similar adverse events, may occur. - * - * In general, BearSSL is not very forgiving of programming errors, and - * does not include much failsafes or error reporting when the problem - * does not arise from external transient conditions, and can be fixed - * only in the application code. This is done so in order to make the - * total code footprint lighter. - * - * - * ## `NULL` values - * - * Function parameters with a pointer type shall not be `NULL` unless - * explicitly authorised by the documentation. As an exception, when - * the pointer aims at a sequence of bytes and is accompanied with - * a length parameter, and the length is zero (meaning that there is - * no byte at all to retrieve), then the pointer may be `NULL` even if - * not explicitly allowed. - * - * - * ## Memory Allocation - * - * BearSSL does not perform dynamic memory allocation. This implies that - * for any functionality that requires a non-transient state, the caller - * is responsible for allocating the relevant context structure. Such - * allocation can be done in any appropriate area, including static data - * segments, the heap, and the stack, provided that proper alignment is - * respected. The header files define these context structures - * (including size and contents), so the C compiler should handle - * alignment automatically. - * - * Since there is no dynamic resource allocation, there is also nothing to - * release. When the calling code is done with a BearSSL feature, it - * may simple release the context structures it allocated itself, with - * no "close function" to call. If the context structures were allocated - * on the stack (as local variables), then even that release operation is - * implicit. - * - * - * ## Structure Contents - * - * Except when explicitly indicated, structure contents are opaque: they - * are included in the header files so that calling code may know the - * structure sizes and alignment requirements, but callers SHALL NOT - * access individual fields directly. For fields that are supposed to - * be read from or written to, the API defines accessor functions (the - * simplest of these accessor functions are defined as `static inline` - * functions, and the C compiler will optimise them away). - * - * - * # API Usage - * - * BearSSL usage for running a SSL/TLS client or server is described - * on the [BearSSL Web site](https://www.bearssl.org/api1.html). The - * BearSSL source archive also comes with sample code. - */ - -#include "bearssl_hash.h" -#include "bearssl_hmac.h" -#include "bearssl_kdf.h" -#include "bearssl_rand.h" -#include "bearssl_prf.h" -#include "bearssl_block.h" -#include "bearssl_aead.h" -#include "bearssl_rsa.h" -#include "bearssl_ec.h" -#include "bearssl_ssl.h" -#include "bearssl_x509.h" -#include "bearssl_pem.h" - -/** \brief Type for a configuration option. - * - * A "configuration option" is a value that is selected when the BearSSL - * library itself is compiled. Most options are boolean; their value is - * then either 1 (option is enabled) or 0 (option is disabled). Some - * values have other integer values. Option names correspond to macro - * names. Some of the options can be explicitly set in the internal - * `"config.h"` file. - */ -typedef struct { - /** \brief Configurable option name. */ - const char *name; - /** \brief Configurable option value. */ - long value; -} br_config_option; - -/** \brief Get configuration report. - * - * This function returns compiled configuration options, each as a - * 'long' value. Names match internal macro names, in particular those - * that can be set in the `"config.h"` inner file. For boolean options, - * the numerical value is 1 if enabled, 0 if disabled. For maximum - * key sizes, values are expressed in bits. - * - * The returned array is terminated by an entry whose `name` is `NULL`. - * - * \return the configuration report. - */ -const br_config_option *br_get_config(void); - -#endif diff --git a/src/tls/bearssl/bearssl_aead.h b/src/tls/bearssl/bearssl_aead.h deleted file mode 100644 index 8e35a1fde..000000000 --- a/src/tls/bearssl/bearssl_aead.h +++ /dev/null @@ -1,1059 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef BR_BEARSSL_AEAD_H__ -#define BR_BEARSSL_AEAD_H__ - -#include -#include - -#include "bearssl_block.h" -#include "bearssl_hash.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** \file bearssl_aead.h - * - * # Authenticated Encryption with Additional Data - * - * This file documents the API for AEAD encryption. - * - * - * ## Procedural API - * - * An AEAD algorithm processes messages and provides confidentiality - * (encryption) and checked integrity (MAC). It uses the following - * parameters: - * - * - A symmetric key. Exact size depends on the AEAD algorithm. - * - * - A nonce (IV). Size depends on the AEAD algorithm; for most - * algorithms, it is crucial for security that any given nonce - * value is never used twice for the same key and distinct - * messages. - * - * - Data to encrypt and protect. - * - * - Additional authenticated data, which is covered by the MAC but - * otherwise left untouched (i.e. not encrypted). - * - * The AEAD algorithm encrypts the data, and produces an authentication - * tag. It is assumed that the encrypted data, the tag, the additional - * authenticated data and the nonce are sent to the receiver; the - * additional data and the nonce may be implicit (e.g. using elements of - * the underlying transport protocol, such as record sequence numbers). - * The receiver will recompute the tag value and compare it with the one - * received; if they match, then the data is correct, and can be - * decrypted and used; otherwise, at least one of the elements was - * altered in transit, normally leading to wholesale rejection of the - * complete message. - * - * For each AEAD algorithm, identified by a symbolic name (hereafter - * denoted as "`xxx`"), the following functions are defined: - * - * - `br_xxx_init()` - * - * Initialise the AEAD algorithm, on a provided context structure. - * Exact parameters depend on the algorithm, and may include - * pointers to extra implementations and context structures. The - * secret key is provided at this point, either directly or - * indirectly. - * - * - `br_xxx_reset()` - * - * Start a new AEAD computation. The nonce value is provided as - * parameter to this function. - * - * - `br_xxx_aad_inject()` - * - * Inject some additional authenticated data. Additional data may - * be provided in several chunks of arbitrary length. - * - * - `br_xxx_flip()` - * - * This function MUST be called after injecting all additional - * authenticated data, and before beginning to encrypt the plaintext - * (or decrypt the ciphertext). - * - * - `br_xxx_run()` - * - * Process some plaintext (to encrypt) or ciphertext (to decrypt). - * Encryption/decryption is done in place. Data may be provided in - * several chunks of arbitrary length. - * - * - `br_xxx_get_tag()` - * - * Compute the authentication tag. All message data (encrypted or - * decrypted) must have been injected at that point. Also, this - * call may modify internal context elements, so it may be called - * only once for a given AEAD computation. - * - * - `br_xxx_check_tag()` - * - * An alternative to `br_xxx_get_tag()`, meant to be used by the - * receiver: the authentication tag is internally recomputed, and - * compared with the one provided as parameter. - * - * This API makes the following assumptions on the AEAD algorithm: - * - * - Encryption does not expand the size of the ciphertext; there is - * no padding. This is true of most modern AEAD modes such as GCM. - * - * - The additional authenticated data must be processed first, - * before the encrypted/decrypted data. - * - * - Nonce, plaintext and additional authenticated data all consist - * in an integral number of bytes. There is no provision to use - * elements whose length in bits is not a multiple of 8. - * - * Each AEAD algorithm has its own requirements and limits on the sizes - * of additional data and plaintext. This API does not provide any - * way to report invalid usage; it is up to the caller to ensure that - * the provided key, nonce, and data elements all fit the algorithm's - * requirements. - * - * - * ## Object-Oriented API - * - * Each context structure begins with a field (called `vtable`) that - * points to an instance of a structure that references the relevant - * functions through pointers. Each such structure contains the - * following: - * - * - `reset` - * - * Pointer to the reset function, that allows starting a new - * computation. - * - * - `aad_inject` - * - * Pointer to the additional authenticated data injection function. - * - * - `flip` - * - * Pointer to the function that transitions from additional data - * to main message data processing. - * - * - `get_tag` - * - * Pointer to the function that computes and returns the tag. - * - * - `check_tag` - * - * Pointer to the function that computes and verifies the tag against - * a received value. - * - * Note that there is no OOP method for context initialisation: the - * various AEAD algorithms have different requirements that would not - * map well to a single initialisation API. - * - * The OOP API is not provided for CCM, due to its specific requirements - * (length of plaintext must be known in advance). - */ - -/** - * \brief Class type of an AEAD algorithm. - */ -typedef struct br_aead_class_ br_aead_class; -struct br_aead_class_ { - - /** - * \brief Size (in bytes) of authentication tags created by - * this AEAD algorithm. - */ - size_t tag_size; - - /** - * \brief Reset an AEAD context. - * - * This function resets an already initialised AEAD context for - * a new computation run. Implementations and keys are - * conserved. This function can be called at any time; it - * cancels any ongoing AEAD computation that uses the provided - * context structure. - - * The provided IV is a _nonce_. Each AEAD algorithm has its - * own requirements on IV size and contents; for most of them, - * it is crucial to security that each nonce value is used - * only once for a given secret key. - * - * \param cc AEAD context structure. - * \param iv AEAD nonce to use. - * \param len AEAD nonce length (in bytes). - */ - void (*reset)(const br_aead_class **cc, const void *iv, size_t len); - - /** - * \brief Inject additional authenticated data. - * - * The provided data is injected into a running AEAD - * computation. Additional data must be injected _before_ the - * call to `flip()`. Additional data can be injected in several - * chunks of arbitrary length. - * - * \param cc AEAD context structure. - * \param data pointer to additional authenticated data. - * \param len length of additional authenticated data (in bytes). - */ - void (*aad_inject)(const br_aead_class **cc, - const void *data, size_t len); - - /** - * \brief Finish injection of additional authenticated data. - * - * This function MUST be called before beginning the actual - * encryption or decryption (with `run()`), even if no - * additional authenticated data was injected. No additional - * authenticated data may be injected after this function call. - * - * \param cc AEAD context structure. - */ - void (*flip)(const br_aead_class **cc); - - /** - * \brief Encrypt or decrypt some data. - * - * Data encryption or decryption can be done after `flip()` has - * been called on the context. If `encrypt` is non-zero, then - * the provided data shall be plaintext, and it is encrypted in - * place. Otherwise, the data shall be ciphertext, and it is - * decrypted in place. - * - * Data may be provided in several chunks of arbitrary length. - * - * \param cc AEAD context structure. - * \param encrypt non-zero for encryption, zero for decryption. - * \param data data to encrypt or decrypt. - * \param len data length (in bytes). - */ - void (*run)(const br_aead_class **cc, int encrypt, - void *data, size_t len); - - /** - * \brief Compute authentication tag. - * - * Compute the AEAD authentication tag. The tag length depends - * on the AEAD algorithm; it is written in the provided `tag` - * buffer. This call terminates the AEAD run: no data may be - * processed with that AEAD context afterwards, until `reset()` - * is called to initiate a new AEAD run. - * - * The tag value must normally be sent along with the encrypted - * data. When decrypting, the tag value must be recomputed and - * compared with the received tag: if the two tag values differ, - * then either the tag or the encrypted data was altered in - * transit. As an alternative to this function, the - * `check_tag()` function may be used to compute and check the - * tag value. - * - * Tag length depends on the AEAD algorithm. - * - * \param cc AEAD context structure. - * \param tag destination buffer for the tag. - */ - void (*get_tag)(const br_aead_class **cc, void *tag); - - /** - * \brief Compute and check authentication tag. - * - * This function is an alternative to `get_tag()`, and is - * normally used on the receiving end (i.e. when decrypting - * messages). The tag value is recomputed and compared with the - * provided tag value. If they match, 1 is returned; on - * mismatch, 0 is returned. A returned value of 0 means that the - * data or the tag was altered in transit, normally leading to - * wholesale rejection of the complete message. - * - * Tag length depends on the AEAD algorithm. - * - * \param cc AEAD context structure. - * \param tag tag value to compare with. - * \return 1 on success (exact match of tag value), 0 otherwise. - */ - uint32_t (*check_tag)(const br_aead_class **cc, const void *tag); - - /** - * \brief Compute authentication tag (with truncation). - * - * This function is similar to `get_tag()`, except that the tag - * length is provided. Some AEAD algorithms allow several tag - * lengths, usually by truncating the normal tag. Shorter tags - * mechanically increase success probability of forgeries. - * The range of allowed tag lengths depends on the algorithm. - * - * \param cc AEAD context structure. - * \param tag destination buffer for the tag. - * \param len tag length (in bytes). - */ - void (*get_tag_trunc)(const br_aead_class **cc, void *tag, size_t len); - - /** - * \brief Compute and check authentication tag (with truncation). - * - * This function is similar to `check_tag()` except that it - * works over an explicit tag length. See `get_tag()` for a - * discussion of explicit tag lengths; the range of allowed tag - * lengths depends on the algorithm. - * - * \param cc AEAD context structure. - * \param tag tag value to compare with. - * \param len tag length (in bytes). - * \return 1 on success (exact match of tag value), 0 otherwise. - */ - uint32_t (*check_tag_trunc)(const br_aead_class **cc, - const void *tag, size_t len); -}; - -/** - * \brief Context structure for GCM. - * - * GCM is an AEAD mode that combines a block cipher in CTR mode with a - * MAC based on GHASH, to provide authenticated encryption: - * - * - Any block cipher with 16-byte blocks can be used with GCM. - * - * - The nonce can have any length, from 0 up to 2^64-1 bits; however, - * 96-bit nonces (12 bytes) are recommended (nonces with a length - * distinct from 12 bytes are internally hashed, which risks reusing - * nonce value with a small but not always negligible probability). - * - * - Additional authenticated data may have length up to 2^64-1 bits. - * - * - Message length may range up to 2^39-256 bits at most. - * - * - The authentication tag has length 16 bytes. - * - * The GCM initialisation function receives as parameter an - * _initialised_ block cipher implementation context, with the secret - * key already set. A pointer to that context will be kept within the - * GCM context structure. It is up to the caller to allocate and - * initialise that block cipher context. - */ -typedef struct { - /** \brief Pointer to vtable for this context. */ - const br_aead_class *vtable; - -#ifndef BR_DOXYGEN_IGNORE - const br_block_ctr_class **bctx; - br_ghash gh; - unsigned char h[16]; - unsigned char j0_1[12]; - unsigned char buf[16]; - unsigned char y[16]; - uint32_t j0_2, jc; - uint64_t count_aad, count_ctr; -#endif -} br_gcm_context; - -/** - * \brief Initialize a GCM context. - * - * A block cipher implementation, with its initialised context structure, - * is provided. The block cipher MUST use 16-byte blocks in CTR mode, - * and its secret key MUST have been already set in the provided context. - * A GHASH implementation must also be provided. The parameters are linked - * in the GCM context. - * - * After this function has been called, the `br_gcm_reset()` function must - * be called, to provide the IV for GCM computation. - * - * \param ctx GCM context structure. - * \param bctx block cipher context (already initialised with secret key). - * \param gh GHASH implementation. - */ -void br_gcm_init(br_gcm_context *ctx, - const br_block_ctr_class **bctx, br_ghash gh); - -/** - * \brief Reset a GCM context. - * - * This function resets an already initialised GCM context for a new - * computation run. Implementations and keys are conserved. This function - * can be called at any time; it cancels any ongoing GCM computation that - * uses the provided context structure. - * - * The provided IV is a _nonce_. It is critical to GCM security that IV - * values are not repeated for the same encryption key. IV can have - * arbitrary length (up to 2^64-1 bits), but the "normal" length is - * 96 bits (12 bytes). - * - * \param ctx GCM context structure. - * \param iv GCM nonce to use. - * \param len GCM nonce length (in bytes). - */ -void br_gcm_reset(br_gcm_context *ctx, const void *iv, size_t len); - -/** - * \brief Inject additional authenticated data into GCM. - * - * The provided data is injected into a running GCM computation. Additional - * data must be injected _before_ the call to `br_gcm_flip()`. - * Additional data can be injected in several chunks of arbitrary length; - * the maximum total size of additional authenticated data is 2^64-1 - * bits. - * - * \param ctx GCM context structure. - * \param data pointer to additional authenticated data. - * \param len length of additional authenticated data (in bytes). - */ -void br_gcm_aad_inject(br_gcm_context *ctx, const void *data, size_t len); - -/** - * \brief Finish injection of additional authenticated data into GCM. - * - * This function MUST be called before beginning the actual encryption - * or decryption (with `br_gcm_run()`), even if no additional authenticated - * data was injected. No additional authenticated data may be injected - * after this function call. - * - * \param ctx GCM context structure. - */ -void br_gcm_flip(br_gcm_context *ctx); - -/** - * \brief Encrypt or decrypt some data with GCM. - * - * Data encryption or decryption can be done after `br_gcm_flip()` - * has been called on the context. If `encrypt` is non-zero, then the - * provided data shall be plaintext, and it is encrypted in place. - * Otherwise, the data shall be ciphertext, and it is decrypted in place. - * - * Data may be provided in several chunks of arbitrary length. The maximum - * total length for data is 2^39-256 bits, i.e. about 65 gigabytes. - * - * \param ctx GCM context structure. - * \param encrypt non-zero for encryption, zero for decryption. - * \param data data to encrypt or decrypt. - * \param len data length (in bytes). - */ -void br_gcm_run(br_gcm_context *ctx, int encrypt, void *data, size_t len); - -/** - * \brief Compute GCM authentication tag. - * - * Compute the GCM authentication tag. The tag is a 16-byte value which - * is written in the provided `tag` buffer. This call terminates the - * GCM run: no data may be processed with that GCM context afterwards, - * until `br_gcm_reset()` is called to initiate a new GCM run. - * - * The tag value must normally be sent along with the encrypted data. - * When decrypting, the tag value must be recomputed and compared with - * the received tag: if the two tag values differ, then either the tag - * or the encrypted data was altered in transit. As an alternative to - * this function, the `br_gcm_check_tag()` function can be used to - * compute and check the tag value. - * - * \param ctx GCM context structure. - * \param tag destination buffer for the tag (16 bytes). - */ -void br_gcm_get_tag(br_gcm_context *ctx, void *tag); - -/** - * \brief Compute and check GCM authentication tag. - * - * This function is an alternative to `br_gcm_get_tag()`, normally used - * on the receiving end (i.e. when decrypting value). The tag value is - * recomputed and compared with the provided tag value. If they match, 1 - * is returned; on mismatch, 0 is returned. A returned value of 0 means - * that the data or the tag was altered in transit, normally leading to - * wholesale rejection of the complete message. - * - * \param ctx GCM context structure. - * \param tag tag value to compare with (16 bytes). - * \return 1 on success (exact match of tag value), 0 otherwise. - */ -uint32_t br_gcm_check_tag(br_gcm_context *ctx, const void *tag); - -/** - * \brief Compute GCM authentication tag (with truncation). - * - * This function is similar to `br_gcm_get_tag()`, except that it allows - * the tag to be truncated to a smaller length. The intended tag length - * is provided as `len` (in bytes); it MUST be no more than 16, but - * it may be smaller. Note that decreasing tag length mechanically makes - * forgeries easier; NIST SP 800-38D specifies that the tag length shall - * lie between 12 and 16 bytes (inclusive), but may be truncated down to - * 4 or 8 bytes, for specific applications that can tolerate it. It must - * also be noted that successful forgeries leak information on the - * authentication key, making subsequent forgeries easier. Therefore, - * tag truncation, and in particular truncation to sizes lower than 12 - * bytes, shall be envisioned only with great care. - * - * The tag is written in the provided `tag` buffer. This call terminates - * the GCM run: no data may be processed with that GCM context - * afterwards, until `br_gcm_reset()` is called to initiate a new GCM - * run. - * - * The tag value must normally be sent along with the encrypted data. - * When decrypting, the tag value must be recomputed and compared with - * the received tag: if the two tag values differ, then either the tag - * or the encrypted data was altered in transit. As an alternative to - * this function, the `br_gcm_check_tag_trunc()` function can be used to - * compute and check the tag value. - * - * \param ctx GCM context structure. - * \param tag destination buffer for the tag. - * \param len tag length (16 bytes or less). - */ -void br_gcm_get_tag_trunc(br_gcm_context *ctx, void *tag, size_t len); - -/** - * \brief Compute and check GCM authentication tag (with truncation). - * - * This function is an alternative to `br_gcm_get_tag_trunc()`, normally used - * on the receiving end (i.e. when decrypting value). The tag value is - * recomputed and compared with the provided tag value. If they match, 1 - * is returned; on mismatch, 0 is returned. A returned value of 0 means - * that the data or the tag was altered in transit, normally leading to - * wholesale rejection of the complete message. - * - * Tag length MUST be 16 bytes or less. The normal GCM tag length is 16 - * bytes. See `br_check_tag_trunc()` for some discussion on the potential - * perils of truncating authentication tags. - * - * \param ctx GCM context structure. - * \param tag tag value to compare with. - * \param len tag length (in bytes). - * \return 1 on success (exact match of tag value), 0 otherwise. - */ -uint32_t br_gcm_check_tag_trunc(br_gcm_context *ctx, - const void *tag, size_t len); - -/** - * \brief Class instance for GCM. - */ -extern const br_aead_class br_gcm_vtable; - -/** - * \brief Context structure for EAX. - * - * EAX is an AEAD mode that combines a block cipher in CTR mode with - * CBC-MAC using the same block cipher and the same key, to provide - * authenticated encryption: - * - * - Any block cipher with 16-byte blocks can be used with EAX - * (technically, other block sizes are defined as well, but this - * is not implemented by these functions; shorter blocks also - * imply numerous security issues). - * - * - The nonce can have any length, as long as nonce values are - * not reused (thus, if nonces are randomly selected, the nonce - * size should be such that reuse probability is negligible). - * - * - Additional authenticated data length is unlimited. - * - * - Message length is unlimited. - * - * - The authentication tag has length 16 bytes. - * - * The EAX initialisation function receives as parameter an - * _initialised_ block cipher implementation context, with the secret - * key already set. A pointer to that context will be kept within the - * EAX context structure. It is up to the caller to allocate and - * initialise that block cipher context. - */ -typedef struct { - /** \brief Pointer to vtable for this context. */ - const br_aead_class *vtable; - -#ifndef BR_DOXYGEN_IGNORE - const br_block_ctrcbc_class **bctx; - unsigned char L2[16]; - unsigned char L4[16]; - unsigned char nonce[16]; - unsigned char head[16]; - unsigned char ctr[16]; - unsigned char cbcmac[16]; - unsigned char buf[16]; - size_t ptr; -#endif -} br_eax_context; - -/** - * \brief EAX captured state. - * - * Some internal values computed by EAX may be captured at various - * points, and reused for another EAX run with the same secret key, - * for lower per-message overhead. Captured values do not depend on - * the nonce. - */ -typedef struct { -#ifndef BR_DOXYGEN_IGNORE - unsigned char st[3][16]; -#endif -} br_eax_state; - -/** - * \brief Initialize an EAX context. - * - * A block cipher implementation, with its initialised context - * structure, is provided. The block cipher MUST use 16-byte blocks in - * CTR + CBC-MAC mode, and its secret key MUST have been already set in - * the provided context. The parameters are linked in the EAX context. - * - * After this function has been called, the `br_eax_reset()` function must - * be called, to provide the nonce for EAX computation. - * - * \param ctx EAX context structure. - * \param bctx block cipher context (already initialised with secret key). - */ -void br_eax_init(br_eax_context *ctx, const br_block_ctrcbc_class **bctx); - -/** - * \brief Capture pre-AAD state. - * - * This function precomputes key-dependent data, and stores it in the - * provided `st` structure. This structure should then be used with - * `br_eax_reset_pre_aad()`, or updated with `br_eax_get_aad_mac()` - * and then used with `br_eax_reset_post_aad()`. - * - * The EAX context structure is unmodified by this call. - * - * \param ctx EAX context structure. - * \param st recipient for captured state. - */ -void br_eax_capture(const br_eax_context *ctx, br_eax_state *st); - -/** - * \brief Reset an EAX context. - * - * This function resets an already initialised EAX context for a new - * computation run. Implementations and keys are conserved. This function - * can be called at any time; it cancels any ongoing EAX computation that - * uses the provided context structure. - * - * It is critical to EAX security that nonce values are not repeated for - * the same encryption key. Nonces can have arbitrary length. If nonces - * are randomly generated, then a nonce length of at least 128 bits (16 - * bytes) is recommended, to make nonce reuse probability sufficiently - * low. - * - * \param ctx EAX context structure. - * \param nonce EAX nonce to use. - * \param len EAX nonce length (in bytes). - */ -void br_eax_reset(br_eax_context *ctx, const void *nonce, size_t len); - -/** - * \brief Reset an EAX context with a pre-AAD captured state. - * - * This function is an alternative to `br_eax_reset()`, that reuses a - * previously captured state structure for lower per-message overhead. - * The state should have been populated with `br_eax_capture_state()` - * but not updated with `br_eax_get_aad_mac()`. - * - * After this function is called, additional authenticated data MUST - * be injected. At least one byte of additional authenticated data - * MUST be provided with `br_eax_aad_inject()`; computation result will - * be incorrect if `br_eax_flip()` is called right away. - * - * After injection of the AAD and call to `br_eax_flip()`, at least - * one message byte must be provided. Empty messages are not supported - * with this reset mode. - * - * \param ctx EAX context structure. - * \param st pre-AAD captured state. - * \param nonce EAX nonce to use. - * \param len EAX nonce length (in bytes). - */ -void br_eax_reset_pre_aad(br_eax_context *ctx, const br_eax_state *st, - const void *nonce, size_t len); - -/** - * \brief Reset an EAX context with a post-AAD captured state. - * - * This function is an alternative to `br_eax_reset()`, that reuses a - * previously captured state structure for lower per-message overhead. - * The state should have been populated with `br_eax_capture_state()` - * and then updated with `br_eax_get_aad_mac()`. - * - * After this function is called, message data MUST be injected. The - * `br_eax_flip()` function MUST NOT be called. At least one byte of - * message data MUST be provided with `br_eax_run()`; empty messages - * are not supported with this reset mode. - * - * \param ctx EAX context structure. - * \param st post-AAD captured state. - * \param nonce EAX nonce to use. - * \param len EAX nonce length (in bytes). - */ -void br_eax_reset_post_aad(br_eax_context *ctx, const br_eax_state *st, - const void *nonce, size_t len); - -/** - * \brief Inject additional authenticated data into EAX. - * - * The provided data is injected into a running EAX computation. Additional - * data must be injected _before_ the call to `br_eax_flip()`. - * Additional data can be injected in several chunks of arbitrary length; - * the total amount of additional authenticated data is unlimited. - * - * \param ctx EAX context structure. - * \param data pointer to additional authenticated data. - * \param len length of additional authenticated data (in bytes). - */ -void br_eax_aad_inject(br_eax_context *ctx, const void *data, size_t len); - -/** - * \brief Finish injection of additional authenticated data into EAX. - * - * This function MUST be called before beginning the actual encryption - * or decryption (with `br_eax_run()`), even if no additional authenticated - * data was injected. No additional authenticated data may be injected - * after this function call. - * - * \param ctx EAX context structure. - */ -void br_eax_flip(br_eax_context *ctx); - -/** - * \brief Obtain a copy of the MAC on additional authenticated data. - * - * This function may be called only after `br_eax_flip()`; it copies the - * AAD-specific MAC value into the provided state. The MAC value depends - * on the secret key and the additional data itself, but not on the - * nonce. The updated state `st` is meant to be used as parameter for a - * further `br_eax_reset_post_aad()` call. - * - * \param ctx EAX context structure. - * \param st captured state to update. - */ -static inline void -br_eax_get_aad_mac(const br_eax_context *ctx, br_eax_state *st) -{ - memcpy(st->st[1], ctx->head, sizeof ctx->head); -} - -/** - * \brief Encrypt or decrypt some data with EAX. - * - * Data encryption or decryption can be done after `br_eax_flip()` - * has been called on the context. If `encrypt` is non-zero, then the - * provided data shall be plaintext, and it is encrypted in place. - * Otherwise, the data shall be ciphertext, and it is decrypted in place. - * - * Data may be provided in several chunks of arbitrary length. - * - * \param ctx EAX context structure. - * \param encrypt non-zero for encryption, zero for decryption. - * \param data data to encrypt or decrypt. - * \param len data length (in bytes). - */ -void br_eax_run(br_eax_context *ctx, int encrypt, void *data, size_t len); - -/** - * \brief Compute EAX authentication tag. - * - * Compute the EAX authentication tag. The tag is a 16-byte value which - * is written in the provided `tag` buffer. This call terminates the - * EAX run: no data may be processed with that EAX context afterwards, - * until `br_eax_reset()` is called to initiate a new EAX run. - * - * The tag value must normally be sent along with the encrypted data. - * When decrypting, the tag value must be recomputed and compared with - * the received tag: if the two tag values differ, then either the tag - * or the encrypted data was altered in transit. As an alternative to - * this function, the `br_eax_check_tag()` function can be used to - * compute and check the tag value. - * - * \param ctx EAX context structure. - * \param tag destination buffer for the tag (16 bytes). - */ -void br_eax_get_tag(br_eax_context *ctx, void *tag); - -/** - * \brief Compute and check EAX authentication tag. - * - * This function is an alternative to `br_eax_get_tag()`, normally used - * on the receiving end (i.e. when decrypting value). The tag value is - * recomputed and compared with the provided tag value. If they match, 1 - * is returned; on mismatch, 0 is returned. A returned value of 0 means - * that the data or the tag was altered in transit, normally leading to - * wholesale rejection of the complete message. - * - * \param ctx EAX context structure. - * \param tag tag value to compare with (16 bytes). - * \return 1 on success (exact match of tag value), 0 otherwise. - */ -uint32_t br_eax_check_tag(br_eax_context *ctx, const void *tag); - -/** - * \brief Compute EAX authentication tag (with truncation). - * - * This function is similar to `br_eax_get_tag()`, except that it allows - * the tag to be truncated to a smaller length. The intended tag length - * is provided as `len` (in bytes); it MUST be no more than 16, but - * it may be smaller. Note that decreasing tag length mechanically makes - * forgeries easier; NIST SP 800-38D specifies that the tag length shall - * lie between 12 and 16 bytes (inclusive), but may be truncated down to - * 4 or 8 bytes, for specific applications that can tolerate it. It must - * also be noted that successful forgeries leak information on the - * authentication key, making subsequent forgeries easier. Therefore, - * tag truncation, and in particular truncation to sizes lower than 12 - * bytes, shall be envisioned only with great care. - * - * The tag is written in the provided `tag` buffer. This call terminates - * the EAX run: no data may be processed with that EAX context - * afterwards, until `br_eax_reset()` is called to initiate a new EAX - * run. - * - * The tag value must normally be sent along with the encrypted data. - * When decrypting, the tag value must be recomputed and compared with - * the received tag: if the two tag values differ, then either the tag - * or the encrypted data was altered in transit. As an alternative to - * this function, the `br_eax_check_tag_trunc()` function can be used to - * compute and check the tag value. - * - * \param ctx EAX context structure. - * \param tag destination buffer for the tag. - * \param len tag length (16 bytes or less). - */ -void br_eax_get_tag_trunc(br_eax_context *ctx, void *tag, size_t len); - -/** - * \brief Compute and check EAX authentication tag (with truncation). - * - * This function is an alternative to `br_eax_get_tag_trunc()`, normally used - * on the receiving end (i.e. when decrypting value). The tag value is - * recomputed and compared with the provided tag value. If they match, 1 - * is returned; on mismatch, 0 is returned. A returned value of 0 means - * that the data or the tag was altered in transit, normally leading to - * wholesale rejection of the complete message. - * - * Tag length MUST be 16 bytes or less. The normal EAX tag length is 16 - * bytes. See `br_check_tag_trunc()` for some discussion on the potential - * perils of truncating authentication tags. - * - * \param ctx EAX context structure. - * \param tag tag value to compare with. - * \param len tag length (in bytes). - * \return 1 on success (exact match of tag value), 0 otherwise. - */ -uint32_t br_eax_check_tag_trunc(br_eax_context *ctx, - const void *tag, size_t len); - -/** - * \brief Class instance for EAX. - */ -extern const br_aead_class br_eax_vtable; - -/** - * \brief Context structure for CCM. - * - * CCM is an AEAD mode that combines a block cipher in CTR mode with - * CBC-MAC using the same block cipher and the same key, to provide - * authenticated encryption: - * - * - Any block cipher with 16-byte blocks can be used with CCM - * (technically, other block sizes are defined as well, but this - * is not implemented by these functions; shorter blocks also - * imply numerous security issues). - * - * - The authentication tag length, and plaintext length, MUST be - * known when starting processing data. Plaintext and ciphertext - * can still be provided by chunks, but the total size must match - * the value provided upon initialisation. - * - * - The nonce length is constrained between 7 and 13 bytes (inclusive). - * Furthermore, the plaintext length, when encoded, must fit over - * 15-nonceLen bytes; thus, if the nonce has length 13 bytes, then - * the plaintext length cannot exceed 65535 bytes. - * - * - Additional authenticated data length is practically unlimited - * (formal limit is at 2^64 bytes). - * - * - The authentication tag has length 4 to 16 bytes (even values only). - * - * The CCM initialisation function receives as parameter an - * _initialised_ block cipher implementation context, with the secret - * key already set. A pointer to that context will be kept within the - * CCM context structure. It is up to the caller to allocate and - * initialise that block cipher context. - */ -typedef struct { -#ifndef BR_DOXYGEN_IGNORE - const br_block_ctrcbc_class **bctx; - unsigned char ctr[16]; - unsigned char cbcmac[16]; - unsigned char tagmask[16]; - unsigned char buf[16]; - size_t ptr; - size_t tag_len; -#endif -} br_ccm_context; - -/** - * \brief Initialize a CCM context. - * - * A block cipher implementation, with its initialised context - * structure, is provided. The block cipher MUST use 16-byte blocks in - * CTR + CBC-MAC mode, and its secret key MUST have been already set in - * the provided context. The parameters are linked in the CCM context. - * - * After this function has been called, the `br_ccm_reset()` function must - * be called, to provide the nonce for CCM computation. - * - * \param ctx CCM context structure. - * \param bctx block cipher context (already initialised with secret key). - */ -void br_ccm_init(br_ccm_context *ctx, const br_block_ctrcbc_class **bctx); - -/** - * \brief Reset a CCM context. - * - * This function resets an already initialised CCM context for a new - * computation run. Implementations and keys are conserved. This function - * can be called at any time; it cancels any ongoing CCM computation that - * uses the provided context structure. - * - * The `aad_len` parameter contains the total length, in bytes, of the - * additional authenticated data. It may be zero. That length MUST be - * exact. - * - * The `data_len` parameter contains the total length, in bytes, of the - * data that will be injected (plaintext or ciphertext). That length MUST - * be exact. Moreover, that length MUST be less than 2^(8*(15-nonce_len)). - * - * The nonce length (`nonce_len`), in bytes, must be in the 7..13 range - * (inclusive). - * - * The tag length (`tag_len`), in bytes, must be in the 4..16 range, and - * be an even integer. Short tags mechanically allow for higher forgery - * probabilities; hence, tag sizes smaller than 12 bytes shall be used only - * with care. - * - * It is critical to CCM security that nonce values are not repeated for - * the same encryption key. Random generation of nonces is not generally - * recommended, due to the relatively small maximum nonce value. - * - * Returned value is 1 on success, 0 on error. An error is reported if - * the tag or nonce length is out of range, or if the - * plaintext/ciphertext length cannot be encoded with the specified - * nonce length. - * - * \param ctx CCM context structure. - * \param nonce CCM nonce to use. - * \param nonce_len CCM nonce length (in bytes, 7 to 13). - * \param aad_len additional authenticated data length (in bytes). - * \param data_len plaintext/ciphertext length (in bytes). - * \param tag_len tag length (in bytes). - * \return 1 on success, 0 on error. - */ -int br_ccm_reset(br_ccm_context *ctx, const void *nonce, size_t nonce_len, - uint64_t aad_len, uint64_t data_len, size_t tag_len); - -/** - * \brief Inject additional authenticated data into CCM. - * - * The provided data is injected into a running CCM computation. Additional - * data must be injected _before_ the call to `br_ccm_flip()`. - * Additional data can be injected in several chunks of arbitrary length, - * but the total amount MUST exactly match the value which was provided - * to `br_ccm_reset()`. - * - * \param ctx CCM context structure. - * \param data pointer to additional authenticated data. - * \param len length of additional authenticated data (in bytes). - */ -void br_ccm_aad_inject(br_ccm_context *ctx, const void *data, size_t len); - -/** - * \brief Finish injection of additional authenticated data into CCM. - * - * This function MUST be called before beginning the actual encryption - * or decryption (with `br_ccm_run()`), even if no additional authenticated - * data was injected. No additional authenticated data may be injected - * after this function call. - * - * \param ctx CCM context structure. - */ -void br_ccm_flip(br_ccm_context *ctx); - -/** - * \brief Encrypt or decrypt some data with CCM. - * - * Data encryption or decryption can be done after `br_ccm_flip()` - * has been called on the context. If `encrypt` is non-zero, then the - * provided data shall be plaintext, and it is encrypted in place. - * Otherwise, the data shall be ciphertext, and it is decrypted in place. - * - * Data may be provided in several chunks of arbitrary length, provided - * that the total length exactly matches the length provided to the - * `br_ccm_reset()` call. - * - * \param ctx CCM context structure. - * \param encrypt non-zero for encryption, zero for decryption. - * \param data data to encrypt or decrypt. - * \param len data length (in bytes). - */ -void br_ccm_run(br_ccm_context *ctx, int encrypt, void *data, size_t len); - -/** - * \brief Compute CCM authentication tag. - * - * Compute the CCM authentication tag. This call terminates the CCM - * run: all data must have been injected with `br_ccm_run()` (in zero, - * one or more successive calls). After this function has been called, - * no more data can br processed; a `br_ccm_reset()` call is required - * to start a new message. - * - * The tag length was provided upon context initialisation (last call - * to `br_ccm_reset()`); it is returned by this function. - * - * The tag value must normally be sent along with the encrypted data. - * When decrypting, the tag value must be recomputed and compared with - * the received tag: if the two tag values differ, then either the tag - * or the encrypted data was altered in transit. As an alternative to - * this function, the `br_ccm_check_tag()` function can be used to - * compute and check the tag value. - * - * \param ctx CCM context structure. - * \param tag destination buffer for the tag (up to 16 bytes). - * \return the tag length (in bytes). - */ -size_t br_ccm_get_tag(br_ccm_context *ctx, void *tag); - -/** - * \brief Compute and check CCM authentication tag. - * - * This function is an alternative to `br_ccm_get_tag()`, normally used - * on the receiving end (i.e. when decrypting value). The tag value is - * recomputed and compared with the provided tag value. If they match, 1 - * is returned; on mismatch, 0 is returned. A returned value of 0 means - * that the data or the tag was altered in transit, normally leading to - * wholesale rejection of the complete message. - * - * \param ctx CCM context structure. - * \param tag tag value to compare with (up to 16 bytes). - * \return 1 on success (exact match of tag value), 0 otherwise. - */ -uint32_t br_ccm_check_tag(br_ccm_context *ctx, const void *tag); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/tls/bearssl/bearssl_block.h b/src/tls/bearssl/bearssl_block.h deleted file mode 100644 index 683a4906d..000000000 --- a/src/tls/bearssl/bearssl_block.h +++ /dev/null @@ -1,2618 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef BR_BEARSSL_BLOCK_H__ -#define BR_BEARSSL_BLOCK_H__ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** \file bearssl_block.h - * - * # Block Ciphers and Symmetric Ciphers - * - * This file documents the API for block ciphers and other symmetric - * ciphers. - * - * - * ## Procedural API - * - * For a block cipher implementation, up to three separate sets of - * functions are provided, for CBC encryption, CBC decryption, and CTR - * encryption/decryption. Each set has its own context structure, - * initialised with the encryption key. - * - * For CBC encryption and decryption, the data to encrypt or decrypt is - * referenced as a sequence of blocks. The implementations assume that - * there is no partial block; no padding is applied or removed. The - * caller is responsible for handling any kind of padding. - * - * Function for CTR encryption are defined only for block ciphers with - * blocks of 16 bytes or more (i.e. AES, but not DES/3DES). - * - * Each implemented block cipher is identified by an "internal name" - * from which are derived the names of structures and functions that - * implement the cipher. For the block cipher of internal name "`xxx`", - * the following are defined: - * - * - `br_xxx_BLOCK_SIZE` - * - * A macro that evaluates to the block size (in bytes) of the - * cipher. For all implemented block ciphers, this value is a - * power of two. - * - * - `br_xxx_cbcenc_keys` - * - * Context structure that contains the subkeys resulting from the key - * expansion. These subkeys are appropriate for CBC encryption. The - * structure first field is called `vtable` and points to the - * appropriate OOP structure. - * - * - `br_xxx_cbcenc_init(br_xxx_cbcenc_keys *ctx, const void *key, size_t len)` - * - * Perform key expansion: subkeys for CBC encryption are computed and - * written in the provided context structure. The key length MUST be - * adequate for the implemented block cipher. This function also sets - * the `vtable` field. - * - * - `br_xxx_cbcenc_run(const br_xxx_cbcenc_keys *ctx, void *iv, void *data, size_t len)` - * - * Perform CBC encryption of `len` bytes, in place. The encrypted data - * replaces the cleartext. `len` MUST be a multiple of the block length - * (if it is not, the function may loop forever or overflow a buffer). - * The IV is provided with the `iv` pointer; it is also updated with - * a copy of the last encrypted block. - * - * - `br_xxx_cbcdec_keys` - * - * Context structure that contains the subkeys resulting from the key - * expansion. These subkeys are appropriate for CBC decryption. The - * structure first field is called `vtable` and points to the - * appropriate OOP structure. - * - * - `br_xxx_cbcdec_init(br_xxx_cbcenc_keys *ctx, const void *key, size_t len)` - * - * Perform key expansion: subkeys for CBC decryption are computed and - * written in the provided context structure. The key length MUST be - * adequate for the implemented block cipher. This function also sets - * the `vtable` field. - * - * - `br_xxx_cbcdec_run(const br_xxx_cbcdec_keys *ctx, void *iv, void *data, size_t num_blocks)` - * - * Perform CBC decryption of `len` bytes, in place. The decrypted data - * replaces the ciphertext. `len` MUST be a multiple of the block length - * (if it is not, the function may loop forever or overflow a buffer). - * The IV is provided with the `iv` pointer; it is also updated with - * a copy of the last _encrypted_ block. - * - * - `br_xxx_ctr_keys` - * - * Context structure that contains the subkeys resulting from the key - * expansion. These subkeys are appropriate for CTR encryption and - * decryption. The structure first field is called `vtable` and - * points to the appropriate OOP structure. - * - * - `br_xxx_ctr_init(br_xxx_ctr_keys *ctx, const void *key, size_t len)` - * - * Perform key expansion: subkeys for CTR encryption and decryption - * are computed and written in the provided context structure. The - * key length MUST be adequate for the implemented block cipher. This - * function also sets the `vtable` field. - * - * - `br_xxx_ctr_run(const br_xxx_ctr_keys *ctx, const void *iv, uint32_t cc, void *data, size_t len)` (returns `uint32_t`) - * - * Perform CTR encryption/decryption of some data. Processing is done - * "in place" (the output data replaces the input data). This function - * implements the "standard incrementing function" from NIST SP800-38A, - * annex B: the IV length shall be 4 bytes less than the block size - * (i.e. 12 bytes for AES) and the counter is the 32-bit value starting - * with `cc`. The data length (`len`) is not necessarily a multiple of - * the block size. The new counter value is returned, which supports - * chunked processing, provided that each chunk length (except possibly - * the last one) is a multiple of the block size. - * - * - `br_xxx_ctrcbc_keys` - * - * Context structure that contains the subkeys resulting from the - * key expansion. These subkeys are appropriate for doing combined - * CTR encryption/decryption and CBC-MAC, as used in the CCM and EAX - * authenticated encryption modes. The structure first field is - * called `vtable` and points to the appropriate OOP structure. - * - * - `br_xxx_ctrcbc_init(br_xxx_ctr_keys *ctx, const void *key, size_t len)` - * - * Perform key expansion: subkeys for combined CTR - * encryption/decryption and CBC-MAC are computed and written in the - * provided context structure. The key length MUST be adequate for - * the implemented block cipher. This function also sets the - * `vtable` field. - * - * - `br_xxx_ctrcbc_encrypt(const br_xxx_ctrcbc_keys *ctx, void *ctr, void *cbcmac, void *data, size_t len)` - * - * Perform CTR encryption of some data, and CBC-MAC. Processing is - * done "in place" (the output data replaces the input data). This - * function applies CTR encryption on the data, using a full - * block-size counter (i.e. for 128-bit blocks, the counter is - * incremented as a 128-bit value). The 'ctr' array contains the - * initial value for the counter (used in the first block) and it is - * updated with the new value after data processing. The 'cbcmac' - * value shall point to a block-sized value which is used as IV for - * CBC-MAC, computed over the encrypted data (output of CTR - * encryption); the resulting CBC-MAC is written over 'cbcmac' on - * output. - * - * The data length MUST be a multiple of the block size. - * - * - `br_xxx_ctrcbc_decrypt(const br_xxx_ctrcbc_keys *ctx, void *ctr, void *cbcmac, void *data, size_t len)` - * - * Perform CTR decryption of some data, and CBC-MAC. Processing is - * done "in place" (the output data replaces the input data). This - * function applies CTR decryption on the data, using a full - * block-size counter (i.e. for 128-bit blocks, the counter is - * incremented as a 128-bit value). The 'ctr' array contains the - * initial value for the counter (used in the first block) and it is - * updated with the new value after data processing. The 'cbcmac' - * value shall point to a block-sized value which is used as IV for - * CBC-MAC, computed over the encrypted data (input of CTR - * encryption); the resulting CBC-MAC is written over 'cbcmac' on - * output. - * - * The data length MUST be a multiple of the block size. - * - * - `br_xxx_ctrcbc_ctr(const br_xxx_ctrcbc_keys *ctx, void *ctr, void *data, size_t len)` - * - * Perform CTR encryption or decryption of the provided data. The - * data is processed "in place" (the output data replaces the input - * data). A full block-sized counter is applied (i.e. for 128-bit - * blocks, the counter is incremented as a 128-bit value). The 'ctr' - * array contains the initial value for the counter (used in the - * first block), and it is updated with the new value after data - * processing. - * - * The data length MUST be a multiple of the block size. - * - * - `br_xxx_ctrcbc_mac(const br_xxx_ctrcbc_keys *ctx, void *cbcmac, const void *data, size_t len)` - * - * Compute CBC-MAC over the provided data. The IV for CBC-MAC is - * provided as 'cbcmac'; the output is written over the same array. - * The data itself is untouched. The data length MUST be a multiple - * of the block size. - * - * - * It shall be noted that the key expansion functions return `void`. If - * the provided key length is not allowed, then there will be no error - * reporting; implementations need not validate the key length, thus an - * invalid key length may result in undefined behaviour (e.g. buffer - * overflow). - * - * Subkey structures contain no interior pointer, and no external - * resources are allocated upon key expansion. They can thus be - * discarded without any explicit deallocation. - * - * - * ## Object-Oriented API - * - * Each context structure begins with a field (called `vtable`) that - * points to an instance of a structure that references the relevant - * functions through pointers. Each such structure contains the - * following: - * - * - `context_size` - * - * The size (in bytes) of the context structure for subkeys. - * - * - `block_size` - * - * The cipher block size (in bytes). - * - * - `log_block_size` - * - * The base-2 logarithm of cipher block size (e.g. 4 for blocks - * of 16 bytes). - * - * - `init` - * - * Pointer to the key expansion function. - * - * - `run` - * - * Pointer to the encryption/decryption function. - * - * For combined CTR/CBC-MAC encryption, the `vtable` has a slightly - * different structure: - * - * - `context_size` - * - * The size (in bytes) of the context structure for subkeys. - * - * - `block_size` - * - * The cipher block size (in bytes). - * - * - `log_block_size` - * - * The base-2 logarithm of cipher block size (e.g. 4 for blocks - * of 16 bytes). - * - * - `init` - * - * Pointer to the key expansion function. - * - * - `encrypt` - * - * Pointer to the CTR encryption + CBC-MAC function. - * - * - `decrypt` - * - * Pointer to the CTR decryption + CBC-MAC function. - * - * - `ctr` - * - * Pointer to the CTR encryption/decryption function. - * - * - `mac` - * - * Pointer to the CBC-MAC function. - * - * For block cipher "`xxx`", static, constant instances of these - * structures are defined, under the names: - * - * - `br_xxx_cbcenc_vtable` - * - `br_xxx_cbcdec_vtable` - * - `br_xxx_ctr_vtable` - * - `br_xxx_ctrcbc_vtable` - * - * - * ## Implemented Block Ciphers - * - * Provided implementations are: - * - * | Name | Function | Block Size (bytes) | Key lengths (bytes) | - * | :-------- | :------- | :----------------: | :-----------------: | - * | aes_big | AES | 16 | 16, 24 and 32 | - * | aes_small | AES | 16 | 16, 24 and 32 | - * | aes_ct | AES | 16 | 16, 24 and 32 | - * | aes_ct64 | AES | 16 | 16, 24 and 32 | - * | aes_x86ni | AES | 16 | 16, 24 and 32 | - * | aes_pwr8 | AES | 16 | 16, 24 and 32 | - * | des_ct | DES/3DES | 8 | 8, 16 and 24 | - * | des_tab | DES/3DES | 8 | 8, 16 and 24 | - * - * **Note:** DES/3DES nominally uses keys of 64, 128 and 192 bits (i.e. 8, - * 16 and 24 bytes), but some of the bits are ignored by the algorithm, so - * the _effective_ key lengths, from a security point of view, are 56, - * 112 and 168 bits, respectively. - * - * `aes_big` is a "classical" AES implementation, using tables. It - * is fast but not constant-time, since it makes data-dependent array - * accesses. - * - * `aes_small` is an AES implementation optimized for code size. It - * is substantially slower than `aes_big`; it is not constant-time - * either. - * - * `aes_ct` is a constant-time implementation of AES; its code is about - * as big as that of `aes_big`, while its performance is comparable to - * that of `aes_small`. However, it is constant-time. This - * implementation should thus be considered to be the "default" AES in - * BearSSL, to be used unless the operational context guarantees that a - * non-constant-time implementation is safe, or an architecture-specific - * constant-time implementation can be used (e.g. using dedicated - * hardware opcodes). - * - * `aes_ct64` is another constant-time implementation of AES. It is - * similar to `aes_ct` but uses 64-bit values. On 32-bit machines, - * `aes_ct64` is not faster than `aes_ct`, often a bit slower, and has - * a larger footprint; however, on 64-bit architectures, `aes_ct64` - * is typically twice faster than `aes_ct` for modes that allow parallel - * operations (i.e. CTR, and CBC decryption, but not CBC encryption). - * - * `aes_x86ni` exists only on x86 architectures (32-bit and 64-bit). It - * uses the AES-NI opcodes when available. - * - * `aes_pwr8` exists only on PowerPC / POWER architectures (32-bit and - * 64-bit, both little-endian and big-endian). It uses the AES opcodes - * present in POWER8 and later. - * - * `des_tab` is a classic, table-based implementation of DES/3DES. It - * is not constant-time. - * - * `des_ct` is an constant-time implementation of DES/3DES. It is - * substantially slower than `des_tab`. - * - * ## ChaCha20 and Poly1305 - * - * ChaCha20 is a stream cipher. Poly1305 is a MAC algorithm. They - * are described in [RFC 7539](https://tools.ietf.org/html/rfc7539). - * - * Two function pointer types are defined: - * - * - `br_chacha20_run` describes a function that implements ChaCha20 - * only. - * - * - `br_poly1305_run` describes an implementation of Poly1305, - * in the AEAD combination with ChaCha20 specified in RFC 7539 - * (the ChaCha20 implementation is provided as a function pointer). - * - * `chacha20_ct` is a straightforward implementation of ChaCha20 in - * plain C; it is constant-time, small, and reasonably fast. - * - * `chacha20_sse2` leverages SSE2 opcodes (on x86 architectures that - * support these opcodes). It is faster than `chacha20_ct`. - * - * `poly1305_ctmul` is an implementation of the ChaCha20+Poly1305 AEAD - * construction, where the Poly1305 part is performed with mixed 32-bit - * multiplications (operands are 32-bit, result is 64-bit). - * - * `poly1305_ctmul32` implements ChaCha20+Poly1305 using pure 32-bit - * multiplications (32-bit operands, 32-bit result). It is slower than - * `poly1305_ctmul`, except on some specific architectures such as - * the ARM Cortex M0+. - * - * `poly1305_ctmulq` implements ChaCha20+Poly1305 with mixed 64-bit - * multiplications (operands are 64-bit, result is 128-bit) on 64-bit - * platforms that support such operations. - * - * `poly1305_i15` implements ChaCha20+Poly1305 with the generic "i15" - * big integer implementation. It is meant mostly for testing purposes, - * although it can help with saving a few hundred bytes of code footprint - * on systems where code size is scarce. - */ - -/** - * \brief Class type for CBC encryption implementations. - * - * A `br_block_cbcenc_class` instance points to the functions implementing - * a specific block cipher, when used in CBC mode for encrypting data. - */ -typedef struct br_block_cbcenc_class_ br_block_cbcenc_class; -struct br_block_cbcenc_class_ { - /** - * \brief Size (in bytes) of the context structure appropriate - * for containing subkeys. - */ - size_t context_size; - - /** - * \brief Size of individual blocks (in bytes). - */ - unsigned block_size; - - /** - * \brief Base-2 logarithm of the size of individual blocks, - * expressed in bytes. - */ - unsigned log_block_size; - - /** - * \brief Initialisation function. - * - * This function sets the `vtable` field in the context structure. - * The key length MUST be one of the key lengths supported by - * the implementation. - * - * \param ctx context structure to initialise. - * \param key secret key. - * \param key_len key length (in bytes). - */ - void (*init)(const br_block_cbcenc_class **ctx, - const void *key, size_t key_len); - - /** - * \brief Run the CBC encryption. - * - * The `iv` parameter points to the IV for this run; it is - * updated with a copy of the last encrypted block. The data - * is encrypted "in place"; its length (`len`) MUST be a - * multiple of the block size. - * - * \param ctx context structure (already initialised). - * \param iv IV for CBC encryption (updated). - * \param data data to encrypt. - * \param len data length (in bytes, multiple of block size). - */ - void (*run)(const br_block_cbcenc_class *const *ctx, - void *iv, void *data, size_t len); -}; - -/** - * \brief Class type for CBC decryption implementations. - * - * A `br_block_cbcdec_class` instance points to the functions implementing - * a specific block cipher, when used in CBC mode for decrypting data. - */ -typedef struct br_block_cbcdec_class_ br_block_cbcdec_class; -struct br_block_cbcdec_class_ { - /** - * \brief Size (in bytes) of the context structure appropriate - * for containing subkeys. - */ - size_t context_size; - - /** - * \brief Size of individual blocks (in bytes). - */ - unsigned block_size; - - /** - * \brief Base-2 logarithm of the size of individual blocks, - * expressed in bytes. - */ - unsigned log_block_size; - - /** - * \brief Initialisation function. - * - * This function sets the `vtable` field in the context structure. - * The key length MUST be one of the key lengths supported by - * the implementation. - * - * \param ctx context structure to initialise. - * \param key secret key. - * \param key_len key length (in bytes). - */ - void (*init)(const br_block_cbcdec_class **ctx, - const void *key, size_t key_len); - - /** - * \brief Run the CBC decryption. - * - * The `iv` parameter points to the IV for this run; it is - * updated with a copy of the last encrypted block. The data - * is decrypted "in place"; its length (`len`) MUST be a - * multiple of the block size. - * - * \param ctx context structure (already initialised). - * \param iv IV for CBC decryption (updated). - * \param data data to decrypt. - * \param len data length (in bytes, multiple of block size). - */ - void (*run)(const br_block_cbcdec_class *const *ctx, - void *iv, void *data, size_t len); -}; - -/** - * \brief Class type for CTR encryption/decryption implementations. - * - * A `br_block_ctr_class` instance points to the functions implementing - * a specific block cipher, when used in CTR mode for encrypting or - * decrypting data. - */ -typedef struct br_block_ctr_class_ br_block_ctr_class; -struct br_block_ctr_class_ { - /** - * \brief Size (in bytes) of the context structure appropriate - * for containing subkeys. - */ - size_t context_size; - - /** - * \brief Size of individual blocks (in bytes). - */ - unsigned block_size; - - /** - * \brief Base-2 logarithm of the size of individual blocks, - * expressed in bytes. - */ - unsigned log_block_size; - - /** - * \brief Initialisation function. - * - * This function sets the `vtable` field in the context structure. - * The key length MUST be one of the key lengths supported by - * the implementation. - * - * \param ctx context structure to initialise. - * \param key secret key. - * \param key_len key length (in bytes). - */ - void (*init)(const br_block_ctr_class **ctx, - const void *key, size_t key_len); - - /** - * \brief Run the CTR encryption or decryption. - * - * The `iv` parameter points to the IV for this run; its - * length is exactly 4 bytes less than the block size (e.g. - * 12 bytes for AES/CTR). The IV is combined with a 32-bit - * block counter to produce the block value which is processed - * with the block cipher. - * - * The data to encrypt or decrypt is updated "in place". Its - * length (`len` bytes) is not required to be a multiple of - * the block size; if the final block is partial, then the - * corresponding key stream bits are dropped. - * - * The resulting counter value is returned. - * - * \param ctx context structure (already initialised). - * \param iv IV for CTR encryption/decryption. - * \param cc initial value for the block counter. - * \param data data to encrypt or decrypt. - * \param len data length (in bytes). - * \return the new block counter value. - */ - uint32_t (*run)(const br_block_ctr_class *const *ctx, - const void *iv, uint32_t cc, void *data, size_t len); -}; - -/** - * \brief Class type for combined CTR and CBC-MAC implementations. - * - * A `br_block_ctrcbc_class` instance points to the functions implementing - * a specific block cipher, when used in CTR mode for encrypting or - * decrypting data, along with CBC-MAC. - */ -typedef struct br_block_ctrcbc_class_ br_block_ctrcbc_class; -struct br_block_ctrcbc_class_ { - /** - * \brief Size (in bytes) of the context structure appropriate - * for containing subkeys. - */ - size_t context_size; - - /** - * \brief Size of individual blocks (in bytes). - */ - unsigned block_size; - - /** - * \brief Base-2 logarithm of the size of individual blocks, - * expressed in bytes. - */ - unsigned log_block_size; - - /** - * \brief Initialisation function. - * - * This function sets the `vtable` field in the context structure. - * The key length MUST be one of the key lengths supported by - * the implementation. - * - * \param ctx context structure to initialise. - * \param key secret key. - * \param key_len key length (in bytes). - */ - void (*init)(const br_block_ctrcbc_class **ctx, - const void *key, size_t key_len); - - /** - * \brief Run the CTR encryption + CBC-MAC. - * - * The `ctr` parameter points to the counter; its length shall - * be equal to the block size. It is updated by this function - * as encryption proceeds. - * - * The `cbcmac` parameter points to the IV for CBC-MAC. The MAC - * is computed over the encrypted data (output of CTR - * encryption). Its length shall be equal to the block size. The - * computed CBC-MAC value is written over the `cbcmac` array. - * - * The data to encrypt is updated "in place". Its length (`len` - * bytes) MUST be a multiple of the block size. - * - * \param ctx context structure (already initialised). - * \param ctr counter for CTR encryption (initial and final). - * \param cbcmac IV and output buffer for CBC-MAC. - * \param data data to encrypt. - * \param len data length (in bytes). - */ - void (*encrypt)(const br_block_ctrcbc_class *const *ctx, - void *ctr, void *cbcmac, void *data, size_t len); - - /** - * \brief Run the CTR decryption + CBC-MAC. - * - * The `ctr` parameter points to the counter; its length shall - * be equal to the block size. It is updated by this function - * as decryption proceeds. - * - * The `cbcmac` parameter points to the IV for CBC-MAC. The MAC - * is computed over the encrypted data (i.e. before CTR - * decryption). Its length shall be equal to the block size. The - * computed CBC-MAC value is written over the `cbcmac` array. - * - * The data to decrypt is updated "in place". Its length (`len` - * bytes) MUST be a multiple of the block size. - * - * \param ctx context structure (already initialised). - * \param ctr counter for CTR encryption (initial and final). - * \param cbcmac IV and output buffer for CBC-MAC. - * \param data data to decrypt. - * \param len data length (in bytes). - */ - void (*decrypt)(const br_block_ctrcbc_class *const *ctx, - void *ctr, void *cbcmac, void *data, size_t len); - - /** - * \brief Run the CTR encryption/decryption only. - * - * The `ctr` parameter points to the counter; its length shall - * be equal to the block size. It is updated by this function - * as decryption proceeds. - * - * The data to decrypt is updated "in place". Its length (`len` - * bytes) MUST be a multiple of the block size. - * - * \param ctx context structure (already initialised). - * \param ctr counter for CTR encryption (initial and final). - * \param data data to decrypt. - * \param len data length (in bytes). - */ - void (*ctr)(const br_block_ctrcbc_class *const *ctx, - void *ctr, void *data, size_t len); - - /** - * \brief Run the CBC-MAC only. - * - * The `cbcmac` parameter points to the IV for CBC-MAC. The MAC - * is computed over the encrypted data (i.e. before CTR - * decryption). Its length shall be equal to the block size. The - * computed CBC-MAC value is written over the `cbcmac` array. - * - * The data is unmodified. Its length (`len` bytes) MUST be a - * multiple of the block size. - * - * \param ctx context structure (already initialised). - * \param cbcmac IV and output buffer for CBC-MAC. - * \param data data to decrypt. - * \param len data length (in bytes). - */ - void (*mac)(const br_block_ctrcbc_class *const *ctx, - void *cbcmac, const void *data, size_t len); -}; - -/* - * Traditional, table-based AES implementation. It is fast, but uses - * internal tables (in particular a 1 kB table for encryption, another - * 1 kB table for decryption, and a 256-byte table for key schedule), - * and it is not constant-time. In contexts where cache-timing attacks - * apply, this implementation may leak the secret key. - */ - -/** \brief AES block size (16 bytes). */ -#define br_aes_big_BLOCK_SIZE 16 - -/** - * \brief Context for AES subkeys (`aes_big` implementation, CBC encryption). - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** \brief Pointer to vtable for this context. */ - const br_block_cbcenc_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - uint32_t skey[60]; - unsigned num_rounds; -#endif -} br_aes_big_cbcenc_keys; - -/** - * \brief Context for AES subkeys (`aes_big` implementation, CBC decryption). - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** \brief Pointer to vtable for this context. */ - const br_block_cbcdec_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - uint32_t skey[60]; - unsigned num_rounds; -#endif -} br_aes_big_cbcdec_keys; - -/** - * \brief Context for AES subkeys (`aes_big` implementation, CTR encryption - * and decryption). - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** \brief Pointer to vtable for this context. */ - const br_block_ctr_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - uint32_t skey[60]; - unsigned num_rounds; -#endif -} br_aes_big_ctr_keys; - -/** - * \brief Context for AES subkeys (`aes_big` implementation, CTR encryption - * and decryption + CBC-MAC). - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** \brief Pointer to vtable for this context. */ - const br_block_ctrcbc_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - uint32_t skey[60]; - unsigned num_rounds; -#endif -} br_aes_big_ctrcbc_keys; - -/** - * \brief Class instance for AES CBC encryption (`aes_big` implementation). - */ -extern const br_block_cbcenc_class br_aes_big_cbcenc_vtable; - -/** - * \brief Class instance for AES CBC decryption (`aes_big` implementation). - */ -extern const br_block_cbcdec_class br_aes_big_cbcdec_vtable; - -/** - * \brief Class instance for AES CTR encryption and decryption - * (`aes_big` implementation). - */ -extern const br_block_ctr_class br_aes_big_ctr_vtable; - -/** - * \brief Class instance for AES CTR encryption/decryption + CBC-MAC - * (`aes_big` implementation). - */ -extern const br_block_ctrcbc_class br_aes_big_ctrcbc_vtable; - -/** - * \brief Context initialisation (key schedule) for AES CBC encryption - * (`aes_big` implementation). - * - * \param ctx context to initialise. - * \param key secret key. - * \param len secret key length (in bytes). - */ -void br_aes_big_cbcenc_init(br_aes_big_cbcenc_keys *ctx, - const void *key, size_t len); - -/** - * \brief Context initialisation (key schedule) for AES CBC decryption - * (`aes_big` implementation). - * - * \param ctx context to initialise. - * \param key secret key. - * \param len secret key length (in bytes). - */ -void br_aes_big_cbcdec_init(br_aes_big_cbcdec_keys *ctx, - const void *key, size_t len); - -/** - * \brief Context initialisation (key schedule) for AES CTR encryption - * and decryption (`aes_big` implementation). - * - * \param ctx context to initialise. - * \param key secret key. - * \param len secret key length (in bytes). - */ -void br_aes_big_ctr_init(br_aes_big_ctr_keys *ctx, - const void *key, size_t len); - -/** - * \brief Context initialisation (key schedule) for AES CTR + CBC-MAC - * (`aes_big` implementation). - * - * \param ctx context to initialise. - * \param key secret key. - * \param len secret key length (in bytes). - */ -void br_aes_big_ctrcbc_init(br_aes_big_ctrcbc_keys *ctx, - const void *key, size_t len); - -/** - * \brief CBC encryption with AES (`aes_big` implementation). - * - * \param ctx context (already initialised). - * \param iv IV (updated). - * \param data data to encrypt (updated). - * \param len data length (in bytes, MUST be multiple of 16). - */ -void br_aes_big_cbcenc_run(const br_aes_big_cbcenc_keys *ctx, void *iv, - void *data, size_t len); - -/** - * \brief CBC decryption with AES (`aes_big` implementation). - * - * \param ctx context (already initialised). - * \param iv IV (updated). - * \param data data to decrypt (updated). - * \param len data length (in bytes, MUST be multiple of 16). - */ -void br_aes_big_cbcdec_run(const br_aes_big_cbcdec_keys *ctx, void *iv, - void *data, size_t len); - -/** - * \brief CTR encryption and decryption with AES (`aes_big` implementation). - * - * \param ctx context (already initialised). - * \param iv IV (constant, 12 bytes). - * \param cc initial block counter value. - * \param data data to encrypt or decrypt (updated). - * \param len data length (in bytes). - * \return new block counter value. - */ -uint32_t br_aes_big_ctr_run(const br_aes_big_ctr_keys *ctx, - const void *iv, uint32_t cc, void *data, size_t len); - -/** - * \brief CTR encryption + CBC-MAC with AES (`aes_big` implementation). - * - * \param ctx context (already initialised). - * \param ctr counter for CTR (16 bytes, updated). - * \param cbcmac IV for CBC-MAC (updated). - * \param data data to encrypt (updated). - * \param len data length (in bytes, MUST be a multiple of 16). - */ -void br_aes_big_ctrcbc_encrypt(const br_aes_big_ctrcbc_keys *ctx, - void *ctr, void *cbcmac, void *data, size_t len); - -/** - * \brief CTR decryption + CBC-MAC with AES (`aes_big` implementation). - * - * \param ctx context (already initialised). - * \param ctr counter for CTR (16 bytes, updated). - * \param cbcmac IV for CBC-MAC (updated). - * \param data data to decrypt (updated). - * \param len data length (in bytes, MUST be a multiple of 16). - */ -void br_aes_big_ctrcbc_decrypt(const br_aes_big_ctrcbc_keys *ctx, - void *ctr, void *cbcmac, void *data, size_t len); - -/** - * \brief CTR encryption/decryption with AES (`aes_big` implementation). - * - * \param ctx context (already initialised). - * \param ctr counter for CTR (16 bytes, updated). - * \param data data to MAC (updated). - * \param len data length (in bytes, MUST be a multiple of 16). - */ -void br_aes_big_ctrcbc_ctr(const br_aes_big_ctrcbc_keys *ctx, - void *ctr, void *data, size_t len); - -/** - * \brief CBC-MAC with AES (`aes_big` implementation). - * - * \param ctx context (already initialised). - * \param cbcmac IV for CBC-MAC (updated). - * \param data data to MAC (unmodified). - * \param len data length (in bytes, MUST be a multiple of 16). - */ -void br_aes_big_ctrcbc_mac(const br_aes_big_ctrcbc_keys *ctx, - void *cbcmac, const void *data, size_t len); - -/* - * AES implementation optimized for size. It is slower than the - * traditional table-based AES implementation, but requires much less - * code. It still uses data-dependent table accesses (albeit within a - * much smaller 256-byte table), which makes it conceptually vulnerable - * to cache-timing attacks. - */ - -/** \brief AES block size (16 bytes). */ -#define br_aes_small_BLOCK_SIZE 16 - -/** - * \brief Context for AES subkeys (`aes_small` implementation, CBC encryption). - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** \brief Pointer to vtable for this context. */ - const br_block_cbcenc_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - uint32_t skey[60]; - unsigned num_rounds; -#endif -} br_aes_small_cbcenc_keys; - -/** - * \brief Context for AES subkeys (`aes_small` implementation, CBC decryption). - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** \brief Pointer to vtable for this context. */ - const br_block_cbcdec_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - uint32_t skey[60]; - unsigned num_rounds; -#endif -} br_aes_small_cbcdec_keys; - -/** - * \brief Context for AES subkeys (`aes_small` implementation, CTR encryption - * and decryption). - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** \brief Pointer to vtable for this context. */ - const br_block_ctr_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - uint32_t skey[60]; - unsigned num_rounds; -#endif -} br_aes_small_ctr_keys; - -/** - * \brief Context for AES subkeys (`aes_small` implementation, CTR encryption - * and decryption + CBC-MAC). - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** \brief Pointer to vtable for this context. */ - const br_block_ctrcbc_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - uint32_t skey[60]; - unsigned num_rounds; -#endif -} br_aes_small_ctrcbc_keys; - -/** - * \brief Class instance for AES CBC encryption (`aes_small` implementation). - */ -extern const br_block_cbcenc_class br_aes_small_cbcenc_vtable; - -/** - * \brief Class instance for AES CBC decryption (`aes_small` implementation). - */ -extern const br_block_cbcdec_class br_aes_small_cbcdec_vtable; - -/** - * \brief Class instance for AES CTR encryption and decryption - * (`aes_small` implementation). - */ -extern const br_block_ctr_class br_aes_small_ctr_vtable; - -/** - * \brief Class instance for AES CTR encryption/decryption + CBC-MAC - * (`aes_small` implementation). - */ -extern const br_block_ctrcbc_class br_aes_small_ctrcbc_vtable; - -/** - * \brief Context initialisation (key schedule) for AES CBC encryption - * (`aes_small` implementation). - * - * \param ctx context to initialise. - * \param key secret key. - * \param len secret key length (in bytes). - */ -void br_aes_small_cbcenc_init(br_aes_small_cbcenc_keys *ctx, - const void *key, size_t len); - -/** - * \brief Context initialisation (key schedule) for AES CBC decryption - * (`aes_small` implementation). - * - * \param ctx context to initialise. - * \param key secret key. - * \param len secret key length (in bytes). - */ -void br_aes_small_cbcdec_init(br_aes_small_cbcdec_keys *ctx, - const void *key, size_t len); - -/** - * \brief Context initialisation (key schedule) for AES CTR encryption - * and decryption (`aes_small` implementation). - * - * \param ctx context to initialise. - * \param key secret key. - * \param len secret key length (in bytes). - */ -void br_aes_small_ctr_init(br_aes_small_ctr_keys *ctx, - const void *key, size_t len); - -/** - * \brief Context initialisation (key schedule) for AES CTR + CBC-MAC - * (`aes_small` implementation). - * - * \param ctx context to initialise. - * \param key secret key. - * \param len secret key length (in bytes). - */ -void br_aes_small_ctrcbc_init(br_aes_small_ctrcbc_keys *ctx, - const void *key, size_t len); - -/** - * \brief CBC encryption with AES (`aes_small` implementation). - * - * \param ctx context (already initialised). - * \param iv IV (updated). - * \param data data to encrypt (updated). - * \param len data length (in bytes, MUST be multiple of 16). - */ -void br_aes_small_cbcenc_run(const br_aes_small_cbcenc_keys *ctx, void *iv, - void *data, size_t len); - -/** - * \brief CBC decryption with AES (`aes_small` implementation). - * - * \param ctx context (already initialised). - * \param iv IV (updated). - * \param data data to decrypt (updated). - * \param len data length (in bytes, MUST be multiple of 16). - */ -void br_aes_small_cbcdec_run(const br_aes_small_cbcdec_keys *ctx, void *iv, - void *data, size_t len); - -/** - * \brief CTR encryption and decryption with AES (`aes_small` implementation). - * - * \param ctx context (already initialised). - * \param iv IV (constant, 12 bytes). - * \param cc initial block counter value. - * \param data data to decrypt (updated). - * \param len data length (in bytes). - * \return new block counter value. - */ -uint32_t br_aes_small_ctr_run(const br_aes_small_ctr_keys *ctx, - const void *iv, uint32_t cc, void *data, size_t len); - -/** - * \brief CTR encryption + CBC-MAC with AES (`aes_small` implementation). - * - * \param ctx context (already initialised). - * \param ctr counter for CTR (16 bytes, updated). - * \param cbcmac IV for CBC-MAC (updated). - * \param data data to encrypt (updated). - * \param len data length (in bytes, MUST be a multiple of 16). - */ -void br_aes_small_ctrcbc_encrypt(const br_aes_small_ctrcbc_keys *ctx, - void *ctr, void *cbcmac, void *data, size_t len); - -/** - * \brief CTR decryption + CBC-MAC with AES (`aes_small` implementation). - * - * \param ctx context (already initialised). - * \param ctr counter for CTR (16 bytes, updated). - * \param cbcmac IV for CBC-MAC (updated). - * \param data data to decrypt (updated). - * \param len data length (in bytes, MUST be a multiple of 16). - */ -void br_aes_small_ctrcbc_decrypt(const br_aes_small_ctrcbc_keys *ctx, - void *ctr, void *cbcmac, void *data, size_t len); - -/** - * \brief CTR encryption/decryption with AES (`aes_small` implementation). - * - * \param ctx context (already initialised). - * \param ctr counter for CTR (16 bytes, updated). - * \param data data to MAC (updated). - * \param len data length (in bytes, MUST be a multiple of 16). - */ -void br_aes_small_ctrcbc_ctr(const br_aes_small_ctrcbc_keys *ctx, - void *ctr, void *data, size_t len); - -/** - * \brief CBC-MAC with AES (`aes_small` implementation). - * - * \param ctx context (already initialised). - * \param cbcmac IV for CBC-MAC (updated). - * \param data data to MAC (unmodified). - * \param len data length (in bytes, MUST be a multiple of 16). - */ -void br_aes_small_ctrcbc_mac(const br_aes_small_ctrcbc_keys *ctx, - void *cbcmac, const void *data, size_t len); - -/* - * Constant-time AES implementation. Its size is similar to that of - * 'aes_big', and its performance is similar to that of 'aes_small' (faster - * decryption, slower encryption). However, it is constant-time, i.e. - * immune to cache-timing and similar attacks. - */ - -/** \brief AES block size (16 bytes). */ -#define br_aes_ct_BLOCK_SIZE 16 - -/** - * \brief Context for AES subkeys (`aes_ct` implementation, CBC encryption). - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** \brief Pointer to vtable for this context. */ - const br_block_cbcenc_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - uint32_t skey[60]; - unsigned num_rounds; -#endif -} br_aes_ct_cbcenc_keys; - -/** - * \brief Context for AES subkeys (`aes_ct` implementation, CBC decryption). - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** \brief Pointer to vtable for this context. */ - const br_block_cbcdec_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - uint32_t skey[60]; - unsigned num_rounds; -#endif -} br_aes_ct_cbcdec_keys; - -/** - * \brief Context for AES subkeys (`aes_ct` implementation, CTR encryption - * and decryption). - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** \brief Pointer to vtable for this context. */ - const br_block_ctr_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - uint32_t skey[60]; - unsigned num_rounds; -#endif -} br_aes_ct_ctr_keys; - -/** - * \brief Context for AES subkeys (`aes_ct` implementation, CTR encryption - * and decryption + CBC-MAC). - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** \brief Pointer to vtable for this context. */ - const br_block_ctrcbc_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - uint32_t skey[60]; - unsigned num_rounds; -#endif -} br_aes_ct_ctrcbc_keys; - -/** - * \brief Class instance for AES CBC encryption (`aes_ct` implementation). - */ -extern const br_block_cbcenc_class br_aes_ct_cbcenc_vtable; - -/** - * \brief Class instance for AES CBC decryption (`aes_ct` implementation). - */ -extern const br_block_cbcdec_class br_aes_ct_cbcdec_vtable; - -/** - * \brief Class instance for AES CTR encryption and decryption - * (`aes_ct` implementation). - */ -extern const br_block_ctr_class br_aes_ct_ctr_vtable; - -/** - * \brief Class instance for AES CTR encryption/decryption + CBC-MAC - * (`aes_ct` implementation). - */ -extern const br_block_ctrcbc_class br_aes_ct_ctrcbc_vtable; - -/** - * \brief Context initialisation (key schedule) for AES CBC encryption - * (`aes_ct` implementation). - * - * \param ctx context to initialise. - * \param key secret key. - * \param len secret key length (in bytes). - */ -void br_aes_ct_cbcenc_init(br_aes_ct_cbcenc_keys *ctx, - const void *key, size_t len); - -/** - * \brief Context initialisation (key schedule) for AES CBC decryption - * (`aes_ct` implementation). - * - * \param ctx context to initialise. - * \param key secret key. - * \param len secret key length (in bytes). - */ -void br_aes_ct_cbcdec_init(br_aes_ct_cbcdec_keys *ctx, - const void *key, size_t len); - -/** - * \brief Context initialisation (key schedule) for AES CTR encryption - * and decryption (`aes_ct` implementation). - * - * \param ctx context to initialise. - * \param key secret key. - * \param len secret key length (in bytes). - */ -void br_aes_ct_ctr_init(br_aes_ct_ctr_keys *ctx, - const void *key, size_t len); - -/** - * \brief Context initialisation (key schedule) for AES CTR + CBC-MAC - * (`aes_ct` implementation). - * - * \param ctx context to initialise. - * \param key secret key. - * \param len secret key length (in bytes). - */ -void br_aes_ct_ctrcbc_init(br_aes_ct_ctrcbc_keys *ctx, - const void *key, size_t len); - -/** - * \brief CBC encryption with AES (`aes_ct` implementation). - * - * \param ctx context (already initialised). - * \param iv IV (updated). - * \param data data to encrypt (updated). - * \param len data length (in bytes, MUST be multiple of 16). - */ -void br_aes_ct_cbcenc_run(const br_aes_ct_cbcenc_keys *ctx, void *iv, - void *data, size_t len); - -/** - * \brief CBC decryption with AES (`aes_ct` implementation). - * - * \param ctx context (already initialised). - * \param iv IV (updated). - * \param data data to decrypt (updated). - * \param len data length (in bytes, MUST be multiple of 16). - */ -void br_aes_ct_cbcdec_run(const br_aes_ct_cbcdec_keys *ctx, void *iv, - void *data, size_t len); - -/** - * \brief CTR encryption and decryption with AES (`aes_ct` implementation). - * - * \param ctx context (already initialised). - * \param iv IV (constant, 12 bytes). - * \param cc initial block counter value. - * \param data data to decrypt (updated). - * \param len data length (in bytes). - * \return new block counter value. - */ -uint32_t br_aes_ct_ctr_run(const br_aes_ct_ctr_keys *ctx, - const void *iv, uint32_t cc, void *data, size_t len); - -/** - * \brief CTR encryption + CBC-MAC with AES (`aes_ct` implementation). - * - * \param ctx context (already initialised). - * \param ctr counter for CTR (16 bytes, updated). - * \param cbcmac IV for CBC-MAC (updated). - * \param data data to encrypt (updated). - * \param len data length (in bytes, MUST be a multiple of 16). - */ -void br_aes_ct_ctrcbc_encrypt(const br_aes_ct_ctrcbc_keys *ctx, - void *ctr, void *cbcmac, void *data, size_t len); - -/** - * \brief CTR decryption + CBC-MAC with AES (`aes_ct` implementation). - * - * \param ctx context (already initialised). - * \param ctr counter for CTR (16 bytes, updated). - * \param cbcmac IV for CBC-MAC (updated). - * \param data data to decrypt (updated). - * \param len data length (in bytes, MUST be a multiple of 16). - */ -void br_aes_ct_ctrcbc_decrypt(const br_aes_ct_ctrcbc_keys *ctx, - void *ctr, void *cbcmac, void *data, size_t len); - -/** - * \brief CTR encryption/decryption with AES (`aes_ct` implementation). - * - * \param ctx context (already initialised). - * \param ctr counter for CTR (16 bytes, updated). - * \param data data to MAC (updated). - * \param len data length (in bytes, MUST be a multiple of 16). - */ -void br_aes_ct_ctrcbc_ctr(const br_aes_ct_ctrcbc_keys *ctx, - void *ctr, void *data, size_t len); - -/** - * \brief CBC-MAC with AES (`aes_ct` implementation). - * - * \param ctx context (already initialised). - * \param cbcmac IV for CBC-MAC (updated). - * \param data data to MAC (unmodified). - * \param len data length (in bytes, MUST be a multiple of 16). - */ -void br_aes_ct_ctrcbc_mac(const br_aes_ct_ctrcbc_keys *ctx, - void *cbcmac, const void *data, size_t len); - -/* - * 64-bit constant-time AES implementation. It is similar to 'aes_ct' - * but uses 64-bit registers, making it about twice faster than 'aes_ct' - * on 64-bit platforms, while remaining constant-time and with a similar - * code size. (The doubling in performance is only for CBC decryption - * and CTR mode; CBC encryption is non-parallel and cannot benefit from - * the larger registers.) - */ - -/** \brief AES block size (16 bytes). */ -#define br_aes_ct64_BLOCK_SIZE 16 - -/** - * \brief Context for AES subkeys (`aes_ct64` implementation, CBC encryption). - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** \brief Pointer to vtable for this context. */ - const br_block_cbcenc_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - uint64_t skey[30]; - unsigned num_rounds; -#endif -} br_aes_ct64_cbcenc_keys; - -/** - * \brief Context for AES subkeys (`aes_ct64` implementation, CBC decryption). - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** \brief Pointer to vtable for this context. */ - const br_block_cbcdec_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - uint64_t skey[30]; - unsigned num_rounds; -#endif -} br_aes_ct64_cbcdec_keys; - -/** - * \brief Context for AES subkeys (`aes_ct64` implementation, CTR encryption - * and decryption). - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** \brief Pointer to vtable for this context. */ - const br_block_ctr_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - uint64_t skey[30]; - unsigned num_rounds; -#endif -} br_aes_ct64_ctr_keys; - -/** - * \brief Context for AES subkeys (`aes_ct64` implementation, CTR encryption - * and decryption + CBC-MAC). - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** \brief Pointer to vtable for this context. */ - const br_block_ctrcbc_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - uint64_t skey[30]; - unsigned num_rounds; -#endif -} br_aes_ct64_ctrcbc_keys; - -/** - * \brief Class instance for AES CBC encryption (`aes_ct64` implementation). - */ -extern const br_block_cbcenc_class br_aes_ct64_cbcenc_vtable; - -/** - * \brief Class instance for AES CBC decryption (`aes_ct64` implementation). - */ -extern const br_block_cbcdec_class br_aes_ct64_cbcdec_vtable; - -/** - * \brief Class instance for AES CTR encryption and decryption - * (`aes_ct64` implementation). - */ -extern const br_block_ctr_class br_aes_ct64_ctr_vtable; - -/** - * \brief Class instance for AES CTR encryption/decryption + CBC-MAC - * (`aes_ct64` implementation). - */ -extern const br_block_ctrcbc_class br_aes_ct64_ctrcbc_vtable; - -/** - * \brief Context initialisation (key schedule) for AES CBC encryption - * (`aes_ct64` implementation). - * - * \param ctx context to initialise. - * \param key secret key. - * \param len secret key length (in bytes). - */ -void br_aes_ct64_cbcenc_init(br_aes_ct64_cbcenc_keys *ctx, - const void *key, size_t len); - -/** - * \brief Context initialisation (key schedule) for AES CBC decryption - * (`aes_ct64` implementation). - * - * \param ctx context to initialise. - * \param key secret key. - * \param len secret key length (in bytes). - */ -void br_aes_ct64_cbcdec_init(br_aes_ct64_cbcdec_keys *ctx, - const void *key, size_t len); - -/** - * \brief Context initialisation (key schedule) for AES CTR encryption - * and decryption (`aes_ct64` implementation). - * - * \param ctx context to initialise. - * \param key secret key. - * \param len secret key length (in bytes). - */ -void br_aes_ct64_ctr_init(br_aes_ct64_ctr_keys *ctx, - const void *key, size_t len); - -/** - * \brief Context initialisation (key schedule) for AES CTR + CBC-MAC - * (`aes_ct64` implementation). - * - * \param ctx context to initialise. - * \param key secret key. - * \param len secret key length (in bytes). - */ -void br_aes_ct64_ctrcbc_init(br_aes_ct64_ctrcbc_keys *ctx, - const void *key, size_t len); - -/** - * \brief CBC encryption with AES (`aes_ct64` implementation). - * - * \param ctx context (already initialised). - * \param iv IV (updated). - * \param data data to encrypt (updated). - * \param len data length (in bytes, MUST be multiple of 16). - */ -void br_aes_ct64_cbcenc_run(const br_aes_ct64_cbcenc_keys *ctx, void *iv, - void *data, size_t len); - -/** - * \brief CBC decryption with AES (`aes_ct64` implementation). - * - * \param ctx context (already initialised). - * \param iv IV (updated). - * \param data data to decrypt (updated). - * \param len data length (in bytes, MUST be multiple of 16). - */ -void br_aes_ct64_cbcdec_run(const br_aes_ct64_cbcdec_keys *ctx, void *iv, - void *data, size_t len); - -/** - * \brief CTR encryption and decryption with AES (`aes_ct64` implementation). - * - * \param ctx context (already initialised). - * \param iv IV (constant, 12 bytes). - * \param cc initial block counter value. - * \param data data to decrypt (updated). - * \param len data length (in bytes). - * \return new block counter value. - */ -uint32_t br_aes_ct64_ctr_run(const br_aes_ct64_ctr_keys *ctx, - const void *iv, uint32_t cc, void *data, size_t len); - -/** - * \brief CTR encryption + CBC-MAC with AES (`aes_ct64` implementation). - * - * \param ctx context (already initialised). - * \param ctr counter for CTR (16 bytes, updated). - * \param cbcmac IV for CBC-MAC (updated). - * \param data data to encrypt (updated). - * \param len data length (in bytes, MUST be a multiple of 16). - */ -void br_aes_ct64_ctrcbc_encrypt(const br_aes_ct64_ctrcbc_keys *ctx, - void *ctr, void *cbcmac, void *data, size_t len); - -/** - * \brief CTR decryption + CBC-MAC with AES (`aes_ct64` implementation). - * - * \param ctx context (already initialised). - * \param ctr counter for CTR (16 bytes, updated). - * \param cbcmac IV for CBC-MAC (updated). - * \param data data to decrypt (updated). - * \param len data length (in bytes, MUST be a multiple of 16). - */ -void br_aes_ct64_ctrcbc_decrypt(const br_aes_ct64_ctrcbc_keys *ctx, - void *ctr, void *cbcmac, void *data, size_t len); - -/** - * \brief CTR encryption/decryption with AES (`aes_ct64` implementation). - * - * \param ctx context (already initialised). - * \param ctr counter for CTR (16 bytes, updated). - * \param data data to MAC (updated). - * \param len data length (in bytes, MUST be a multiple of 16). - */ -void br_aes_ct64_ctrcbc_ctr(const br_aes_ct64_ctrcbc_keys *ctx, - void *ctr, void *data, size_t len); - -/** - * \brief CBC-MAC with AES (`aes_ct64` implementation). - * - * \param ctx context (already initialised). - * \param cbcmac IV for CBC-MAC (updated). - * \param data data to MAC (unmodified). - * \param len data length (in bytes, MUST be a multiple of 16). - */ -void br_aes_ct64_ctrcbc_mac(const br_aes_ct64_ctrcbc_keys *ctx, - void *cbcmac, const void *data, size_t len); - -/* - * AES implementation using AES-NI opcodes (x86 platform). - */ - -/** \brief AES block size (16 bytes). */ -#define br_aes_x86ni_BLOCK_SIZE 16 - -/** - * \brief Context for AES subkeys (`aes_x86ni` implementation, CBC encryption). - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** \brief Pointer to vtable for this context. */ - const br_block_cbcenc_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - union { - unsigned char skni[16 * 15]; - } skey; - unsigned num_rounds; -#endif -} br_aes_x86ni_cbcenc_keys; - -/** - * \brief Context for AES subkeys (`aes_x86ni` implementation, CBC decryption). - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** \brief Pointer to vtable for this context. */ - const br_block_cbcdec_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - union { - unsigned char skni[16 * 15]; - } skey; - unsigned num_rounds; -#endif -} br_aes_x86ni_cbcdec_keys; - -/** - * \brief Context for AES subkeys (`aes_x86ni` implementation, CTR encryption - * and decryption). - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** \brief Pointer to vtable for this context. */ - const br_block_ctr_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - union { - unsigned char skni[16 * 15]; - } skey; - unsigned num_rounds; -#endif -} br_aes_x86ni_ctr_keys; - -/** - * \brief Context for AES subkeys (`aes_x86ni` implementation, CTR encryption - * and decryption + CBC-MAC). - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** \brief Pointer to vtable for this context. */ - const br_block_ctrcbc_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - union { - unsigned char skni[16 * 15]; - } skey; - unsigned num_rounds; -#endif -} br_aes_x86ni_ctrcbc_keys; - -/** - * \brief Class instance for AES CBC encryption (`aes_x86ni` implementation). - * - * Since this implementation might be omitted from the library, or the - * AES opcode unavailable on the current CPU, a pointer to this class - * instance should be obtained through `br_aes_x86ni_cbcenc_get_vtable()`. - */ -extern const br_block_cbcenc_class br_aes_x86ni_cbcenc_vtable; - -/** - * \brief Class instance for AES CBC decryption (`aes_x86ni` implementation). - * - * Since this implementation might be omitted from the library, or the - * AES opcode unavailable on the current CPU, a pointer to this class - * instance should be obtained through `br_aes_x86ni_cbcdec_get_vtable()`. - */ -extern const br_block_cbcdec_class br_aes_x86ni_cbcdec_vtable; - -/** - * \brief Class instance for AES CTR encryption and decryption - * (`aes_x86ni` implementation). - * - * Since this implementation might be omitted from the library, or the - * AES opcode unavailable on the current CPU, a pointer to this class - * instance should be obtained through `br_aes_x86ni_ctr_get_vtable()`. - */ -extern const br_block_ctr_class br_aes_x86ni_ctr_vtable; - -/** - * \brief Class instance for AES CTR encryption/decryption + CBC-MAC - * (`aes_x86ni` implementation). - * - * Since this implementation might be omitted from the library, or the - * AES opcode unavailable on the current CPU, a pointer to this class - * instance should be obtained through `br_aes_x86ni_ctrcbc_get_vtable()`. - */ -extern const br_block_ctrcbc_class br_aes_x86ni_ctrcbc_vtable; - -/** - * \brief Context initialisation (key schedule) for AES CBC encryption - * (`aes_x86ni` implementation). - * - * \param ctx context to initialise. - * \param key secret key. - * \param len secret key length (in bytes). - */ -void br_aes_x86ni_cbcenc_init(br_aes_x86ni_cbcenc_keys *ctx, - const void *key, size_t len); - -/** - * \brief Context initialisation (key schedule) for AES CBC decryption - * (`aes_x86ni` implementation). - * - * \param ctx context to initialise. - * \param key secret key. - * \param len secret key length (in bytes). - */ -void br_aes_x86ni_cbcdec_init(br_aes_x86ni_cbcdec_keys *ctx, - const void *key, size_t len); - -/** - * \brief Context initialisation (key schedule) for AES CTR encryption - * and decryption (`aes_x86ni` implementation). - * - * \param ctx context to initialise. - * \param key secret key. - * \param len secret key length (in bytes). - */ -void br_aes_x86ni_ctr_init(br_aes_x86ni_ctr_keys *ctx, - const void *key, size_t len); - -/** - * \brief Context initialisation (key schedule) for AES CTR + CBC-MAC - * (`aes_x86ni` implementation). - * - * \param ctx context to initialise. - * \param key secret key. - * \param len secret key length (in bytes). - */ -void br_aes_x86ni_ctrcbc_init(br_aes_x86ni_ctrcbc_keys *ctx, - const void *key, size_t len); - -/** - * \brief CBC encryption with AES (`aes_x86ni` implementation). - * - * \param ctx context (already initialised). - * \param iv IV (updated). - * \param data data to encrypt (updated). - * \param len data length (in bytes, MUST be multiple of 16). - */ -void br_aes_x86ni_cbcenc_run(const br_aes_x86ni_cbcenc_keys *ctx, void *iv, - void *data, size_t len); - -/** - * \brief CBC decryption with AES (`aes_x86ni` implementation). - * - * \param ctx context (already initialised). - * \param iv IV (updated). - * \param data data to decrypt (updated). - * \param len data length (in bytes, MUST be multiple of 16). - */ -void br_aes_x86ni_cbcdec_run(const br_aes_x86ni_cbcdec_keys *ctx, void *iv, - void *data, size_t len); - -/** - * \brief CTR encryption and decryption with AES (`aes_x86ni` implementation). - * - * \param ctx context (already initialised). - * \param iv IV (constant, 12 bytes). - * \param cc initial block counter value. - * \param data data to decrypt (updated). - * \param len data length (in bytes). - * \return new block counter value. - */ -uint32_t br_aes_x86ni_ctr_run(const br_aes_x86ni_ctr_keys *ctx, - const void *iv, uint32_t cc, void *data, size_t len); - -/** - * \brief CTR encryption + CBC-MAC with AES (`aes_x86ni` implementation). - * - * \param ctx context (already initialised). - * \param ctr counter for CTR (16 bytes, updated). - * \param cbcmac IV for CBC-MAC (updated). - * \param data data to encrypt (updated). - * \param len data length (in bytes, MUST be a multiple of 16). - */ -void br_aes_x86ni_ctrcbc_encrypt(const br_aes_x86ni_ctrcbc_keys *ctx, - void *ctr, void *cbcmac, void *data, size_t len); - -/** - * \brief CTR decryption + CBC-MAC with AES (`aes_x86ni` implementation). - * - * \param ctx context (already initialised). - * \param ctr counter for CTR (16 bytes, updated). - * \param cbcmac IV for CBC-MAC (updated). - * \param data data to decrypt (updated). - * \param len data length (in bytes, MUST be a multiple of 16). - */ -void br_aes_x86ni_ctrcbc_decrypt(const br_aes_x86ni_ctrcbc_keys *ctx, - void *ctr, void *cbcmac, void *data, size_t len); - -/** - * \brief CTR encryption/decryption with AES (`aes_x86ni` implementation). - * - * \param ctx context (already initialised). - * \param ctr counter for CTR (16 bytes, updated). - * \param data data to MAC (updated). - * \param len data length (in bytes, MUST be a multiple of 16). - */ -void br_aes_x86ni_ctrcbc_ctr(const br_aes_x86ni_ctrcbc_keys *ctx, - void *ctr, void *data, size_t len); - -/** - * \brief CBC-MAC with AES (`aes_x86ni` implementation). - * - * \param ctx context (already initialised). - * \param cbcmac IV for CBC-MAC (updated). - * \param data data to MAC (unmodified). - * \param len data length (in bytes, MUST be a multiple of 16). - */ -void br_aes_x86ni_ctrcbc_mac(const br_aes_x86ni_ctrcbc_keys *ctx, - void *cbcmac, const void *data, size_t len); - -/** - * \brief Obtain the `aes_x86ni` AES-CBC (encryption) implementation, if - * available. - * - * This function returns a pointer to `br_aes_x86ni_cbcenc_vtable`, if - * that implementation was compiled in the library _and_ the x86 AES - * opcodes are available on the currently running CPU. If either of - * these conditions is not met, then this function returns `NULL`. - * - * \return the `aes_x86ni` AES-CBC (encryption) implementation, or `NULL`. - */ -const br_block_cbcenc_class *br_aes_x86ni_cbcenc_get_vtable(void); - -/** - * \brief Obtain the `aes_x86ni` AES-CBC (decryption) implementation, if - * available. - * - * This function returns a pointer to `br_aes_x86ni_cbcdec_vtable`, if - * that implementation was compiled in the library _and_ the x86 AES - * opcodes are available on the currently running CPU. If either of - * these conditions is not met, then this function returns `NULL`. - * - * \return the `aes_x86ni` AES-CBC (decryption) implementation, or `NULL`. - */ -const br_block_cbcdec_class *br_aes_x86ni_cbcdec_get_vtable(void); - -/** - * \brief Obtain the `aes_x86ni` AES-CTR implementation, if available. - * - * This function returns a pointer to `br_aes_x86ni_ctr_vtable`, if - * that implementation was compiled in the library _and_ the x86 AES - * opcodes are available on the currently running CPU. If either of - * these conditions is not met, then this function returns `NULL`. - * - * \return the `aes_x86ni` AES-CTR implementation, or `NULL`. - */ -const br_block_ctr_class *br_aes_x86ni_ctr_get_vtable(void); - -/** - * \brief Obtain the `aes_x86ni` AES-CTR + CBC-MAC implementation, if - * available. - * - * This function returns a pointer to `br_aes_x86ni_ctrcbc_vtable`, if - * that implementation was compiled in the library _and_ the x86 AES - * opcodes are available on the currently running CPU. If either of - * these conditions is not met, then this function returns `NULL`. - * - * \return the `aes_x86ni` AES-CTR implementation, or `NULL`. - */ -const br_block_ctrcbc_class *br_aes_x86ni_ctrcbc_get_vtable(void); - -/* - * AES implementation using POWER8 opcodes. - */ - -/** \brief AES block size (16 bytes). */ -#define br_aes_pwr8_BLOCK_SIZE 16 - -/** - * \brief Context for AES subkeys (`aes_pwr8` implementation, CBC encryption). - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** \brief Pointer to vtable for this context. */ - const br_block_cbcenc_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - union { - unsigned char skni[16 * 15]; - } skey; - unsigned num_rounds; -#endif -} br_aes_pwr8_cbcenc_keys; - -/** - * \brief Context for AES subkeys (`aes_pwr8` implementation, CBC decryption). - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** \brief Pointer to vtable for this context. */ - const br_block_cbcdec_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - union { - unsigned char skni[16 * 15]; - } skey; - unsigned num_rounds; -#endif -} br_aes_pwr8_cbcdec_keys; - -/** - * \brief Context for AES subkeys (`aes_pwr8` implementation, CTR encryption - * and decryption). - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** \brief Pointer to vtable for this context. */ - const br_block_ctr_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - union { - unsigned char skni[16 * 15]; - } skey; - unsigned num_rounds; -#endif -} br_aes_pwr8_ctr_keys; - -/** - * \brief Context for AES subkeys (`aes_pwr8` implementation, CTR encryption - * and decryption + CBC-MAC). - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** \brief Pointer to vtable for this context. */ - const br_block_ctrcbc_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - union { - unsigned char skni[16 * 15]; - } skey; - unsigned num_rounds; -#endif -} br_aes_pwr8_ctrcbc_keys; - -/** - * \brief Class instance for AES CBC encryption (`aes_pwr8` implementation). - * - * Since this implementation might be omitted from the library, or the - * AES opcode unavailable on the current CPU, a pointer to this class - * instance should be obtained through `br_aes_pwr8_cbcenc_get_vtable()`. - */ -extern const br_block_cbcenc_class br_aes_pwr8_cbcenc_vtable; - -/** - * \brief Class instance for AES CBC decryption (`aes_pwr8` implementation). - * - * Since this implementation might be omitted from the library, or the - * AES opcode unavailable on the current CPU, a pointer to this class - * instance should be obtained through `br_aes_pwr8_cbcdec_get_vtable()`. - */ -extern const br_block_cbcdec_class br_aes_pwr8_cbcdec_vtable; - -/** - * \brief Class instance for AES CTR encryption and decryption - * (`aes_pwr8` implementation). - * - * Since this implementation might be omitted from the library, or the - * AES opcode unavailable on the current CPU, a pointer to this class - * instance should be obtained through `br_aes_pwr8_ctr_get_vtable()`. - */ -extern const br_block_ctr_class br_aes_pwr8_ctr_vtable; - -/** - * \brief Class instance for AES CTR encryption/decryption + CBC-MAC - * (`aes_pwr8` implementation). - * - * Since this implementation might be omitted from the library, or the - * AES opcode unavailable on the current CPU, a pointer to this class - * instance should be obtained through `br_aes_pwr8_ctrcbc_get_vtable()`. - */ -extern const br_block_ctrcbc_class br_aes_pwr8_ctrcbc_vtable; - -/** - * \brief Context initialisation (key schedule) for AES CBC encryption - * (`aes_pwr8` implementation). - * - * \param ctx context to initialise. - * \param key secret key. - * \param len secret key length (in bytes). - */ -void br_aes_pwr8_cbcenc_init(br_aes_pwr8_cbcenc_keys *ctx, - const void *key, size_t len); - -/** - * \brief Context initialisation (key schedule) for AES CBC decryption - * (`aes_pwr8` implementation). - * - * \param ctx context to initialise. - * \param key secret key. - * \param len secret key length (in bytes). - */ -void br_aes_pwr8_cbcdec_init(br_aes_pwr8_cbcdec_keys *ctx, - const void *key, size_t len); - -/** - * \brief Context initialisation (key schedule) for AES CTR encryption - * and decryption (`aes_pwr8` implementation). - * - * \param ctx context to initialise. - * \param key secret key. - * \param len secret key length (in bytes). - */ -void br_aes_pwr8_ctr_init(br_aes_pwr8_ctr_keys *ctx, - const void *key, size_t len); - -/** - * \brief Context initialisation (key schedule) for AES CTR + CBC-MAC - * (`aes_pwr8` implementation). - * - * \param ctx context to initialise. - * \param key secret key. - * \param len secret key length (in bytes). - */ -void br_aes_pwr8_ctrcbc_init(br_aes_pwr8_ctrcbc_keys *ctx, - const void *key, size_t len); - -/** - * \brief CBC encryption with AES (`aes_pwr8` implementation). - * - * \param ctx context (already initialised). - * \param iv IV (updated). - * \param data data to encrypt (updated). - * \param len data length (in bytes, MUST be multiple of 16). - */ -void br_aes_pwr8_cbcenc_run(const br_aes_pwr8_cbcenc_keys *ctx, void *iv, - void *data, size_t len); - -/** - * \brief CBC decryption with AES (`aes_pwr8` implementation). - * - * \param ctx context (already initialised). - * \param iv IV (updated). - * \param data data to decrypt (updated). - * \param len data length (in bytes, MUST be multiple of 16). - */ -void br_aes_pwr8_cbcdec_run(const br_aes_pwr8_cbcdec_keys *ctx, void *iv, - void *data, size_t len); - -/** - * \brief CTR encryption and decryption with AES (`aes_pwr8` implementation). - * - * \param ctx context (already initialised). - * \param iv IV (constant, 12 bytes). - * \param cc initial block counter value. - * \param data data to decrypt (updated). - * \param len data length (in bytes). - * \return new block counter value. - */ -uint32_t br_aes_pwr8_ctr_run(const br_aes_pwr8_ctr_keys *ctx, - const void *iv, uint32_t cc, void *data, size_t len); - -/** - * \brief CTR encryption + CBC-MAC with AES (`aes_pwr8` implementation). - * - * \param ctx context (already initialised). - * \param ctr counter for CTR (16 bytes, updated). - * \param cbcmac IV for CBC-MAC (updated). - * \param data data to encrypt (updated). - * \param len data length (in bytes, MUST be a multiple of 16). - */ -void br_aes_pwr8_ctrcbc_encrypt(const br_aes_pwr8_ctrcbc_keys *ctx, - void *ctr, void *cbcmac, void *data, size_t len); - -/** - * \brief CTR decryption + CBC-MAC with AES (`aes_pwr8` implementation). - * - * \param ctx context (already initialised). - * \param ctr counter for CTR (16 bytes, updated). - * \param cbcmac IV for CBC-MAC (updated). - * \param data data to decrypt (updated). - * \param len data length (in bytes, MUST be a multiple of 16). - */ -void br_aes_pwr8_ctrcbc_decrypt(const br_aes_pwr8_ctrcbc_keys *ctx, - void *ctr, void *cbcmac, void *data, size_t len); - -/** - * \brief CTR encryption/decryption with AES (`aes_pwr8` implementation). - * - * \param ctx context (already initialised). - * \param ctr counter for CTR (16 bytes, updated). - * \param data data to MAC (updated). - * \param len data length (in bytes, MUST be a multiple of 16). - */ -void br_aes_pwr8_ctrcbc_ctr(const br_aes_pwr8_ctrcbc_keys *ctx, - void *ctr, void *data, size_t len); - -/** - * \brief CBC-MAC with AES (`aes_pwr8` implementation). - * - * \param ctx context (already initialised). - * \param cbcmac IV for CBC-MAC (updated). - * \param data data to MAC (unmodified). - * \param len data length (in bytes, MUST be a multiple of 16). - */ -void br_aes_pwr8_ctrcbc_mac(const br_aes_pwr8_ctrcbc_keys *ctx, - void *cbcmac, const void *data, size_t len); - -/** - * \brief Obtain the `aes_pwr8` AES-CBC (encryption) implementation, if - * available. - * - * This function returns a pointer to `br_aes_pwr8_cbcenc_vtable`, if - * that implementation was compiled in the library _and_ the POWER8 - * crypto opcodes are available on the currently running CPU. If either - * of these conditions is not met, then this function returns `NULL`. - * - * \return the `aes_pwr8` AES-CBC (encryption) implementation, or `NULL`. - */ -const br_block_cbcenc_class *br_aes_pwr8_cbcenc_get_vtable(void); - -/** - * \brief Obtain the `aes_pwr8` AES-CBC (decryption) implementation, if - * available. - * - * This function returns a pointer to `br_aes_pwr8_cbcdec_vtable`, if - * that implementation was compiled in the library _and_ the POWER8 - * crypto opcodes are available on the currently running CPU. If either - * of these conditions is not met, then this function returns `NULL`. - * - * \return the `aes_pwr8` AES-CBC (decryption) implementation, or `NULL`. - */ -const br_block_cbcdec_class *br_aes_pwr8_cbcdec_get_vtable(void); - -/** - * \brief Obtain the `aes_pwr8` AES-CTR implementation, if available. - * - * This function returns a pointer to `br_aes_pwr8_ctr_vtable`, if that - * implementation was compiled in the library _and_ the POWER8 crypto - * opcodes are available on the currently running CPU. If either of - * these conditions is not met, then this function returns `NULL`. - * - * \return the `aes_pwr8` AES-CTR implementation, or `NULL`. - */ -const br_block_ctr_class *br_aes_pwr8_ctr_get_vtable(void); - -/** - * \brief Obtain the `aes_pwr8` AES-CTR + CBC-MAC implementation, if - * available. - * - * This function returns a pointer to `br_aes_pwr8_ctrcbc_vtable`, if - * that implementation was compiled in the library _and_ the POWER8 AES - * opcodes are available on the currently running CPU. If either of - * these conditions is not met, then this function returns `NULL`. - * - * \return the `aes_pwr8` AES-CTR implementation, or `NULL`. - */ -const br_block_ctrcbc_class *br_aes_pwr8_ctrcbc_get_vtable(void); - -/** - * \brief Aggregate structure large enough to be used as context for - * subkeys (CBC encryption) for all AES implementations. - */ -typedef union { - const br_block_cbcenc_class *vtable; - br_aes_big_cbcenc_keys c_big; - br_aes_small_cbcenc_keys c_small; - br_aes_ct_cbcenc_keys c_ct; - br_aes_ct64_cbcenc_keys c_ct64; - br_aes_x86ni_cbcenc_keys c_x86ni; - br_aes_pwr8_cbcenc_keys c_pwr8; -} br_aes_gen_cbcenc_keys; - -/** - * \brief Aggregate structure large enough to be used as context for - * subkeys (CBC decryption) for all AES implementations. - */ -typedef union { - const br_block_cbcdec_class *vtable; - br_aes_big_cbcdec_keys c_big; - br_aes_small_cbcdec_keys c_small; - br_aes_ct_cbcdec_keys c_ct; - br_aes_ct64_cbcdec_keys c_ct64; - br_aes_x86ni_cbcdec_keys c_x86ni; - br_aes_pwr8_cbcdec_keys c_pwr8; -} br_aes_gen_cbcdec_keys; - -/** - * \brief Aggregate structure large enough to be used as context for - * subkeys (CTR encryption and decryption) for all AES implementations. - */ -typedef union { - const br_block_ctr_class *vtable; - br_aes_big_ctr_keys c_big; - br_aes_small_ctr_keys c_small; - br_aes_ct_ctr_keys c_ct; - br_aes_ct64_ctr_keys c_ct64; - br_aes_x86ni_ctr_keys c_x86ni; - br_aes_pwr8_ctr_keys c_pwr8; -} br_aes_gen_ctr_keys; - -/** - * \brief Aggregate structure large enough to be used as context for - * subkeys (CTR encryption/decryption + CBC-MAC) for all AES implementations. - */ -typedef union { - const br_block_ctrcbc_class *vtable; - br_aes_big_ctrcbc_keys c_big; - br_aes_small_ctrcbc_keys c_small; - br_aes_ct_ctrcbc_keys c_ct; - br_aes_ct64_ctrcbc_keys c_ct64; - br_aes_x86ni_ctrcbc_keys c_x86ni; - br_aes_pwr8_ctrcbc_keys c_pwr8; -} br_aes_gen_ctrcbc_keys; - -/* - * Traditional, table-based implementation for DES/3DES. Since tables are - * used, cache-timing attacks are conceptually possible. - */ - -/** \brief DES/3DES block size (8 bytes). */ -#define br_des_tab_BLOCK_SIZE 8 - -/** - * \brief Context for DES subkeys (`des_tab` implementation, CBC encryption). - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** \brief Pointer to vtable for this context. */ - const br_block_cbcenc_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - uint32_t skey[96]; - unsigned num_rounds; -#endif -} br_des_tab_cbcenc_keys; - -/** - * \brief Context for DES subkeys (`des_tab` implementation, CBC decryption). - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** \brief Pointer to vtable for this context. */ - const br_block_cbcdec_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - uint32_t skey[96]; - unsigned num_rounds; -#endif -} br_des_tab_cbcdec_keys; - -/** - * \brief Class instance for DES CBC encryption (`des_tab` implementation). - */ -extern const br_block_cbcenc_class br_des_tab_cbcenc_vtable; - -/** - * \brief Class instance for DES CBC decryption (`des_tab` implementation). - */ -extern const br_block_cbcdec_class br_des_tab_cbcdec_vtable; - -/** - * \brief Context initialisation (key schedule) for DES CBC encryption - * (`des_tab` implementation). - * - * \param ctx context to initialise. - * \param key secret key. - * \param len secret key length (in bytes). - */ -void br_des_tab_cbcenc_init(br_des_tab_cbcenc_keys *ctx, - const void *key, size_t len); - -/** - * \brief Context initialisation (key schedule) for DES CBC decryption - * (`des_tab` implementation). - * - * \param ctx context to initialise. - * \param key secret key. - * \param len secret key length (in bytes). - */ -void br_des_tab_cbcdec_init(br_des_tab_cbcdec_keys *ctx, - const void *key, size_t len); - -/** - * \brief CBC encryption with DES (`des_tab` implementation). - * - * \param ctx context (already initialised). - * \param iv IV (updated). - * \param data data to encrypt (updated). - * \param len data length (in bytes, MUST be multiple of 8). - */ -void br_des_tab_cbcenc_run(const br_des_tab_cbcenc_keys *ctx, void *iv, - void *data, size_t len); - -/** - * \brief CBC decryption with DES (`des_tab` implementation). - * - * \param ctx context (already initialised). - * \param iv IV (updated). - * \param data data to decrypt (updated). - * \param len data length (in bytes, MUST be multiple of 8). - */ -void br_des_tab_cbcdec_run(const br_des_tab_cbcdec_keys *ctx, void *iv, - void *data, size_t len); - -/* - * Constant-time implementation for DES/3DES. It is substantially slower - * (by a factor of about 4x), but also immune to cache-timing attacks. - */ - -/** \brief DES/3DES block size (8 bytes). */ -#define br_des_ct_BLOCK_SIZE 8 - -/** - * \brief Context for DES subkeys (`des_ct` implementation, CBC encryption). - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** \brief Pointer to vtable for this context. */ - const br_block_cbcenc_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - uint32_t skey[96]; - unsigned num_rounds; -#endif -} br_des_ct_cbcenc_keys; - -/** - * \brief Context for DES subkeys (`des_ct` implementation, CBC decryption). - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** \brief Pointer to vtable for this context. */ - const br_block_cbcdec_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - uint32_t skey[96]; - unsigned num_rounds; -#endif -} br_des_ct_cbcdec_keys; - -/** - * \brief Class instance for DES CBC encryption (`des_ct` implementation). - */ -extern const br_block_cbcenc_class br_des_ct_cbcenc_vtable; - -/** - * \brief Class instance for DES CBC decryption (`des_ct` implementation). - */ -extern const br_block_cbcdec_class br_des_ct_cbcdec_vtable; - -/** - * \brief Context initialisation (key schedule) for DES CBC encryption - * (`des_ct` implementation). - * - * \param ctx context to initialise. - * \param key secret key. - * \param len secret key length (in bytes). - */ -void br_des_ct_cbcenc_init(br_des_ct_cbcenc_keys *ctx, - const void *key, size_t len); - -/** - * \brief Context initialisation (key schedule) for DES CBC decryption - * (`des_ct` implementation). - * - * \param ctx context to initialise. - * \param key secret key. - * \param len secret key length (in bytes). - */ -void br_des_ct_cbcdec_init(br_des_ct_cbcdec_keys *ctx, - const void *key, size_t len); - -/** - * \brief CBC encryption with DES (`des_ct` implementation). - * - * \param ctx context (already initialised). - * \param iv IV (updated). - * \param data data to encrypt (updated). - * \param len data length (in bytes, MUST be multiple of 8). - */ -void br_des_ct_cbcenc_run(const br_des_ct_cbcenc_keys *ctx, void *iv, - void *data, size_t len); - -/** - * \brief CBC decryption with DES (`des_ct` implementation). - * - * \param ctx context (already initialised). - * \param iv IV (updated). - * \param data data to decrypt (updated). - * \param len data length (in bytes, MUST be multiple of 8). - */ -void br_des_ct_cbcdec_run(const br_des_ct_cbcdec_keys *ctx, void *iv, - void *data, size_t len); - -/* - * These structures are large enough to accommodate subkeys for all - * DES/3DES implementations. - */ - -/** - * \brief Aggregate structure large enough to be used as context for - * subkeys (CBC encryption) for all DES implementations. - */ -typedef union { - const br_block_cbcenc_class *vtable; - br_des_tab_cbcenc_keys tab; - br_des_ct_cbcenc_keys ct; -} br_des_gen_cbcenc_keys; - -/** - * \brief Aggregate structure large enough to be used as context for - * subkeys (CBC decryption) for all DES implementations. - */ -typedef union { - const br_block_cbcdec_class *vtable; - br_des_tab_cbcdec_keys c_tab; - br_des_ct_cbcdec_keys c_ct; -} br_des_gen_cbcdec_keys; - -/** - * \brief Type for a ChaCha20 implementation. - * - * An implementation follows the description in RFC 7539: - * - * - Key is 256 bits (`key` points to exactly 32 bytes). - * - * - IV is 96 bits (`iv` points to exactly 12 bytes). - * - * - Block counter is over 32 bits and starts at value `cc`; the - * resulting value is returned. - * - * Data (pointed to by `data`, of length `len`) is encrypted/decrypted - * in place. If `len` is not a multiple of 64, then the excess bytes from - * the last block processing are dropped (therefore, "chunked" processing - * works only as long as each non-final chunk has a length multiple of 64). - * - * \param key secret key (32 bytes). - * \param iv IV (12 bytes). - * \param cc initial counter value. - * \param data data to encrypt or decrypt. - * \param len data length (in bytes). - */ -typedef uint32_t (*br_chacha20_run)(const void *key, - const void *iv, uint32_t cc, void *data, size_t len); - -/** - * \brief ChaCha20 implementation (straightforward C code, constant-time). - * - * \see br_chacha20_run - * - * \param key secret key (32 bytes). - * \param iv IV (12 bytes). - * \param cc initial counter value. - * \param data data to encrypt or decrypt. - * \param len data length (in bytes). - */ -uint32_t br_chacha20_ct_run(const void *key, - const void *iv, uint32_t cc, void *data, size_t len); - -/** - * \brief ChaCha20 implementation (SSE2 code, constant-time). - * - * This implementation is available only on x86 platforms, depending on - * compiler support. Moreover, in 32-bit mode, it might not actually run, - * if the underlying hardware does not implement the SSE2 opcode (in - * 64-bit mode, SSE2 is part of the ABI, so if the code could be compiled - * at all, then it can run). Use `br_chacha20_sse2_get()` to safely obtain - * a pointer to that function. - * - * \see br_chacha20_run - * - * \param key secret key (32 bytes). - * \param iv IV (12 bytes). - * \param cc initial counter value. - * \param data data to encrypt or decrypt. - * \param len data length (in bytes). - */ -uint32_t br_chacha20_sse2_run(const void *key, - const void *iv, uint32_t cc, void *data, size_t len); - -/** - * \brief Obtain the `sse2` ChaCha20 implementation, if available. - * - * This function returns a pointer to `br_chacha20_sse2_run`, if - * that implementation was compiled in the library _and_ the SSE2 - * opcodes are available on the currently running CPU. If either of - * these conditions is not met, then this function returns `0`. - * - * \return the `sse2` ChaCha20 implementation, or `0`. - */ -br_chacha20_run br_chacha20_sse2_get(void); - -/** - * \brief Type for a ChaCha20+Poly1305 AEAD implementation. - * - * The provided data is encrypted or decrypted with ChaCha20. The - * authentication tag is computed on the concatenation of the - * additional data and the ciphertext, with the padding and lengths - * as described in RFC 7539 (section 2.8). - * - * After decryption, the caller is responsible for checking that the - * computed tag matches the expected value. - * - * \param key secret key (32 bytes). - * \param iv nonce (12 bytes). - * \param data data to encrypt or decrypt. - * \param len data length (in bytes). - * \param aad additional authenticated data. - * \param aad_len length of additional authenticated data (in bytes). - * \param tag output buffer for the authentication tag. - * \param ichacha implementation of ChaCha20. - * \param encrypt non-zero for encryption, zero for decryption. - */ -typedef void (*br_poly1305_run)(const void *key, const void *iv, - void *data, size_t len, const void *aad, size_t aad_len, - void *tag, br_chacha20_run ichacha, int encrypt); - -/** - * \brief ChaCha20+Poly1305 AEAD implementation (mixed 32-bit multiplications). - * - * \see br_poly1305_run - * - * \param key secret key (32 bytes). - * \param iv nonce (12 bytes). - * \param data data to encrypt or decrypt. - * \param len data length (in bytes). - * \param aad additional authenticated data. - * \param aad_len length of additional authenticated data (in bytes). - * \param tag output buffer for the authentication tag. - * \param ichacha implementation of ChaCha20. - * \param encrypt non-zero for encryption, zero for decryption. - */ -void br_poly1305_ctmul_run(const void *key, const void *iv, - void *data, size_t len, const void *aad, size_t aad_len, - void *tag, br_chacha20_run ichacha, int encrypt); - -/** - * \brief ChaCha20+Poly1305 AEAD implementation (pure 32-bit multiplications). - * - * \see br_poly1305_run - * - * \param key secret key (32 bytes). - * \param iv nonce (12 bytes). - * \param data data to encrypt or decrypt. - * \param len data length (in bytes). - * \param aad additional authenticated data. - * \param aad_len length of additional authenticated data (in bytes). - * \param tag output buffer for the authentication tag. - * \param ichacha implementation of ChaCha20. - * \param encrypt non-zero for encryption, zero for decryption. - */ -void br_poly1305_ctmul32_run(const void *key, const void *iv, - void *data, size_t len, const void *aad, size_t aad_len, - void *tag, br_chacha20_run ichacha, int encrypt); - -/** - * \brief ChaCha20+Poly1305 AEAD implementation (i15). - * - * This implementation relies on the generic big integer code "i15" - * (which uses pure 32-bit multiplications). As such, it may save a - * little code footprint in a context where "i15" is already included - * (e.g. for elliptic curves or for RSA); however, it is also - * substantially slower than the ctmul and ctmul32 implementations. - * - * \see br_poly1305_run - * - * \param key secret key (32 bytes). - * \param iv nonce (12 bytes). - * \param data data to encrypt or decrypt. - * \param len data length (in bytes). - * \param aad additional authenticated data. - * \param aad_len length of additional authenticated data (in bytes). - * \param tag output buffer for the authentication tag. - * \param ichacha implementation of ChaCha20. - * \param encrypt non-zero for encryption, zero for decryption. - */ -void br_poly1305_i15_run(const void *key, const void *iv, - void *data, size_t len, const void *aad, size_t aad_len, - void *tag, br_chacha20_run ichacha, int encrypt); - -/** - * \brief ChaCha20+Poly1305 AEAD implementation (ctmulq). - * - * This implementation uses 64-bit multiplications (result over 128 bits). - * It is available only on platforms that offer such a primitive (in - * practice, 64-bit architectures). Use `br_poly1305_ctmulq_get()` to - * dynamically obtain a pointer to that function, or 0 if not supported. - * - * \see br_poly1305_run - * - * \param key secret key (32 bytes). - * \param iv nonce (12 bytes). - * \param data data to encrypt or decrypt. - * \param len data length (in bytes). - * \param aad additional authenticated data. - * \param aad_len length of additional authenticated data (in bytes). - * \param tag output buffer for the authentication tag. - * \param ichacha implementation of ChaCha20. - * \param encrypt non-zero for encryption, zero for decryption. - */ -void br_poly1305_ctmulq_run(const void *key, const void *iv, - void *data, size_t len, const void *aad, size_t aad_len, - void *tag, br_chacha20_run ichacha, int encrypt); - -/** - * \brief Get the ChaCha20+Poly1305 "ctmulq" implementation, if available. - * - * This function returns a pointer to the `br_poly1305_ctmulq_run()` - * function if supported on the current platform; otherwise, it returns 0. - * - * \return the ctmulq ChaCha20+Poly1305 implementation, or 0. - */ -br_poly1305_run br_poly1305_ctmulq_get(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/tls/bearssl/bearssl_ec.h b/src/tls/bearssl/bearssl_ec.h deleted file mode 100644 index db22692ee..000000000 --- a/src/tls/bearssl/bearssl_ec.h +++ /dev/null @@ -1,883 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef BR_BEARSSL_EC_H__ -#define BR_BEARSSL_EC_H__ - -#include -#include - -#include "bearssl_rand.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** \file bearssl_ec.h - * - * # Elliptic Curves - * - * This file documents the EC implementations provided with BearSSL, and - * ECDSA. - * - * ## Elliptic Curve API - * - * Only "named curves" are supported. Each EC implementation supports - * one or several named curves, identified by symbolic identifiers. - * These identifiers are small integers, that correspond to the values - * registered by the - * [IANA](http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8). - * - * Since all currently defined elliptic curve identifiers are in the 0..31 - * range, it is convenient to encode support of some curves in a 32-bit - * word, such that bit x corresponds to curve of identifier x. - * - * An EC implementation is incarnated by a `br_ec_impl` instance, that - * offers the following fields: - * - * - `supported_curves` - * - * A 32-bit word that documents the identifiers of the curves supported - * by this implementation. - * - * - `generator()` - * - * Callback method that returns a pointer to the conventional generator - * point for that curve. - * - * - `order()` - * - * Callback method that returns a pointer to the subgroup order for - * that curve. That value uses unsigned big-endian encoding. - * - * - `xoff()` - * - * Callback method that returns the offset and length of the X - * coordinate in an encoded point. - * - * - `mul()` - * - * Multiply a curve point with an integer. - * - * - `mulgen()` - * - * Multiply the curve generator with an integer. This may be faster - * than the generic `mul()`. - * - * - `muladd()` - * - * Multiply two curve points by two integers, and return the sum of - * the two products. - * - * All curve points are represented in uncompressed format. The `mul()` - * and `muladd()` methods take care to validate that the provided points - * are really part of the relevant curve subgroup. - * - * For all point multiplication functions, the following holds: - * - * - Functions validate that the provided points are valid members - * of the relevant curve subgroup. An error is reported if that is - * not the case. - * - * - Processing is constant-time, even if the point operands are not - * valid. This holds for both the source and resulting points, and - * the multipliers (integers). Only the byte length of the provided - * multiplier arrays (not their actual value length in bits) may - * leak through timing-based side channels. - * - * - The multipliers (integers) MUST be lower than the subgroup order. - * If this property is not met, then the result is indeterminate, - * but an error value is not ncessearily returned. - * - * - * ## ECDSA - * - * ECDSA signatures have two standard formats, called "raw" and "asn1". - * Internally, such a signature is a pair of modular integers `(r,s)`. - * The "raw" format is the concatenation of the unsigned big-endian - * encodings of these two integers, possibly left-padded with zeros so - * that they have the same encoded length. The "asn1" format is the - * DER encoding of an ASN.1 structure that contains the two integer - * values: - * - * ECDSASignature ::= SEQUENCE { - * r INTEGER, - * s INTEGER - * } - * - * In general, in all of X.509 and SSL/TLS, the "asn1" format is used. - * BearSSL offers ECDSA implementations for both formats; conversion - * functions between the two formats are also provided. Conversion of a - * "raw" format signature into "asn1" may enlarge a signature by no more - * than 9 bytes for all supported curves; conversely, conversion of an - * "asn1" signature to "raw" may expand the signature but the "raw" - * length will never be more than twice the length of the "asn1" length - * (and usually it will be shorter). - * - * Note that for a given signature, the "raw" format is not fully - * deterministic, in that it does not enforce a minimal common length. - */ - -/* - * Standard curve ID. These ID are equal to the assigned numerical - * identifiers assigned to these curves for TLS: - * http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8 - */ - -/** \brief Identifier for named curve sect163k1. */ -#define BR_EC_sect163k1 1 - -/** \brief Identifier for named curve sect163r1. */ -#define BR_EC_sect163r1 2 - -/** \brief Identifier for named curve sect163r2. */ -#define BR_EC_sect163r2 3 - -/** \brief Identifier for named curve sect193r1. */ -#define BR_EC_sect193r1 4 - -/** \brief Identifier for named curve sect193r2. */ -#define BR_EC_sect193r2 5 - -/** \brief Identifier for named curve sect233k1. */ -#define BR_EC_sect233k1 6 - -/** \brief Identifier for named curve sect233r1. */ -#define BR_EC_sect233r1 7 - -/** \brief Identifier for named curve sect239k1. */ -#define BR_EC_sect239k1 8 - -/** \brief Identifier for named curve sect283k1. */ -#define BR_EC_sect283k1 9 - -/** \brief Identifier for named curve sect283r1. */ -#define BR_EC_sect283r1 10 - -/** \brief Identifier for named curve sect409k1. */ -#define BR_EC_sect409k1 11 - -/** \brief Identifier for named curve sect409r1. */ -#define BR_EC_sect409r1 12 - -/** \brief Identifier for named curve sect571k1. */ -#define BR_EC_sect571k1 13 - -/** \brief Identifier for named curve sect571r1. */ -#define BR_EC_sect571r1 14 - -/** \brief Identifier for named curve secp160k1. */ -#define BR_EC_secp160k1 15 - -/** \brief Identifier for named curve secp160r1. */ -#define BR_EC_secp160r1 16 - -/** \brief Identifier for named curve secp160r2. */ -#define BR_EC_secp160r2 17 - -/** \brief Identifier for named curve secp192k1. */ -#define BR_EC_secp192k1 18 - -/** \brief Identifier for named curve secp192r1. */ -#define BR_EC_secp192r1 19 - -/** \brief Identifier for named curve secp224k1. */ -#define BR_EC_secp224k1 20 - -/** \brief Identifier for named curve secp224r1. */ -#define BR_EC_secp224r1 21 - -/** \brief Identifier for named curve secp256k1. */ -#define BR_EC_secp256k1 22 - -/** \brief Identifier for named curve secp256r1. */ -#define BR_EC_secp256r1 23 - -/** \brief Identifier for named curve secp384r1. */ -#define BR_EC_secp384r1 24 - -/** \brief Identifier for named curve secp521r1. */ -#define BR_EC_secp521r1 25 - -/** \brief Identifier for named curve brainpoolP256r1. */ -#define BR_EC_brainpoolP256r1 26 - -/** \brief Identifier for named curve brainpoolP384r1. */ -#define BR_EC_brainpoolP384r1 27 - -/** \brief Identifier for named curve brainpoolP512r1. */ -#define BR_EC_brainpoolP512r1 28 - -/** \brief Identifier for named curve Curve25519. */ -#define BR_EC_curve25519 29 - -/** \brief Identifier for named curve Curve448. */ -#define BR_EC_curve448 30 - -/** - * \brief Structure for an EC public key. - */ -typedef struct { - /** \brief Identifier for the curve used by this key. */ - int curve; - /** \brief Public curve point (uncompressed format). */ - unsigned char *q; - /** \brief Length of public curve point (in bytes). */ - size_t qlen; -} br_ec_public_key; - -/** - * \brief Structure for an EC private key. - * - * The private key is an integer modulo the curve subgroup order. The - * encoding below tolerates extra leading zeros. In general, it is - * recommended that the private key has the same length as the curve - * subgroup order. - */ -typedef struct { - /** \brief Identifier for the curve used by this key. */ - int curve; - /** \brief Private key (integer, unsigned big-endian encoding). */ - unsigned char *x; - /** \brief Private key length (in bytes). */ - size_t xlen; -} br_ec_private_key; - -/** - * \brief Type for an EC implementation. - */ -typedef struct { - /** - * \brief Supported curves. - * - * This word is a bitfield: bit `x` is set if the curve of ID `x` - * is supported. E.g. an implementation supporting both NIST P-256 - * (secp256r1, ID 23) and NIST P-384 (secp384r1, ID 24) will have - * value `0x01800000` in this field. - */ - uint32_t supported_curves; - - /** - * \brief Get the conventional generator. - * - * This function returns the conventional generator (encoded - * curve point) for the specified curve. This function MUST NOT - * be called if the curve is not supported. - * - * \param curve curve identifier. - * \param len receiver for the encoded generator length (in bytes). - * \return the encoded generator. - */ - const unsigned char *(*generator)(int curve, size_t *len); - - /** - * \brief Get the subgroup order. - * - * This function returns the order of the subgroup generated by - * the conventional generator, for the specified curve. Unsigned - * big-endian encoding is used. This function MUST NOT be called - * if the curve is not supported. - * - * \param curve curve identifier. - * \param len receiver for the encoded order length (in bytes). - * \return the encoded order. - */ - const unsigned char *(*order)(int curve, size_t *len); - - /** - * \brief Get the offset and length for the X coordinate. - * - * This function returns the offset and length (in bytes) of - * the X coordinate in an encoded non-zero point. - * - * \param curve curve identifier. - * \param len receiver for the X coordinate length (in bytes). - * \return the offset for the X coordinate (in bytes). - */ - size_t (*xoff)(int curve, size_t *len); - - /** - * \brief Multiply a curve point by an integer. - * - * The source point is provided in array `G` (of size `Glen` bytes); - * the multiplication result is written over it. The multiplier - * `x` (of size `xlen` bytes) uses unsigned big-endian encoding. - * - * Rules: - * - * - The specified curve MUST be supported. - * - * - The source point must be a valid point on the relevant curve - * subgroup (and not the "point at infinity" either). If this is - * not the case, then this function returns an error (0). - * - * - The multiplier integer MUST be non-zero and less than the - * curve subgroup order. If this property does not hold, then - * the result is indeterminate and an error code is not - * guaranteed. - * - * Returned value is 1 on success, 0 on error. On error, the - * contents of `G` are indeterminate. - * - * \param G point to multiply. - * \param Glen length of the encoded point (in bytes). - * \param x multiplier (unsigned big-endian). - * \param xlen multiplier length (in bytes). - * \param curve curve identifier. - * \return 1 on success, 0 on error. - */ - uint32_t (*mul)(unsigned char *G, size_t Glen, - const unsigned char *x, size_t xlen, int curve); - - /** - * \brief Multiply the generator by an integer. - * - * The multiplier MUST be non-zero and less than the curve - * subgroup order. Results are indeterminate if this property - * does not hold. - * - * \param R output buffer for the point. - * \param x multiplier (unsigned big-endian). - * \param xlen multiplier length (in bytes). - * \param curve curve identifier. - * \return encoded result point length (in bytes). - */ - size_t (*mulgen)(unsigned char *R, - const unsigned char *x, size_t xlen, int curve); - - /** - * \brief Multiply two points by two integers and add the - * results. - * - * The point `x*A + y*B` is computed and written back in the `A` - * array. - * - * Rules: - * - * - The specified curve MUST be supported. - * - * - The source points (`A` and `B`) must be valid points on - * the relevant curve subgroup (and not the "point at - * infinity" either). If this is not the case, then this - * function returns an error (0). - * - * - If the `B` pointer is `NULL`, then the conventional - * subgroup generator is used. With some implementations, - * this may be faster than providing a pointer to the - * generator. - * - * - The multiplier integers (`x` and `y`) MUST be non-zero - * and less than the curve subgroup order. If either integer - * is zero, then an error is reported, but if one of them is - * not lower than the subgroup order, then the result is - * indeterminate and an error code is not guaranteed. - * - * - If the final result is the point at infinity, then an - * error is returned. - * - * Returned value is 1 on success, 0 on error. On error, the - * contents of `A` are indeterminate. - * - * \param A first point to multiply. - * \param B second point to multiply (`NULL` for the generator). - * \param len common length of the encoded points (in bytes). - * \param x multiplier for `A` (unsigned big-endian). - * \param xlen length of multiplier for `A` (in bytes). - * \param y multiplier for `A` (unsigned big-endian). - * \param ylen length of multiplier for `A` (in bytes). - * \param curve curve identifier. - * \return 1 on success, 0 on error. - */ - uint32_t (*muladd)(unsigned char *A, const unsigned char *B, size_t len, - const unsigned char *x, size_t xlen, - const unsigned char *y, size_t ylen, int curve); -} br_ec_impl; - -/** - * \brief EC implementation "i31". - * - * This implementation internally uses generic code for modular integers, - * with a representation as sequences of 31-bit words. It supports secp256r1, - * secp384r1 and secp521r1 (aka NIST curves P-256, P-384 and P-521). - */ -extern const br_ec_impl br_ec_prime_i31; - -/** - * \brief EC implementation "i15". - * - * This implementation internally uses generic code for modular integers, - * with a representation as sequences of 15-bit words. It supports secp256r1, - * secp384r1 and secp521r1 (aka NIST curves P-256, P-384 and P-521). - */ -extern const br_ec_impl br_ec_prime_i15; - -/** - * \brief EC implementation "m15" for P-256. - * - * This implementation uses specialised code for curve secp256r1 (also - * known as NIST P-256), with optional Karatsuba decomposition, and fast - * modular reduction thanks to the field modulus special format. Only - * 32-bit multiplications are used (with 32-bit results, not 64-bit). - */ -extern const br_ec_impl br_ec_p256_m15; - -/** - * \brief EC implementation "m31" for P-256. - * - * This implementation uses specialised code for curve secp256r1 (also - * known as NIST P-256), relying on multiplications of 31-bit values - * (MUL31). - */ -extern const br_ec_impl br_ec_p256_m31; - -/** - * \brief EC implementation "i15" (generic code) for Curve25519. - * - * This implementation uses the generic code for modular integers (with - * 15-bit words) to support Curve25519. Due to the specificities of the - * curve definition, the following applies: - * - * - `muladd()` is not implemented (the function returns 0 systematically). - * - `order()` returns 2^255-1, since the point multiplication algorithm - * accepts any 32-bit integer as input (it clears the top bit and low - * three bits systematically). - */ -extern const br_ec_impl br_ec_c25519_i15; - -/** - * \brief EC implementation "i31" (generic code) for Curve25519. - * - * This implementation uses the generic code for modular integers (with - * 31-bit words) to support Curve25519. Due to the specificities of the - * curve definition, the following applies: - * - * - `muladd()` is not implemented (the function returns 0 systematically). - * - `order()` returns 2^255-1, since the point multiplication algorithm - * accepts any 32-bit integer as input (it clears the top bit and low - * three bits systematically). - */ -extern const br_ec_impl br_ec_c25519_i31; - -/** - * \brief EC implementation "m15" (specialised code) for Curve25519. - * - * This implementation uses custom code relying on multiplication of - * integers up to 15 bits. Due to the specificities of the curve - * definition, the following applies: - * - * - `muladd()` is not implemented (the function returns 0 systematically). - * - `order()` returns 2^255-1, since the point multiplication algorithm - * accepts any 32-bit integer as input (it clears the top bit and low - * three bits systematically). - */ -extern const br_ec_impl br_ec_c25519_m15; - -/** - * \brief EC implementation "m31" (specialised code) for Curve25519. - * - * This implementation uses custom code relying on multiplication of - * integers up to 31 bits. Due to the specificities of the curve - * definition, the following applies: - * - * - `muladd()` is not implemented (the function returns 0 systematically). - * - `order()` returns 2^255-1, since the point multiplication algorithm - * accepts any 32-bit integer as input (it clears the top bit and low - * three bits systematically). - */ -extern const br_ec_impl br_ec_c25519_m31; - -/** - * \brief Aggregate EC implementation "m15". - * - * This implementation is a wrapper for: - * - * - `br_ec_c25519_m15` for Curve25519 - * - `br_ec_p256_m15` for NIST P-256 - * - `br_ec_prime_i15` for other curves (NIST P-384 and NIST-P512) - */ -extern const br_ec_impl br_ec_all_m15; - -/** - * \brief Aggregate EC implementation "m31". - * - * This implementation is a wrapper for: - * - * - `br_ec_c25519_m31` for Curve25519 - * - `br_ec_p256_m31` for NIST P-256 - * - `br_ec_prime_i31` for other curves (NIST P-384 and NIST-P512) - */ -extern const br_ec_impl br_ec_all_m31; - -/** - * \brief Get the "default" EC implementation for the current system. - * - * This returns a pointer to the preferred implementation on the - * current system. - * - * \return the default EC implementation. - */ -const br_ec_impl *br_ec_get_default(void); - -/** - * \brief Convert a signature from "raw" to "asn1". - * - * Conversion is done "in place" and the new length is returned. - * Conversion may enlarge the signature, but by no more than 9 bytes at - * most. On error, 0 is returned (error conditions include an odd raw - * signature length, or an oversized integer). - * - * \param sig signature to convert. - * \param sig_len signature length (in bytes). - * \return the new signature length, or 0 on error. - */ -size_t br_ecdsa_raw_to_asn1(void *sig, size_t sig_len); - -/** - * \brief Convert a signature from "asn1" to "raw". - * - * Conversion is done "in place" and the new length is returned. - * Conversion may enlarge the signature, but the new signature length - * will be less than twice the source length at most. On error, 0 is - * returned (error conditions include an invalid ASN.1 structure or an - * oversized integer). - * - * \param sig signature to convert. - * \param sig_len signature length (in bytes). - * \return the new signature length, or 0 on error. - */ -size_t br_ecdsa_asn1_to_raw(void *sig, size_t sig_len); - -/** - * \brief Type for an ECDSA signer function. - * - * A pointer to the EC implementation is provided. The hash value is - * assumed to have the length inferred from the designated hash function - * class. - * - * Signature is written in the buffer pointed to by `sig`, and the length - * (in bytes) is returned. On error, nothing is written in the buffer, - * and 0 is returned. This function returns 0 if the specified curve is - * not supported by the provided EC implementation. - * - * The signature format is either "raw" or "asn1", depending on the - * implementation; maximum length is predictable from the implemented - * curve: - * - * | curve | raw | asn1 | - * | :--------- | --: | ---: | - * | NIST P-256 | 64 | 72 | - * | NIST P-384 | 96 | 104 | - * | NIST P-521 | 132 | 139 | - * - * \param impl EC implementation to use. - * \param hf hash function used to process the data. - * \param hash_value signed data (hashed). - * \param sk EC private key. - * \param sig destination buffer. - * \return the signature length (in bytes), or 0 on error. - */ -typedef size_t (*br_ecdsa_sign)(const br_ec_impl *impl, - const br_hash_class *hf, const void *hash_value, - const br_ec_private_key *sk, void *sig); - -/** - * \brief Type for an ECDSA signature verification function. - * - * A pointer to the EC implementation is provided. The hashed value, - * computed over the purportedly signed data, is also provided with - * its length. - * - * The signature format is either "raw" or "asn1", depending on the - * implementation. - * - * Returned value is 1 on success (valid signature), 0 on error. This - * function returns 0 if the specified curve is not supported by the - * provided EC implementation. - * - * \param impl EC implementation to use. - * \param hash signed data (hashed). - * \param hash_len hash value length (in bytes). - * \param pk EC public key. - * \param sig signature. - * \param sig_len signature length (in bytes). - * \return 1 on success, 0 on error. - */ -typedef uint32_t (*br_ecdsa_vrfy)(const br_ec_impl *impl, - const void *hash, size_t hash_len, - const br_ec_public_key *pk, const void *sig, size_t sig_len); - -/** - * \brief ECDSA signature generator, "i31" implementation, "asn1" format. - * - * \see br_ecdsa_sign() - * - * \param impl EC implementation to use. - * \param hf hash function used to process the data. - * \param hash_value signed data (hashed). - * \param sk EC private key. - * \param sig destination buffer. - * \return the signature length (in bytes), or 0 on error. - */ -size_t br_ecdsa_i31_sign_asn1(const br_ec_impl *impl, - const br_hash_class *hf, const void *hash_value, - const br_ec_private_key *sk, void *sig); - -/** - * \brief ECDSA signature generator, "i31" implementation, "raw" format. - * - * \see br_ecdsa_sign() - * - * \param impl EC implementation to use. - * \param hf hash function used to process the data. - * \param hash_value signed data (hashed). - * \param sk EC private key. - * \param sig destination buffer. - * \return the signature length (in bytes), or 0 on error. - */ -size_t br_ecdsa_i31_sign_raw(const br_ec_impl *impl, - const br_hash_class *hf, const void *hash_value, - const br_ec_private_key *sk, void *sig); - -/** - * \brief ECDSA signature verifier, "i31" implementation, "asn1" format. - * - * \see br_ecdsa_vrfy() - * - * \param impl EC implementation to use. - * \param hash signed data (hashed). - * \param hash_len hash value length (in bytes). - * \param pk EC public key. - * \param sig signature. - * \param sig_len signature length (in bytes). - * \return 1 on success, 0 on error. - */ -uint32_t br_ecdsa_i31_vrfy_asn1(const br_ec_impl *impl, - const void *hash, size_t hash_len, - const br_ec_public_key *pk, const void *sig, size_t sig_len); - -/** - * \brief ECDSA signature verifier, "i31" implementation, "raw" format. - * - * \see br_ecdsa_vrfy() - * - * \param impl EC implementation to use. - * \param hash signed data (hashed). - * \param hash_len hash value length (in bytes). - * \param pk EC public key. - * \param sig signature. - * \param sig_len signature length (in bytes). - * \return 1 on success, 0 on error. - */ -uint32_t br_ecdsa_i31_vrfy_raw(const br_ec_impl *impl, - const void *hash, size_t hash_len, - const br_ec_public_key *pk, const void *sig, size_t sig_len); - -/** - * \brief ECDSA signature generator, "i15" implementation, "asn1" format. - * - * \see br_ecdsa_sign() - * - * \param impl EC implementation to use. - * \param hf hash function used to process the data. - * \param hash_value signed data (hashed). - * \param sk EC private key. - * \param sig destination buffer. - * \return the signature length (in bytes), or 0 on error. - */ -size_t br_ecdsa_i15_sign_asn1(const br_ec_impl *impl, - const br_hash_class *hf, const void *hash_value, - const br_ec_private_key *sk, void *sig); - -/** - * \brief ECDSA signature generator, "i15" implementation, "raw" format. - * - * \see br_ecdsa_sign() - * - * \param impl EC implementation to use. - * \param hf hash function used to process the data. - * \param hash_value signed data (hashed). - * \param sk EC private key. - * \param sig destination buffer. - * \return the signature length (in bytes), or 0 on error. - */ -size_t br_ecdsa_i15_sign_raw(const br_ec_impl *impl, - const br_hash_class *hf, const void *hash_value, - const br_ec_private_key *sk, void *sig); - -/** - * \brief ECDSA signature verifier, "i15" implementation, "asn1" format. - * - * \see br_ecdsa_vrfy() - * - * \param impl EC implementation to use. - * \param hash signed data (hashed). - * \param hash_len hash value length (in bytes). - * \param pk EC public key. - * \param sig signature. - * \param sig_len signature length (in bytes). - * \return 1 on success, 0 on error. - */ -uint32_t br_ecdsa_i15_vrfy_asn1(const br_ec_impl *impl, - const void *hash, size_t hash_len, - const br_ec_public_key *pk, const void *sig, size_t sig_len); - -/** - * \brief ECDSA signature verifier, "i15" implementation, "raw" format. - * - * \see br_ecdsa_vrfy() - * - * \param impl EC implementation to use. - * \param hash signed data (hashed). - * \param hash_len hash value length (in bytes). - * \param pk EC public key. - * \param sig signature. - * \param sig_len signature length (in bytes). - * \return 1 on success, 0 on error. - */ -uint32_t br_ecdsa_i15_vrfy_raw(const br_ec_impl *impl, - const void *hash, size_t hash_len, - const br_ec_public_key *pk, const void *sig, size_t sig_len); - -/** - * \brief Get "default" ECDSA implementation (signer, asn1 format). - * - * This returns the preferred implementation of ECDSA signature generation - * ("asn1" output format) on the current system. - * - * \return the default implementation. - */ -br_ecdsa_sign br_ecdsa_sign_asn1_get_default(void); - -/** - * \brief Get "default" ECDSA implementation (signer, raw format). - * - * This returns the preferred implementation of ECDSA signature generation - * ("raw" output format) on the current system. - * - * \return the default implementation. - */ -br_ecdsa_sign br_ecdsa_sign_raw_get_default(void); - -/** - * \brief Get "default" ECDSA implementation (verifier, asn1 format). - * - * This returns the preferred implementation of ECDSA signature verification - * ("asn1" output format) on the current system. - * - * \return the default implementation. - */ -br_ecdsa_vrfy br_ecdsa_vrfy_asn1_get_default(void); - -/** - * \brief Get "default" ECDSA implementation (verifier, raw format). - * - * This returns the preferred implementation of ECDSA signature verification - * ("raw" output format) on the current system. - * - * \return the default implementation. - */ -br_ecdsa_vrfy br_ecdsa_vrfy_raw_get_default(void); - -/** - * \brief Maximum size for EC private key element buffer. - * - * This is the largest number of bytes that `br_ec_keygen()` may need or - * ever return. - */ -#define BR_EC_KBUF_PRIV_MAX_SIZE 72 - -/** - * \brief Maximum size for EC public key element buffer. - * - * This is the largest number of bytes that `br_ec_compute_public()` may - * need or ever return. - */ -#define BR_EC_KBUF_PUB_MAX_SIZE 145 - -/** - * \brief Generate a new EC private key. - * - * If the specified `curve` is not supported by the elliptic curve - * implementation (`impl`), then this function returns zero. - * - * The `sk` structure fields are set to the new private key data. In - * particular, `sk.x` is made to point to the provided key buffer (`kbuf`), - * in which the actual private key data is written. That buffer is assumed - * to be large enough. The `BR_EC_KBUF_PRIV_MAX_SIZE` defines the maximum - * size for all supported curves. - * - * The number of bytes used in `kbuf` is returned. If `kbuf` is `NULL`, then - * the private key is not actually generated, and `sk` may also be `NULL`; - * the minimum length for `kbuf` is still computed and returned. - * - * If `sk` is `NULL` but `kbuf` is not `NULL`, then the private key is - * still generated and stored in `kbuf`. - * - * \param rng_ctx source PRNG context (already initialized). - * \param impl the elliptic curve implementation. - * \param sk the private key structure to fill, or `NULL`. - * \param kbuf the key element buffer, or `NULL`. - * \param curve the curve identifier. - * \return the key data length (in bytes), or zero. - */ -size_t br_ec_keygen(const br_prng_class **rng_ctx, - const br_ec_impl *impl, br_ec_private_key *sk, - void *kbuf, int curve); - -/** - * \brief Compute EC public key from EC private key. - * - * This function uses the provided elliptic curve implementation (`impl`) - * to compute the public key corresponding to the private key held in `sk`. - * The public key point is written into `kbuf`, which is then linked from - * the `*pk` structure. The size of the public key point, i.e. the number - * of bytes used in `kbuf`, is returned. - * - * If `kbuf` is `NULL`, then the public key point is NOT computed, and - * the public key structure `*pk` is unmodified (`pk` may be `NULL` in - * that case). The size of the public key point is still returned. - * - * If `pk` is `NULL` but `kbuf` is not `NULL`, then the public key - * point is computed and stored in `kbuf`, and its size is returned. - * - * If the curve used by the private key is not supported by the curve - * implementation, then this function returns zero. - * - * The private key MUST be valid. An off-range private key value is not - * necessarily detected, and leads to unpredictable results. - * - * \param impl the elliptic curve implementation. - * \param pk the public key structure to fill (or `NULL`). - * \param kbuf the public key point buffer (or `NULL`). - * \param sk the source private key. - * \return the public key point length (in bytes), or zero. - */ -size_t br_ec_compute_pub(const br_ec_impl *impl, br_ec_public_key *pk, - void *kbuf, const br_ec_private_key *sk); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/tls/bearssl/bearssl_hash.h b/src/tls/bearssl/bearssl_hash.h deleted file mode 100644 index 3b15ba7ca..000000000 --- a/src/tls/bearssl/bearssl_hash.h +++ /dev/null @@ -1,1346 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef BR_BEARSSL_HASH_H__ -#define BR_BEARSSL_HASH_H__ - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** \file bearssl_hash.h - * - * # Hash Functions - * - * This file documents the API for hash functions. - * - * - * ## Procedural API - * - * For each implemented hash function, of name "`xxx`", the following - * elements are defined: - * - * - `br_xxx_vtable` - * - * An externally defined instance of `br_hash_class`. - * - * - `br_xxx_SIZE` - * - * A macro that evaluates to the output size (in bytes) of the - * hash function. - * - * - `br_xxx_ID` - * - * A macro that evaluates to a symbolic identifier for the hash - * function. Such identifiers are used with HMAC and signature - * algorithm implementations. - * - * NOTE: for the "standard" hash functions defined in [the TLS - * standard](https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1), - * the symbolic identifiers match the constants used in TLS, i.e. - * 1 to 6 for MD5, SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512, - * respectively. - * - * - `br_xxx_context` - * - * Context for an ongoing computation. It is allocated by the - * caller, and a pointer to it is passed to all functions. A - * context contains no interior pointer, so it can be moved around - * and cloned (with a simple `memcpy()` or equivalent) in order to - * capture the function state at some point. Computations that use - * distinct context structures are independent of each other. The - * first field of `br_xxx_context` is always a pointer to the - * `br_xxx_vtable` structure; `br_xxx_init()` sets that pointer. - * - * - `br_xxx_init(br_xxx_context *ctx)` - * - * Initialise the provided context. Previous contents of the structure - * are ignored. This calls resets the context to the start of a new - * hash computation; it also sets the first field of the context - * structure (called `vtable`) to a pointer to the statically - * allocated constant `br_xxx_vtable` structure. - * - * - `br_xxx_update(br_xxx_context *ctx, const void *data, size_t len)` - * - * Add some more bytes to the hash computation represented by the - * provided context. - * - * - `br_xxx_out(const br_xxx_context *ctx, void *out)` - * - * Complete the hash computation and write the result in the provided - * buffer. The output buffer MUST be large enough to accommodate the - * result. The context is NOT modified by this operation, so this - * function can be used to get a "partial hash" while still keeping - * the possibility of adding more bytes to the input. - * - * - `br_xxx_state(const br_xxx_context *ctx, void *out)` - * - * Get a copy of the "current state" for the computation so far. For - * MD functions (MD5, SHA-1, SHA-2 family), this is the running state - * resulting from the processing of the last complete input block. - * Returned value is the current input length (in bytes). - * - * - `br_xxx_set_state(br_xxx_context *ctx, const void *stb, uint64_t count)` - * - * Set the internal state to the provided values. The 'stb' and - * 'count' values shall match that which was obtained from - * `br_xxx_state()`. This restores the hash state only if the state - * values were at an appropriate block boundary. This does NOT set - * the `vtable` pointer in the context. - * - * Context structures can be discarded without any explicit deallocation. - * Hash function implementations are purely software and don't reserve - * any resources outside of the context structure itself. - * - * - * ## Object-Oriented API - * - * For each hash function that follows the procedural API described - * above, an object-oriented API is also provided. In that API, function - * pointers from the vtable (`br_xxx_vtable`) are used. The vtable - * incarnates object-oriented programming. An introduction on the OOP - * concept used here can be read on the BearSSL Web site:
- *    [https://www.bearssl.org/oop.html](https://www.bearssl.org/oop.html) - * - * The vtable offers functions called `init()`, `update()`, `out()`, - * `set()` and `set_state()`, which are in fact the functions from - * the procedural API. That vtable also contains two informative fields: - * - * - `context_size` - * - * The size of the context structure (`br_xxx_context`), in bytes. - * This can be used by generic implementations to perform dynamic - * context allocation. - * - * - `desc` - * - * A "descriptor" field that encodes some information on the hash - * function: symbolic identifier, output size, state size, - * internal block size, details on the padding. - * - * Users of this object-oriented API (in particular generic HMAC - * implementations) may make the following assumptions: - * - * - Hash output size is no more than 64 bytes. - * - Hash internal state size is no more than 64 bytes. - * - Internal block size is a power of two, no less than 16 and no more - * than 256. - * - * - * ## Implemented Hash Functions - * - * Implemented hash functions are: - * - * | Function | Name | Output length | State length | - * | :-------- | :------ | :-----------: | :----------: | - * | MD5 | md5 | 16 | 16 | - * | SHA-1 | sha1 | 20 | 20 | - * | SHA-224 | sha224 | 28 | 32 | - * | SHA-256 | sha256 | 32 | 32 | - * | SHA-384 | sha384 | 48 | 64 | - * | SHA-512 | sha512 | 64 | 64 | - * | MD5+SHA-1 | md5sha1 | 36 | 36 | - * - * (MD5+SHA-1 is the concatenation of MD5 and SHA-1 computed over the - * same input; in the implementation, the internal data buffer is - * shared, thus making it more memory-efficient than separate MD5 and - * SHA-1. It can be useful in implementing SSL 3.0, TLS 1.0 and TLS - * 1.1.) - * - * - * ## Multi-Hasher - * - * An aggregate hasher is provided, that can compute several standard - * hash functions in parallel. It uses `br_multihash_context` and a - * procedural API. It is configured with the implementations (the vtables) - * that it should use; it will then compute all these hash functions in - * parallel, on the same input. It is meant to be used in cases when the - * hash of an object will be used, but the exact hash function is not - * known yet (typically, streamed processing on X.509 certificates). - * - * Only the standard hash functions (MD5, SHA-1, SHA-224, SHA-256, SHA-384 - * and SHA-512) are supported by the multi-hasher. - * - * - * ## GHASH - * - * GHASH is not a generic hash function; it is a _universal_ hash function, - * which, as the name does not say, means that it CANNOT be used in most - * places where a hash function is needed. GHASH is used within the GCM - * encryption mode, to provide the checked integrity functionality. - * - * A GHASH implementation is basically a function that uses the type defined - * in this file under the name `br_ghash`: - * - * typedef void (*br_ghash)(void *y, const void *h, const void *data, size_t len); - * - * The `y` pointer refers to a 16-byte value which is used as input, and - * receives the output of the GHASH invocation. `h` is a 16-byte secret - * value (that serves as key). `data` and `len` define the input data. - * - * Three GHASH implementations are provided, all constant-time, based on - * the use of integer multiplications with appropriate masking to cancel - * carry propagation. - */ - -/** - * \brief Class type for hash function implementations. - * - * A `br_hash_class` instance references the methods implementing a hash - * function. Constant instances of this structure are defined for each - * implemented hash function. Such instances are also called "vtables". - * - * Vtables are used to support object-oriented programming, as - * described on [the BearSSL Web site](https://www.bearssl.org/oop.html). - */ -typedef struct br_hash_class_ br_hash_class; -struct br_hash_class_ { - /** - * \brief Size (in bytes) of the context structure appropriate for - * computing this hash function. - */ - size_t context_size; - - /** - * \brief Descriptor word that contains information about the hash - * function. - * - * For each word `xxx` described below, use `BR_HASHDESC_xxx_OFF` - * and `BR_HASHDESC_xxx_MASK` to access the specific value, as - * follows: - * - * (hf->desc >> BR_HASHDESC_xxx_OFF) & BR_HASHDESC_xxx_MASK - * - * The defined elements are: - * - * - `ID`: the symbolic identifier for the function, as defined - * in [TLS](https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1) - * (MD5 = 1, SHA-1 = 2,...). - * - * - `OUT`: hash output size, in bytes. - * - * - `STATE`: internal running state size, in bytes. - * - * - `LBLEN`: base-2 logarithm for the internal block size, as - * defined for HMAC processing (this is 6 for MD5, SHA-1, SHA-224 - * and SHA-256, since these functions use 64-byte blocks; for - * SHA-384 and SHA-512, this is 7, corresponding to their - * 128-byte blocks). - * - * The descriptor may contain a few other flags. - */ - uint32_t desc; - - /** - * \brief Initialisation method. - * - * This method takes as parameter a pointer to a context area, - * that it initialises. The first field of the context is set - * to this vtable; other elements are initialised for a new hash - * computation. - * - * \param ctx pointer to (the first field of) the context. - */ - void (*init)(const br_hash_class **ctx); - - /** - * \brief Data injection method. - * - * The `len` bytes starting at address `data` are injected into - * the running hash computation incarnated by the specified - * context. The context is updated accordingly. It is allowed - * to have `len == 0`, in which case `data` is ignored (and could - * be `NULL`), and nothing happens. - * on the input data. - * - * \param ctx pointer to (the first field of) the context. - * \param data pointer to the first data byte to inject. - * \param len number of bytes to inject. - */ - void (*update)(const br_hash_class **ctx, const void *data, size_t len); - - /** - * \brief Produce hash output. - * - * The hash output corresponding to all data bytes injected in the - * context since the last `init()` call is computed, and written - * in the buffer pointed to by `dst`. The hash output size depends - * on the implemented hash function (e.g. 16 bytes for MD5). - * The context is _not_ modified by this call, so further bytes - * may be afterwards injected to continue the current computation. - * - * \param ctx pointer to (the first field of) the context. - * \param dst destination buffer for the hash output. - */ - void (*out)(const br_hash_class *const *ctx, void *dst); - - /** - * \brief Get running state. - * - * This method saves the current running state into the `dst` - * buffer. What constitutes the "running state" depends on the - * hash function; for Merkle-DamgÃ¥rd hash functions (like - * MD5 or SHA-1), this is the output obtained after processing - * each block. The number of bytes injected so far is returned. - * The context is not modified by this call. - * - * \param ctx pointer to (the first field of) the context. - * \param dst destination buffer for the state. - * \return the injected total byte length. - */ - uint64_t (*state)(const br_hash_class *const *ctx, void *dst); - - /** - * \brief Set running state. - * - * This methods replaces the running state for the function. - * - * \param ctx pointer to (the first field of) the context. - * \param stb source buffer for the state. - * \param count injected total byte length. - */ - void (*set_state)(const br_hash_class **ctx, - const void *stb, uint64_t count); -}; - -#ifndef BR_DOXYGEN_IGNORE -#define BR_HASHDESC_ID(id) ((uint32_t)(id) << BR_HASHDESC_ID_OFF) -#define BR_HASHDESC_ID_OFF 0 -#define BR_HASHDESC_ID_MASK 0xFF - -#define BR_HASHDESC_OUT(size) ((uint32_t)(size) << BR_HASHDESC_OUT_OFF) -#define BR_HASHDESC_OUT_OFF 8 -#define BR_HASHDESC_OUT_MASK 0x7F - -#define BR_HASHDESC_STATE(size) ((uint32_t)(size) << BR_HASHDESC_STATE_OFF) -#define BR_HASHDESC_STATE_OFF 15 -#define BR_HASHDESC_STATE_MASK 0xFF - -#define BR_HASHDESC_LBLEN(ls) ((uint32_t)(ls) << BR_HASHDESC_LBLEN_OFF) -#define BR_HASHDESC_LBLEN_OFF 23 -#define BR_HASHDESC_LBLEN_MASK 0x0F - -#define BR_HASHDESC_MD_PADDING ((uint32_t)1 << 28) -#define BR_HASHDESC_MD_PADDING_128 ((uint32_t)1 << 29) -#define BR_HASHDESC_MD_PADDING_BE ((uint32_t)1 << 30) -#endif - -/* - * Specific hash functions. - * - * Rules for contexts: - * -- No interior pointer. - * -- No pointer to external dynamically allocated resources. - * -- First field is called 'vtable' and is a pointer to a - * const-qualified br_hash_class instance (pointer is set by init()). - * -- SHA-224 and SHA-256 contexts are identical. - * -- SHA-384 and SHA-512 contexts are identical. - * - * Thus, contexts can be moved and cloned to capture the hash function - * current state; and there is no need for any explicit "release" function. - */ - -/** - * \brief Symbolic identifier for MD5. - */ -#define br_md5_ID 1 - -/** - * \brief MD5 output size (in bytes). - */ -#define br_md5_SIZE 16 - -/** - * \brief Constant vtable for MD5. - */ -extern const br_hash_class br_md5_vtable; - -/** - * \brief MD5 context. - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** - * \brief Pointer to vtable for this context. - */ - const br_hash_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - unsigned char buf[64]; - uint64_t count; - uint32_t val[4]; -#endif -} br_md5_context; - -/** - * \brief MD5 context initialisation. - * - * This function initialises or resets a context for a new MD5 - * computation. It also sets the vtable pointer. - * - * \param ctx pointer to the context structure. - */ -void br_md5_init(br_md5_context *ctx); - -/** - * \brief Inject some data bytes in a running MD5 computation. - * - * The provided context is updated with some data bytes. If the number - * of bytes (`len`) is zero, then the data pointer (`data`) is ignored - * and may be `NULL`, and this function does nothing. - * - * \param ctx pointer to the context structure. - * \param data pointer to the injected data. - * \param len injected data length (in bytes). - */ -void br_md5_update(br_md5_context *ctx, const void *data, size_t len); - -/** - * \brief Compute MD5 output. - * - * The MD5 output for the concatenation of all bytes injected in the - * provided context since the last initialisation or reset call, is - * computed and written in the buffer pointed to by `out`. The context - * itself is not modified, so extra bytes may be injected afterwards - * to continue that computation. - * - * \param ctx pointer to the context structure. - * \param out destination buffer for the hash output. - */ -void br_md5_out(const br_md5_context *ctx, void *out); - -/** - * \brief Save MD5 running state. - * - * The running state for MD5 (output of the last internal block - * processing) is written in the buffer pointed to by `out`. The - * number of bytes injected since the last initialisation or reset - * call is returned. The context is not modified. - * - * \param ctx pointer to the context structure. - * \param out destination buffer for the running state. - * \return the injected total byte length. - */ -uint64_t br_md5_state(const br_md5_context *ctx, void *out); - -/** - * \brief Restore MD5 running state. - * - * The running state for MD5 is set to the provided values. - * - * \param ctx pointer to the context structure. - * \param stb source buffer for the running state. - * \param count the injected total byte length. - */ -void br_md5_set_state(br_md5_context *ctx, const void *stb, uint64_t count); - -/** - * \brief Symbolic identifier for SHA-1. - */ -#define br_sha1_ID 2 - -/** - * \brief SHA-1 output size (in bytes). - */ -#define br_sha1_SIZE 20 - -/** - * \brief Constant vtable for SHA-1. - */ -extern const br_hash_class br_sha1_vtable; - -/** - * \brief SHA-1 context. - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** - * \brief Pointer to vtable for this context. - */ - const br_hash_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - unsigned char buf[64]; - uint64_t count; - uint32_t val[5]; -#endif -} br_sha1_context; - -/** - * \brief SHA-1 context initialisation. - * - * This function initialises or resets a context for a new SHA-1 - * computation. It also sets the vtable pointer. - * - * \param ctx pointer to the context structure. - */ -void br_sha1_init(br_sha1_context *ctx); - -/** - * \brief Inject some data bytes in a running SHA-1 computation. - * - * The provided context is updated with some data bytes. If the number - * of bytes (`len`) is zero, then the data pointer (`data`) is ignored - * and may be `NULL`, and this function does nothing. - * - * \param ctx pointer to the context structure. - * \param data pointer to the injected data. - * \param len injected data length (in bytes). - */ -void br_sha1_update(br_sha1_context *ctx, const void *data, size_t len); - -/** - * \brief Compute SHA-1 output. - * - * The SHA-1 output for the concatenation of all bytes injected in the - * provided context since the last initialisation or reset call, is - * computed and written in the buffer pointed to by `out`. The context - * itself is not modified, so extra bytes may be injected afterwards - * to continue that computation. - * - * \param ctx pointer to the context structure. - * \param out destination buffer for the hash output. - */ -void br_sha1_out(const br_sha1_context *ctx, void *out); - -/** - * \brief Save SHA-1 running state. - * - * The running state for SHA-1 (output of the last internal block - * processing) is written in the buffer pointed to by `out`. The - * number of bytes injected since the last initialisation or reset - * call is returned. The context is not modified. - * - * \param ctx pointer to the context structure. - * \param out destination buffer for the running state. - * \return the injected total byte length. - */ -uint64_t br_sha1_state(const br_sha1_context *ctx, void *out); - -/** - * \brief Restore SHA-1 running state. - * - * The running state for SHA-1 is set to the provided values. - * - * \param ctx pointer to the context structure. - * \param stb source buffer for the running state. - * \param count the injected total byte length. - */ -void br_sha1_set_state(br_sha1_context *ctx, const void *stb, uint64_t count); - -/** - * \brief Symbolic identifier for SHA-224. - */ -#define br_sha224_ID 3 - -/** - * \brief SHA-224 output size (in bytes). - */ -#define br_sha224_SIZE 28 - -/** - * \brief Constant vtable for SHA-224. - */ -extern const br_hash_class br_sha224_vtable; - -/** - * \brief SHA-224 context. - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** - * \brief Pointer to vtable for this context. - */ - const br_hash_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - unsigned char buf[64]; - uint64_t count; - uint32_t val[8]; -#endif -} br_sha224_context; - -/** - * \brief SHA-224 context initialisation. - * - * This function initialises or resets a context for a new SHA-224 - * computation. It also sets the vtable pointer. - * - * \param ctx pointer to the context structure. - */ -void br_sha224_init(br_sha224_context *ctx); - -/** - * \brief Inject some data bytes in a running SHA-224 computation. - * - * The provided context is updated with some data bytes. If the number - * of bytes (`len`) is zero, then the data pointer (`data`) is ignored - * and may be `NULL`, and this function does nothing. - * - * \param ctx pointer to the context structure. - * \param data pointer to the injected data. - * \param len injected data length (in bytes). - */ -void br_sha224_update(br_sha224_context *ctx, const void *data, size_t len); - -/** - * \brief Compute SHA-224 output. - * - * The SHA-224 output for the concatenation of all bytes injected in the - * provided context since the last initialisation or reset call, is - * computed and written in the buffer pointed to by `out`. The context - * itself is not modified, so extra bytes may be injected afterwards - * to continue that computation. - * - * \param ctx pointer to the context structure. - * \param out destination buffer for the hash output. - */ -void br_sha224_out(const br_sha224_context *ctx, void *out); - -/** - * \brief Save SHA-224 running state. - * - * The running state for SHA-224 (output of the last internal block - * processing) is written in the buffer pointed to by `out`. The - * number of bytes injected since the last initialisation or reset - * call is returned. The context is not modified. - * - * \param ctx pointer to the context structure. - * \param out destination buffer for the running state. - * \return the injected total byte length. - */ -uint64_t br_sha224_state(const br_sha224_context *ctx, void *out); - -/** - * \brief Restore SHA-224 running state. - * - * The running state for SHA-224 is set to the provided values. - * - * \param ctx pointer to the context structure. - * \param stb source buffer for the running state. - * \param count the injected total byte length. - */ -void br_sha224_set_state(br_sha224_context *ctx, - const void *stb, uint64_t count); - -/** - * \brief Symbolic identifier for SHA-256. - */ -#define br_sha256_ID 4 - -/** - * \brief SHA-256 output size (in bytes). - */ -#define br_sha256_SIZE 32 - -/** - * \brief Constant vtable for SHA-256. - */ -extern const br_hash_class br_sha256_vtable; - -#ifdef BR_DOXYGEN_IGNORE -/** - * \brief SHA-256 context. - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** - * \brief Pointer to vtable for this context. - */ - const br_hash_class *vtable; -} br_sha256_context; -#else -typedef br_sha224_context br_sha256_context; -#endif - -/** - * \brief SHA-256 context initialisation. - * - * This function initialises or resets a context for a new SHA-256 - * computation. It also sets the vtable pointer. - * - * \param ctx pointer to the context structure. - */ -void br_sha256_init(br_sha256_context *ctx); - -#ifdef BR_DOXYGEN_IGNORE -/** - * \brief Inject some data bytes in a running SHA-256 computation. - * - * The provided context is updated with some data bytes. If the number - * of bytes (`len`) is zero, then the data pointer (`data`) is ignored - * and may be `NULL`, and this function does nothing. - * - * \param ctx pointer to the context structure. - * \param data pointer to the injected data. - * \param len injected data length (in bytes). - */ -void br_sha256_update(br_sha256_context *ctx, const void *data, size_t len); -#else -#define br_sha256_update br_sha224_update -#endif - -/** - * \brief Compute SHA-256 output. - * - * The SHA-256 output for the concatenation of all bytes injected in the - * provided context since the last initialisation or reset call, is - * computed and written in the buffer pointed to by `out`. The context - * itself is not modified, so extra bytes may be injected afterwards - * to continue that computation. - * - * \param ctx pointer to the context structure. - * \param out destination buffer for the hash output. - */ -void br_sha256_out(const br_sha256_context *ctx, void *out); - -#if BR_DOXYGEN_IGNORE -/** - * \brief Save SHA-256 running state. - * - * The running state for SHA-256 (output of the last internal block - * processing) is written in the buffer pointed to by `out`. The - * number of bytes injected since the last initialisation or reset - * call is returned. The context is not modified. - * - * \param ctx pointer to the context structure. - * \param out destination buffer for the running state. - * \return the injected total byte length. - */ -uint64_t br_sha256_state(const br_sha256_context *ctx, void *out); -#else -#define br_sha256_state br_sha224_state -#endif - -#if BR_DOXYGEN_IGNORE -/** - * \brief Restore SHA-256 running state. - * - * The running state for SHA-256 is set to the provided values. - * - * \param ctx pointer to the context structure. - * \param stb source buffer for the running state. - * \param count the injected total byte length. - */ -void br_sha256_set_state(br_sha256_context *ctx, - const void *stb, uint64_t count); -#else -#define br_sha256_set_state br_sha224_set_state -#endif - -/** - * \brief Symbolic identifier for SHA-384. - */ -#define br_sha384_ID 5 - -/** - * \brief SHA-384 output size (in bytes). - */ -#define br_sha384_SIZE 48 - -/** - * \brief Constant vtable for SHA-384. - */ -extern const br_hash_class br_sha384_vtable; - -/** - * \brief SHA-384 context. - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** - * \brief Pointer to vtable for this context. - */ - const br_hash_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - unsigned char buf[128]; - uint64_t count; - uint64_t val[8]; -#endif -} br_sha384_context; - -/** - * \brief SHA-384 context initialisation. - * - * This function initialises or resets a context for a new SHA-384 - * computation. It also sets the vtable pointer. - * - * \param ctx pointer to the context structure. - */ -void br_sha384_init(br_sha384_context *ctx); - -/** - * \brief Inject some data bytes in a running SHA-384 computation. - * - * The provided context is updated with some data bytes. If the number - * of bytes (`len`) is zero, then the data pointer (`data`) is ignored - * and may be `NULL`, and this function does nothing. - * - * \param ctx pointer to the context structure. - * \param data pointer to the injected data. - * \param len injected data length (in bytes). - */ -void br_sha384_update(br_sha384_context *ctx, const void *data, size_t len); - -/** - * \brief Compute SHA-384 output. - * - * The SHA-384 output for the concatenation of all bytes injected in the - * provided context since the last initialisation or reset call, is - * computed and written in the buffer pointed to by `out`. The context - * itself is not modified, so extra bytes may be injected afterwards - * to continue that computation. - * - * \param ctx pointer to the context structure. - * \param out destination buffer for the hash output. - */ -void br_sha384_out(const br_sha384_context *ctx, void *out); - -/** - * \brief Save SHA-384 running state. - * - * The running state for SHA-384 (output of the last internal block - * processing) is written in the buffer pointed to by `out`. The - * number of bytes injected since the last initialisation or reset - * call is returned. The context is not modified. - * - * \param ctx pointer to the context structure. - * \param out destination buffer for the running state. - * \return the injected total byte length. - */ -uint64_t br_sha384_state(const br_sha384_context *ctx, void *out); - -/** - * \brief Restore SHA-384 running state. - * - * The running state for SHA-384 is set to the provided values. - * - * \param ctx pointer to the context structure. - * \param stb source buffer for the running state. - * \param count the injected total byte length. - */ -void br_sha384_set_state(br_sha384_context *ctx, - const void *stb, uint64_t count); - -/** - * \brief Symbolic identifier for SHA-512. - */ -#define br_sha512_ID 6 - -/** - * \brief SHA-512 output size (in bytes). - */ -#define br_sha512_SIZE 64 - -/** - * \brief Constant vtable for SHA-512. - */ -extern const br_hash_class br_sha512_vtable; - -#ifdef BR_DOXYGEN_IGNORE -/** - * \brief SHA-512 context. - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** - * \brief Pointer to vtable for this context. - */ - const br_hash_class *vtable; -} br_sha512_context; -#else -typedef br_sha384_context br_sha512_context; -#endif - -/** - * \brief SHA-512 context initialisation. - * - * This function initialises or resets a context for a new SHA-512 - * computation. It also sets the vtable pointer. - * - * \param ctx pointer to the context structure. - */ -void br_sha512_init(br_sha512_context *ctx); - -#ifdef BR_DOXYGEN_IGNORE -/** - * \brief Inject some data bytes in a running SHA-512 computation. - * - * The provided context is updated with some data bytes. If the number - * of bytes (`len`) is zero, then the data pointer (`data`) is ignored - * and may be `NULL`, and this function does nothing. - * - * \param ctx pointer to the context structure. - * \param data pointer to the injected data. - * \param len injected data length (in bytes). - */ -void br_sha512_update(br_sha512_context *ctx, const void *data, size_t len); -#else -#define br_sha512_update br_sha384_update -#endif - -/** - * \brief Compute SHA-512 output. - * - * The SHA-512 output for the concatenation of all bytes injected in the - * provided context since the last initialisation or reset call, is - * computed and written in the buffer pointed to by `out`. The context - * itself is not modified, so extra bytes may be injected afterwards - * to continue that computation. - * - * \param ctx pointer to the context structure. - * \param out destination buffer for the hash output. - */ -void br_sha512_out(const br_sha512_context *ctx, void *out); - -#ifdef BR_DOXYGEN_IGNORE -/** - * \brief Save SHA-512 running state. - * - * The running state for SHA-512 (output of the last internal block - * processing) is written in the buffer pointed to by `out`. The - * number of bytes injected since the last initialisation or reset - * call is returned. The context is not modified. - * - * \param ctx pointer to the context structure. - * \param out destination buffer for the running state. - * \return the injected total byte length. - */ -uint64_t br_sha512_state(const br_sha512_context *ctx, void *out); -#else -#define br_sha512_state br_sha384_state -#endif - -#ifdef BR_DOXYGEN_IGNORE -/** - * \brief Restore SHA-512 running state. - * - * The running state for SHA-512 is set to the provided values. - * - * \param ctx pointer to the context structure. - * \param stb source buffer for the running state. - * \param count the injected total byte length. - */ -void br_sha512_set_state(br_sha512_context *ctx, - const void *stb, uint64_t count); -#else -#define br_sha512_set_state br_sha384_set_state -#endif - -/* - * "md5sha1" is a special hash function that computes both MD5 and SHA-1 - * on the same input, and produces a 36-byte output (MD5 and SHA-1 - * concatenation, in that order). State size is also 36 bytes. - */ - -/** - * \brief Symbolic identifier for MD5+SHA-1. - * - * MD5+SHA-1 is the concatenation of MD5 and SHA-1, computed over the - * same input. It is not one of the functions identified in TLS, so - * we give it a symbolic identifier of value 0. - */ -#define br_md5sha1_ID 0 - -/** - * \brief MD5+SHA-1 output size (in bytes). - */ -#define br_md5sha1_SIZE 36 - -/** - * \brief Constant vtable for MD5+SHA-1. - */ -extern const br_hash_class br_md5sha1_vtable; - -/** - * \brief MD5+SHA-1 context. - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** - * \brief Pointer to vtable for this context. - */ - const br_hash_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - unsigned char buf[64]; - uint64_t count; - uint32_t val_md5[4]; - uint32_t val_sha1[5]; -#endif -} br_md5sha1_context; - -/** - * \brief MD5+SHA-1 context initialisation. - * - * This function initialises or resets a context for a new SHA-512 - * computation. It also sets the vtable pointer. - * - * \param ctx pointer to the context structure. - */ -void br_md5sha1_init(br_md5sha1_context *ctx); - -/** - * \brief Inject some data bytes in a running MD5+SHA-1 computation. - * - * The provided context is updated with some data bytes. If the number - * of bytes (`len`) is zero, then the data pointer (`data`) is ignored - * and may be `NULL`, and this function does nothing. - * - * \param ctx pointer to the context structure. - * \param data pointer to the injected data. - * \param len injected data length (in bytes). - */ -void br_md5sha1_update(br_md5sha1_context *ctx, const void *data, size_t len); - -/** - * \brief Compute MD5+SHA-1 output. - * - * The MD5+SHA-1 output for the concatenation of all bytes injected in the - * provided context since the last initialisation or reset call, is - * computed and written in the buffer pointed to by `out`. The context - * itself is not modified, so extra bytes may be injected afterwards - * to continue that computation. - * - * \param ctx pointer to the context structure. - * \param out destination buffer for the hash output. - */ -void br_md5sha1_out(const br_md5sha1_context *ctx, void *out); - -/** - * \brief Save MD5+SHA-1 running state. - * - * The running state for MD5+SHA-1 (output of the last internal block - * processing) is written in the buffer pointed to by `out`. The - * number of bytes injected since the last initialisation or reset - * call is returned. The context is not modified. - * - * \param ctx pointer to the context structure. - * \param out destination buffer for the running state. - * \return the injected total byte length. - */ -uint64_t br_md5sha1_state(const br_md5sha1_context *ctx, void *out); - -/** - * \brief Restore MD5+SHA-1 running state. - * - * The running state for MD5+SHA-1 is set to the provided values. - * - * \param ctx pointer to the context structure. - * \param stb source buffer for the running state. - * \param count the injected total byte length. - */ -void br_md5sha1_set_state(br_md5sha1_context *ctx, - const void *stb, uint64_t count); - -/** - * \brief Aggregate context for configurable hash function support. - * - * The `br_hash_compat_context` type is a type which is large enough to - * serve as context for all standard hash functions defined above. - */ -typedef union { - const br_hash_class *vtable; - br_md5_context md5; - br_sha1_context sha1; - br_sha224_context sha224; - br_sha256_context sha256; - br_sha384_context sha384; - br_sha512_context sha512; - br_md5sha1_context md5sha1; -} br_hash_compat_context; - -/* - * The multi-hasher is a construct that handles hashing of the same input - * data with several hash functions, with a single shared input buffer. - * It can handle MD5, SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512 - * simultaneously, though which functions are activated depends on - * the set implementation pointers. - */ - -/** - * \brief Multi-hasher context structure. - * - * The multi-hasher runs up to six hash functions in the standard TLS list - * (MD5, SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512) in parallel, over - * the same input. - * - * The multi-hasher does _not_ follow the OOP structure with a vtable. - * Instead, it is configured with the vtables of the hash functions it - * should run. Structure fields are not supposed to be accessed directly. - */ -typedef struct { -#ifndef BR_DOXYGEN_IGNORE - unsigned char buf[128]; - uint64_t count; - uint32_t val_32[25]; - uint64_t val_64[16]; - const br_hash_class *impl[6]; -#endif -} br_multihash_context; - -/** - * \brief Clear a multi-hasher context. - * - * This should always be called once on a given context, _before_ setting - * the implementation pointers. - * - * \param ctx the multi-hasher context. - */ -void br_multihash_zero(br_multihash_context *ctx); - -/** - * \brief Set a hash function implementation. - * - * Implementations shall be set _after_ clearing the context (with - * `br_multihash_zero()`) but _before_ initialising the computation - * (with `br_multihash_init()`). The hash function implementation - * MUST be one of the standard hash functions (MD5, SHA-1, SHA-224, - * SHA-256, SHA-384 or SHA-512); it may also be `NULL` to remove - * an implementation from the multi-hasher. - * - * \param ctx the multi-hasher context. - * \param id the hash function symbolic identifier. - * \param impl the hash function vtable, or `NULL`. - */ -static inline void -br_multihash_setimpl(br_multihash_context *ctx, - int id, const br_hash_class *impl) -{ - /* - * This code relies on hash functions ID being values 1 to 6, - * in the MD5 to SHA-512 order. - */ - ctx->impl[id - 1] = impl; -} - -/** - * \brief Get a hash function implementation. - * - * This function returns the currently configured vtable for a given - * hash function (by symbolic ID). If no such function was configured in - * the provided multi-hasher context, then this function returns `NULL`. - * - * \param ctx the multi-hasher context. - * \param id the hash function symbolic identifier. - * \return the hash function vtable, or `NULL`. - */ -static inline const br_hash_class * -br_multihash_getimpl(const br_multihash_context *ctx, int id) -{ - return ctx->impl[id - 1]; -} - -/** - * \brief Reset a multi-hasher context. - * - * This function prepares the context for a new hashing computation, - * for all implementations configured at that point. - * - * \param ctx the multi-hasher context. - */ -void br_multihash_init(br_multihash_context *ctx); - -/** - * \brief Inject some data bytes in a running multi-hashing computation. - * - * The provided context is updated with some data bytes. If the number - * of bytes (`len`) is zero, then the data pointer (`data`) is ignored - * and may be `NULL`, and this function does nothing. - * - * \param ctx pointer to the context structure. - * \param data pointer to the injected data. - * \param len injected data length (in bytes). - */ -void br_multihash_update(br_multihash_context *ctx, - const void *data, size_t len); - -/** - * \brief Compute a hash output from a multi-hasher. - * - * The hash output for the concatenation of all bytes injected in the - * provided context since the last initialisation or reset call, is - * computed and written in the buffer pointed to by `dst`. The hash - * function to use is identified by `id` and must be one of the standard - * hash functions. If that hash function was indeed configured in the - * multi-hasher context, the corresponding hash value is written in - * `dst` and its length (in bytes) is returned. If the hash function - * was _not_ configured, then nothing is written in `dst` and 0 is - * returned. - * - * The context itself is not modified, so extra bytes may be injected - * afterwards to continue the hash computations. - * - * \param ctx pointer to the context structure. - * \param id the hash function symbolic identifier. - * \param dst destination buffer for the hash output. - * \return the hash output length (in bytes), or 0. - */ -size_t br_multihash_out(const br_multihash_context *ctx, int id, void *dst); - -/** - * \brief Type for a GHASH implementation. - * - * GHASH is a sort of keyed hash meant to be used to implement GCM in - * combination with a block cipher (with 16-byte blocks). - * - * The `y` array has length 16 bytes and is used for input and output; in - * a complete GHASH run, it starts with an all-zero value. `h` is a 16-byte - * value that serves as key (it is derived from the encryption key in GCM, - * using the block cipher). The data length (`len`) is expressed in bytes. - * The `y` array is updated. - * - * If the data length is not a multiple of 16, then the data is implicitly - * padded with zeros up to the next multiple of 16. Thus, when using GHASH - * in GCM, this method may be called twice, for the associated data and - * for the ciphertext, respectively; the zero-padding implements exactly - * the GCM rules. - * - * \param y the array to update. - * \param h the GHASH key. - * \param data the input data (may be `NULL` if `len` is zero). - * \param len the input data length (in bytes). - */ -typedef void (*br_ghash)(void *y, const void *h, const void *data, size_t len); - -/** - * \brief GHASH implementation using multiplications (mixed 32-bit). - * - * This implementation uses multiplications of 32-bit values, with a - * 64-bit result. It is constant-time (if multiplications are - * constant-time). - * - * \param y the array to update. - * \param h the GHASH key. - * \param data the input data (may be `NULL` if `len` is zero). - * \param len the input data length (in bytes). - */ -void br_ghash_ctmul(void *y, const void *h, const void *data, size_t len); - -/** - * \brief GHASH implementation using multiplications (strict 32-bit). - * - * This implementation uses multiplications of 32-bit values, with a - * 32-bit result. It is usually somewhat slower than `br_ghash_ctmul()`, - * but it is expected to be faster on architectures for which the - * 32-bit multiplication opcode does not yield the upper 32 bits of the - * product. It is constant-time (if multiplications are constant-time). - * - * \param y the array to update. - * \param h the GHASH key. - * \param data the input data (may be `NULL` if `len` is zero). - * \param len the input data length (in bytes). - */ -void br_ghash_ctmul32(void *y, const void *h, const void *data, size_t len); - -/** - * \brief GHASH implementation using multiplications (64-bit). - * - * This implementation uses multiplications of 64-bit values, with a - * 64-bit result. It is constant-time (if multiplications are - * constant-time). It is substantially faster than `br_ghash_ctmul()` - * and `br_ghash_ctmul32()` on most 64-bit architectures. - * - * \param y the array to update. - * \param h the GHASH key. - * \param data the input data (may be `NULL` if `len` is zero). - * \param len the input data length (in bytes). - */ -void br_ghash_ctmul64(void *y, const void *h, const void *data, size_t len); - -/** - * \brief GHASH implementation using the `pclmulqdq` opcode (part of the - * AES-NI instructions). - * - * This implementation is available only on x86 platforms where the - * compiler supports the relevant intrinsic functions. Even if the - * compiler supports these functions, the local CPU might not support - * the `pclmulqdq` opcode, meaning that a call will fail with an - * illegal instruction exception. To safely obtain a pointer to this - * function when supported (or 0 otherwise), use `br_ghash_pclmul_get()`. - * - * \param y the array to update. - * \param h the GHASH key. - * \param data the input data (may be `NULL` if `len` is zero). - * \param len the input data length (in bytes). - */ -void br_ghash_pclmul(void *y, const void *h, const void *data, size_t len); - -/** - * \brief Obtain the `pclmul` GHASH implementation, if available. - * - * If the `pclmul` implementation was compiled in the library (depending - * on the compiler abilities) _and_ the local CPU appears to support the - * opcode, then this function will return a pointer to the - * `br_ghash_pclmul()` function. Otherwise, it will return `0`. - * - * \return the `pclmul` GHASH implementation, or `0`. - */ -br_ghash br_ghash_pclmul_get(void); - -/** - * \brief GHASH implementation using the POWER8 opcodes. - * - * This implementation is available only on POWER8 platforms (and later). - * To safely obtain a pointer to this function when supported (or 0 - * otherwise), use `br_ghash_pwr8_get()`. - * - * \param y the array to update. - * \param h the GHASH key. - * \param data the input data (may be `NULL` if `len` is zero). - * \param len the input data length (in bytes). - */ -void br_ghash_pwr8(void *y, const void *h, const void *data, size_t len); - -/** - * \brief Obtain the `pwr8` GHASH implementation, if available. - * - * If the `pwr8` implementation was compiled in the library (depending - * on the compiler abilities) _and_ the local CPU appears to support the - * opcode, then this function will return a pointer to the - * `br_ghash_pwr8()` function. Otherwise, it will return `0`. - * - * \return the `pwr8` GHASH implementation, or `0`. - */ -br_ghash br_ghash_pwr8_get(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/tls/bearssl/bearssl_hmac.h b/src/tls/bearssl/bearssl_hmac.h deleted file mode 100644 index 4dc01ca31..000000000 --- a/src/tls/bearssl/bearssl_hmac.h +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef BR_BEARSSL_HMAC_H__ -#define BR_BEARSSL_HMAC_H__ - -#include -#include - -#include "bearssl_hash.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** \file bearssl_hmac.h - * - * # HMAC - * - * HMAC is initialized with a key and an underlying hash function; it - * then fills a "key context". That context contains the processed - * key. - * - * With the key context, a HMAC context can be initialized to process - * the input bytes and obtain the MAC output. The key context is not - * modified during that process, and can be reused. - * - * IMPORTANT: HMAC shall be used only with functions that have the - * following properties: - * - * - hash output size does not exceed 64 bytes; - * - hash internal state size does not exceed 64 bytes; - * - internal block length is a power of 2 between 16 and 256 bytes. - */ - -/** - * \brief HMAC key context. - * - * The HMAC key context is initialised with a hash function implementation - * and a secret key. Contents are opaque (callers should not access them - * directly). The caller is responsible for allocating the context where - * appropriate. Context initialisation and usage incurs no dynamic - * allocation, so there is no release function. - */ -typedef struct { -#ifndef BR_DOXYGEN_IGNORE - const br_hash_class *dig_vtable; - unsigned char ksi[64], kso[64]; -#endif -} br_hmac_key_context; - -/** - * \brief HMAC key context initialisation. - * - * Initialise the key context with the provided key, using the hash function - * identified by `digest_vtable`. This supports arbitrary key lengths. - * - * \param kc HMAC key context to initialise. - * \param digest_vtable pointer to the hash function implementation vtable. - * \param key pointer to the HMAC secret key. - * \param key_len HMAC secret key length (in bytes). - */ -void br_hmac_key_init(br_hmac_key_context *kc, - const br_hash_class *digest_vtable, const void *key, size_t key_len); - -/* - * \brief Get the underlying hash function. - * - * This function returns a pointer to the implementation vtable of the - * hash function used for this HMAC key context. - * - * \param kc HMAC key context. - * \return the hash function implementation. - */ -static inline const br_hash_class *br_hmac_key_get_digest( - const br_hmac_key_context *kc) -{ - return kc->dig_vtable; -} - -/** - * \brief HMAC computation context. - * - * The HMAC computation context maintains the state for a single HMAC - * computation. It is modified as input bytes are injected. The context - * is caller-allocated and has no release function since it does not - * dynamically allocate external resources. Its contents are opaque. - */ -typedef struct { -#ifndef BR_DOXYGEN_IGNORE - br_hash_compat_context dig; - unsigned char kso[64]; - size_t out_len; -#endif -} br_hmac_context; - -/** - * \brief HMAC computation initialisation. - * - * Initialise a HMAC context with a key context. The key context is - * unmodified. Relevant data from the key context is immediately copied; - * the key context can thus be independently reused, modified or released - * without impacting this HMAC computation. - * - * An explicit output length can be specified; the actual output length - * will be the minimum of that value and the natural HMAC output length. - * If `out_len` is 0, then the natural HMAC output length is selected. The - * "natural output length" is the output length of the underlying hash - * function. - * - * \param ctx HMAC context to initialise. - * \param kc HMAC key context (already initialised with the key). - * \param out_len HMAC output length (0 to select "natural length"). - */ -void br_hmac_init(br_hmac_context *ctx, - const br_hmac_key_context *kc, size_t out_len); - -/** - * \brief Get the HMAC output size. - * - * The HMAC output size is the number of bytes that will actually be - * produced with `br_hmac_out()` with the provided context. This function - * MUST NOT be called on a non-initialised HMAC computation context. - * The returned value is the minimum of the HMAC natural length (output - * size of the underlying hash function) and the `out_len` parameter which - * was used with the last `br_hmac_init()` call on that context (if the - * initialisation `out_len` parameter was 0, then this function will - * return the HMAC natural length). - * - * \param ctx the (already initialised) HMAC computation context. - * \return the HMAC actual output size. - */ -static inline size_t -br_hmac_size(br_hmac_context *ctx) -{ - return ctx->out_len; -} - -/* - * \brief Get the underlying hash function. - * - * This function returns a pointer to the implementation vtable of the - * hash function used for this HMAC context. - * - * \param hc HMAC context. - * \return the hash function implementation. - */ -static inline const br_hash_class *br_hmac_get_digest( - const br_hmac_context *hc) -{ - return hc->dig.vtable; -} - -/** - * \brief Inject some bytes in HMAC. - * - * The provided `len` bytes are injected as extra input in the HMAC - * computation incarnated by the `ctx` HMAC context. It is acceptable - * that `len` is zero, in which case `data` is ignored (and may be - * `NULL`) and this function does nothing. - */ -void br_hmac_update(br_hmac_context *ctx, const void *data, size_t len); - -/** - * \brief Compute the HMAC output. - * - * The destination buffer MUST be large enough to accommodate the result; - * its length is at most the "natural length" of HMAC (i.e. the output - * length of the underlying hash function). The context is NOT modified; - * further bytes may be processed. Thus, "partial HMAC" values can be - * efficiently obtained. - * - * Returned value is the output length (in bytes). - * - * \param ctx HMAC computation context. - * \param out destination buffer for the HMAC output. - * \return the produced value length (in bytes). - */ -size_t br_hmac_out(const br_hmac_context *ctx, void *out); - -/** - * \brief Constant-time HMAC computation. - * - * This function compute the HMAC output in constant time. Some extra - * input bytes are processed, then the output is computed. The extra - * input consists in the `len` bytes pointed to by `data`. The `len` - * parameter must lie between `min_len` and `max_len` (inclusive); - * `max_len` bytes are actually read from `data`. Computing time (and - * memory access pattern) will not depend upon the data byte contents or - * the value of `len`. - * - * The output is written in the `out` buffer, that MUST be large enough - * to receive it. - * - * The difference `max_len - min_len` MUST be less than 230 - * (i.e. about one gigabyte). - * - * This function computes the output properly only if the underlying - * hash function uses MD padding (i.e. MD5, SHA-1, SHA-224, SHA-256, - * SHA-384 or SHA-512). - * - * The provided context is NOT modified. - * - * \param ctx the (already initialised) HMAC computation context. - * \param data the extra input bytes. - * \param len the extra input length (in bytes). - * \param min_len minimum extra input length (in bytes). - * \param max_len maximum extra input length (in bytes). - * \param out destination buffer for the HMAC output. - * \return the produced value length (in bytes). - */ -size_t br_hmac_outCT(const br_hmac_context *ctx, - const void *data, size_t len, size_t min_len, size_t max_len, - void *out); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/tls/bearssl/bearssl_kdf.h b/src/tls/bearssl/bearssl_kdf.h deleted file mode 100644 index f018d7e8a..000000000 --- a/src/tls/bearssl/bearssl_kdf.h +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef BR_BEARSSL_KDF_H__ -#define BR_BEARSSL_KDF_H__ - -#include -#include - -#include "bearssl_hash.h" -#include "bearssl_hmac.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** \file bearssl_kdf.h - * - * # Key Derivation Functions - * - * KDF are functions that takes a variable length input, and provide a - * variable length output, meant to be used to derive subkeys from a - * master key. - * - * ## HKDF - * - * HKDF is a KDF defined by [RFC 5869](https://tools.ietf.org/html/rfc5869). - * It is based on HMAC, itself using an underlying hash function. Any - * hash function can be used, as long as it is compatible with the rules - * for the HMAC implementation (i.e. output size is 64 bytes or less, hash - * internal state size is 64 bytes or less, and the internal block length is - * a power of 2 between 16 and 256 bytes). HKDF has two phases: - * - * - HKDF-Extract: the input data in ingested, along with a "salt" value. - * - * - HKDF-Expand: the output is produced, from the result of processing - * the input and salt, and using an extra non-secret parameter called - * "info". - * - * The "salt" and "info" strings are non-secret and can be empty. Their role - * is normally to bind the input and output, respectively, to conventional - * identifiers that qualifu them within the used protocol or application. - * - * The implementation defined in this file uses the following functions: - * - * - `br_hkdf_init()`: initialize an HKDF context, with a hash function, - * and the salt. This starts the HKDF-Extract process. - * - * - `br_hkdf_inject()`: inject more input bytes. This function may be - * called repeatedly if the input data is provided by chunks. - * - * - `br_hkdf_flip()`: end the HKDF-Extract process, and start the - * HKDF-Expand process. - * - * - `br_hkdf_produce()`: get the next bytes of output. This function - * may be called several times to obtain the full output by chunks. - * For correct HKDF processing, the same "info" string must be - * provided for each call. - * - * Note that the HKDF total output size (the number of bytes that - * HKDF-Expand is willing to produce) is limited: if the hash output size - * is _n_ bytes, then the maximum output size is _255*n_. - */ - -/** - * \brief HKDF context. - * - * The HKDF context is initialized with a hash function implementation - * and a salt value. Contents are opaque (callers should not access them - * directly). The caller is responsible for allocating the context where - * appropriate. Context initialisation and usage incurs no dynamic - * allocation, so there is no release function. - */ -typedef struct { -#ifndef BR_DOXYGEN_IGNORE - union { - br_hmac_context hmac_ctx; - br_hmac_key_context prk_ctx; - } u; - unsigned char buf[64]; - size_t ptr; - size_t dig_len; - unsigned chunk_num; -#endif -} br_hkdf_context; - -/** - * \brief HKDF context initialization. - * - * The underlying hash function and salt value are provided. Arbitrary - * salt lengths can be used. - * - * HKDF makes a difference between a salt of length zero, and an - * absent salt (the latter being equivalent to a salt consisting of - * bytes of value zero, of the same length as the hash function output). - * If `salt_len` is zero, then this function assumes that the salt is - * present but of length zero. To specify an _absent_ salt, use - * `BR_HKDF_NO_SALT` as `salt` parameter (`salt_len` is then ignored). - * - * \param hc HKDF context to initialise. - * \param digest_vtable pointer to the hash function implementation vtable. - * \param salt HKDF-Extract salt. - * \param salt_len HKDF-Extract salt length (in bytes). - */ -void br_hkdf_init(br_hkdf_context *hc, const br_hash_class *digest_vtable, - const void *salt, size_t salt_len); - -/** - * \brief The special "absent salt" value for HKDF. - */ -#define BR_HKDF_NO_SALT (&br_hkdf_no_salt) - -#ifndef BR_DOXYGEN_IGNORE -extern const unsigned char br_hkdf_no_salt; -#endif - -/** - * \brief HKDF input injection (HKDF-Extract). - * - * This function injects some more input bytes ("key material") into - * HKDF. This function may be called several times, after `br_hkdf_init()` - * but before `br_hkdf_flip()`. - * - * \param hc HKDF context. - * \param ikm extra input bytes. - * \param ikm_len number of extra input bytes. - */ -void br_hkdf_inject(br_hkdf_context *hc, const void *ikm, size_t ikm_len); - -/** - * \brief HKDF switch to the HKDF-Expand phase. - * - * This call terminates the HKDF-Extract process (input injection), and - * starts the HKDF-Expand process (output production). - * - * \param hc HKDF context. - */ -void br_hkdf_flip(br_hkdf_context *hc); - -/** - * \brief HKDF output production (HKDF-Expand). - * - * Produce more output bytes from the current state. This function may be - * called several times, but only after `br_hkdf_flip()`. - * - * Returned value is the number of actually produced bytes. The total - * output length is limited to 255 times the output length of the - * underlying hash function. - * - * \param hc HKDF context. - * \param info application specific information string. - * \param info_len application specific information string length (in bytes). - * \param out destination buffer for the HKDF output. - * \param out_len the length of the requested output (in bytes). - * \return the produced output length (in bytes). - */ -size_t br_hkdf_produce(br_hkdf_context *hc, - const void *info, size_t info_len, void *out, size_t out_len); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/tls/bearssl/bearssl_pem.h b/src/tls/bearssl/bearssl_pem.h deleted file mode 100644 index 8dba58272..000000000 --- a/src/tls/bearssl/bearssl_pem.h +++ /dev/null @@ -1,294 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef BR_BEARSSL_PEM_H__ -#define BR_BEARSSL_PEM_H__ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** \file bearssl_pem.h - * - * # PEM Support - * - * PEM is a traditional encoding layer use to store binary objects (in - * particular X.509 certificates, and private keys) in text files. While - * the acronym comes from an old, defunct standard ("Privacy Enhanced - * Mail"), the format has been reused, with some variations, by many - * systems, and is a _de facto_ standard, even though it is not, actually, - * specified in all clarity anywhere. - * - * ## Format Details - * - * BearSSL contains a generic, streamed PEM decoder, which handles the - * following format: - * - * - The input source (a sequence of bytes) is assumed to be the - * encoding of a text file in an ASCII-compatible charset. This - * includes ISO-8859-1, Windows-1252, and UTF-8 encodings. Each - * line ends on a newline character (U+000A LINE FEED). The - * U+000D CARRIAGE RETURN characters are ignored, so the code - * accepts both Windows-style and Unix-style line endings. - * - * - Each object begins with a banner that occurs at the start of - * a line; the first banner characters are "`-----BEGIN `" (five - * dashes, the word "BEGIN", and a space). The banner matching is - * not case-sensitive. - * - * - The _object name_ consists in the characters that follow the - * banner start sequence, up to the end of the line, but without - * trailing dashes (in "normal" PEM, there are five trailing - * dashes, but this implementation is not picky about these dashes). - * The BearSSL decoder normalises the name characters to uppercase - * (for ASCII letters only) and accepts names up to 127 characters. - * - * - The object ends with a banner that again occurs at the start of - * a line, and starts with "`-----END `" (again case-insensitive). - * - * - Between that start and end banner, only Base64 data shall occur. - * Base64 converts each sequence of three bytes into four - * characters; the four characters are ASCII letters, digits, "`+`" - * or "`-`" signs, and one or two "`=`" signs may occur in the last - * quartet. Whitespace is ignored (whitespace is any ASCII character - * of code 32 or less, so control characters are whitespace) and - * lines may have arbitrary length; the only restriction is that the - * four characters of a quartet must appear on the same line (no - * line break inside a quartet). - * - * - A single file may contain more than one PEM object. Bytes that - * occur between objects are ignored. - * - * - * ## PEM Decoder API - * - * The PEM decoder offers a state-machine API. The caller allocates a - * decoder context, then injects source bytes. Source bytes are pushed - * with `br_pem_decoder_push()`. The decoder stops accepting bytes when - * it reaches an "event", which is either the start of an object, the - * end of an object, or a decoding error within an object. - * - * The `br_pem_decoder_event()` function is used to obtain the current - * event; it also clears it, thus allowing the decoder to accept more - * bytes. When a object start event is raised, the decoder context - * offers the found object name (normalised to ASCII uppercase). - * - * When an object is reached, the caller must set an appropriate callback - * function, which will receive (by chunks) the decoded object data. - * - * Since the decoder context makes no dynamic allocation, it requires - * no explicit deallocation. - */ - -/** - * \brief PEM decoder context. - * - * Contents are opaque (they should not be accessed directly). - */ -typedef struct { -#ifndef BR_DOXYGEN_IGNORE - /* CPU for the T0 virtual machine. */ - struct { - uint32_t *dp; - uint32_t *rp; - const unsigned char *ip; - } cpu; - uint32_t dp_stack[32]; - uint32_t rp_stack[32]; - int err; - - const unsigned char *hbuf; - size_t hlen; - - void (*dest)(void *dest_ctx, const void *src, size_t len); - void *dest_ctx; - - unsigned char event; - char name[128]; - unsigned char buf[255]; - size_t ptr; -#endif -} br_pem_decoder_context; - -/** - * \brief Initialise a PEM decoder structure. - * - * \param ctx decoder context to initialise. - */ -void br_pem_decoder_init(br_pem_decoder_context *ctx); - -/** - * \brief Push some bytes into the decoder. - * - * Returned value is the number of bytes actually consumed; this may be - * less than the number of provided bytes if an event is raised. When an - * event is raised, it must be read (with `br_pem_decoder_event()`); - * until the event is read, this function will return 0. - * - * \param ctx decoder context. - * \param data new data bytes. - * \param len number of new data bytes. - * \return the number of bytes actually received (may be less than `len`). - */ -size_t br_pem_decoder_push(br_pem_decoder_context *ctx, - const void *data, size_t len); - -/** - * \brief Set the receiver for decoded data. - * - * When an object is entered, the provided function (with opaque context - * pointer) will be called repeatedly with successive chunks of decoded - * data for that object. If `dest` is set to 0, then decoded data is - * simply ignored. The receiver can be set at any time, but, in practice, - * it should be called immediately after receiving a "start of object" - * event. - * - * \param ctx decoder context. - * \param dest callback for receiving decoded data. - * \param dest_ctx opaque context pointer for the `dest` callback. - */ -static inline void -br_pem_decoder_setdest(br_pem_decoder_context *ctx, - void (*dest)(void *dest_ctx, const void *src, size_t len), - void *dest_ctx) -{ - ctx->dest = dest; - ctx->dest_ctx = dest_ctx; -} - -/** - * \brief Get the last event. - * - * If an event was raised, then this function returns the event value, and - * also clears it, thereby allowing the decoder to proceed. If no event - * was raised since the last call to `br_pem_decoder_event()`, then this - * function returns 0. - * - * \param ctx decoder context. - * \return the raised event, or 0. - */ -int br_pem_decoder_event(br_pem_decoder_context *ctx); - -/** - * \brief Event: start of object. - * - * This event is raised when the start of a new object has been detected. - * The object name (normalised to uppercase) can be accessed with - * `br_pem_decoder_name()`. - */ -#define BR_PEM_BEGIN_OBJ 1 - -/** - * \brief Event: end of object. - * - * This event is raised when the end of the current object is reached - * (normally, i.e. with no decoding error). - */ -#define BR_PEM_END_OBJ 2 - -/** - * \brief Event: decoding error. - * - * This event is raised when decoding fails within an object. - * This formally closes the current object and brings the decoder back - * to the "out of any object" state. The offending line in the source - * is consumed. - */ -#define BR_PEM_ERROR 3 - -/** - * \brief Get the name of the encountered object. - * - * The encountered object name is defined only when the "start of object" - * event is raised. That name is normalised to uppercase (for ASCII letters - * only) and does not include trailing dashes. - * - * \param ctx decoder context. - * \return the current object name. - */ -static inline const char * -br_pem_decoder_name(br_pem_decoder_context *ctx) -{ - return ctx->name; -} - -/** - * \brief Encode an object in PEM. - * - * This function encodes the provided binary object (`data`, of length `len` - * bytes) into PEM. The `banner` text will be included in the header and - * footer (e.g. use `"CERTIFICATE"` to get a `"BEGIN CERTIFICATE"` header). - * - * The length (in characters) of the PEM output is returned; that length - * does NOT include the terminating zero, that this function nevertheless - * adds. If using the returned value for allocation purposes, the allocated - * buffer size MUST be at least one byte larger than the returned size. - * - * If `dest` is `NULL`, then the encoding does not happen; however, the - * length of the encoded object is still computed and returned. - * - * The `data` pointer may be `NULL` only if `len` is zero (when encoding - * an object of length zero, which is not very useful), or when `dest` - * is `NULL` (in that case, source data bytes are ignored). - * - * Some `flags` can be specified to alter the encoding behaviour: - * - * - If `BR_PEM_LINE64` is set, then line-breaking will occur after - * every 64 characters of output, instead of the default of 76. - * - * - If `BR_PEM_CRLF` is set, then end-of-line sequence will use - * CR+LF instead of a single LF. - * - * The `data` and `dest` buffers may overlap, in which case the source - * binary data is destroyed in the process. Note that the PEM-encoded output - * is always larger than the source binary. - * - * \param dest the destination buffer (or `NULL`). - * \param data the source buffer (can be `NULL` in some cases). - * \param len the source length (in bytes). - * \param banner the PEM banner expression. - * \param flags the behavioural flags. - * \return the PEM object length (in characters), EXCLUDING the final zero. - */ -size_t br_pem_encode(void *dest, const void *data, size_t len, - const char *banner, unsigned flags); - -/** - * \brief PEM encoding flag: split lines at 64 characters. - */ -#define BR_PEM_LINE64 0x0001 - -/** - * \brief PEM encoding flag: use CR+LF line endings. - */ -#define BR_PEM_CRLF 0x0002 - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/tls/bearssl/bearssl_prf.h b/src/tls/bearssl/bearssl_prf.h deleted file mode 100644 index fdf608c85..000000000 --- a/src/tls/bearssl/bearssl_prf.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef BR_BEARSSL_PRF_H__ -#define BR_BEARSSL_PRF_H__ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** \file bearssl_prf.h - * - * # The TLS PRF - * - * The "PRF" is the pseudorandom function used internally during the - * SSL/TLS handshake, notably to expand negotiated shared secrets into - * the symmetric encryption keys that will be used to process the - * application data. - * - * TLS 1.0 and 1.1 define a PRF that is based on both MD5 and SHA-1. This - * is implemented by the `br_tls10_prf()` function. - * - * TLS 1.2 redefines the PRF, using an explicit hash function. The - * `br_tls12_sha256_prf()` and `br_tls12_sha384_prf()` functions apply that - * PRF with, respectively, SHA-256 and SHA-384. Most standard cipher suites - * rely on the SHA-256 based PRF, but some use SHA-384. - * - * The PRF always uses as input three parameters: a "secret" (some - * bytes), a "label" (ASCII string), and a "seed" (again some bytes). An - * arbitrary output length can be produced. The "seed" is provided as an - * arbitrary number of binary chunks, that gets internally concatenated. - */ - -/** - * \brief Type for a seed chunk. - * - * Each chunk may have an arbitrary length, and may be empty (no byte at - * all). If the chunk length is zero, then the pointer to the chunk data - * may be `NULL`. - */ -typedef struct { - /** - * \brief Pointer to the chunk data. - */ - const void *data; - - /** - * \brief Chunk length (in bytes). - */ - size_t len; -} br_tls_prf_seed_chunk; - -/** - * \brief PRF implementation for TLS 1.0 and 1.1. - * - * This PRF is the one specified by TLS 1.0 and 1.1. It internally uses - * MD5 and SHA-1. - * - * \param dst destination buffer. - * \param len output length (in bytes). - * \param secret secret value (key) for this computation. - * \param secret_len length of "secret" (in bytes). - * \param label PRF label (zero-terminated ASCII string). - * \param seed_num number of seed chunks. - * \param seed seed chnks for this computation (usually non-secret). - */ -void br_tls10_prf(void *dst, size_t len, - const void *secret, size_t secret_len, const char *label, - size_t seed_num, const br_tls_prf_seed_chunk *seed); - -/** - * \brief PRF implementation for TLS 1.2, with SHA-256. - * - * This PRF is the one specified by TLS 1.2, when the underlying hash - * function is SHA-256. - * - * \param dst destination buffer. - * \param len output length (in bytes). - * \param secret secret value (key) for this computation. - * \param secret_len length of "secret" (in bytes). - * \param label PRF label (zero-terminated ASCII string). - * \param seed_num number of seed chunks. - * \param seed seed chnks for this computation (usually non-secret). - */ -void br_tls12_sha256_prf(void *dst, size_t len, - const void *secret, size_t secret_len, const char *label, - size_t seed_num, const br_tls_prf_seed_chunk *seed); - -/** - * \brief PRF implementation for TLS 1.2, with SHA-384. - * - * This PRF is the one specified by TLS 1.2, when the underlying hash - * function is SHA-384. - * - * \param dst destination buffer. - * \param len output length (in bytes). - * \param secret secret value (key) for this computation. - * \param secret_len length of "secret" (in bytes). - * \param label PRF label (zero-terminated ASCII string). - * \param seed_num number of seed chunks. - * \param seed seed chnks for this computation (usually non-secret). - */ -void br_tls12_sha384_prf(void *dst, size_t len, - const void *secret, size_t secret_len, const char *label, - size_t seed_num, const br_tls_prf_seed_chunk *seed); - -/** - * brief A convenient type name for a PRF implementation. - * - * \param dst destination buffer. - * \param len output length (in bytes). - * \param secret secret value (key) for this computation. - * \param secret_len length of "secret" (in bytes). - * \param label PRF label (zero-terminated ASCII string). - * \param seed_num number of seed chunks. - * \param seed seed chnks for this computation (usually non-secret). - */ -typedef void (*br_tls_prf_impl)(void *dst, size_t len, - const void *secret, size_t secret_len, const char *label, - size_t seed_num, const br_tls_prf_seed_chunk *seed); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/tls/bearssl/bearssl_rand.h b/src/tls/bearssl/bearssl_rand.h deleted file mode 100644 index 0a9f544fc..000000000 --- a/src/tls/bearssl/bearssl_rand.h +++ /dev/null @@ -1,397 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef BR_BEARSSL_RAND_H__ -#define BR_BEARSSL_RAND_H__ - -#include -#include - -#include "bearssl_block.h" -#include "bearssl_hash.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** \file bearssl_rand.h - * - * # Pseudo-Random Generators - * - * A PRNG is a state-based engine that outputs pseudo-random bytes on - * demand. It is initialized with an initial seed, and additional seed - * bytes can be added afterwards. Bytes produced depend on the seeds and - * also on the exact sequence of calls (including sizes requested for - * each call). - * - * - * ## Procedural and OOP API - * - * For the PRNG of name "`xxx`", two API are provided. The _procedural_ - * API defined a context structure `br_xxx_context` and three functions: - * - * - `br_xxx_init()` - * - * Initialise the context with an initial seed. - * - * - `br_xxx_generate()` - * - * Produce some pseudo-random bytes. - * - * - `br_xxx_update()` - * - * Inject some additional seed. - * - * The initialisation function sets the first context field (`vtable`) - * to a pointer to the vtable that supports the OOP API. The OOP API - * provides access to the same functions through function pointers, - * named `init()`, `generate()` and `update()`. - * - * Note that the context initialisation method may accept additional - * parameters, provided as a 'const void *' pointer at API level. These - * additional parameters depend on the implemented PRNG. - * - * - * ## HMAC_DRBG - * - * HMAC_DRBG is defined in [NIST SP 800-90A Revision - * 1](http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf). - * It uses HMAC repeatedly, over some configurable underlying hash - * function. In BearSSL, it is implemented under the "`hmac_drbg`" name. - * The "extra parameters" pointer for context initialisation should be - * set to a pointer to the vtable for the underlying hash function (e.g. - * pointer to `br_sha256_vtable` to use HMAC_DRBG with SHA-256). - * - * According to the NIST standard, each request shall produce up to - * 219 bits (i.e. 64 kB of data); moreover, the context shall - * be reseeded at least once every 248 requests. This - * implementation does not maintain the reseed counter (the threshold is - * too high to be reached in practice) and does not object to producing - * more than 64 kB in a single request; thus, the code cannot fail, - * which corresponds to the fact that the API has no room for error - * codes. However, this implies that requesting more than 64 kB in one - * `generate()` request, or making more than 248 requests - * without reseeding, is formally out of NIST specification. There is - * no currently known security penalty for exceeding the NIST limits, - * and, in any case, HMAC_DRBG usage in implementing SSL/TLS always - * stays much below these thresholds. - * - * - * ## AESCTR_DRBG - * - * AESCTR_DRBG is a custom PRNG based on AES-128 in CTR mode. This is - * meant to be used only in situations where you are desperate for - * speed, and have an hardware-optimized AES/CTR implementation. Whether - * this will yield perceptible improvements depends on what you use the - * pseudorandom bytes for, and how many you want; for instance, RSA key - * pair generation uses a substantial amount of randomness, and using - * AESCTR_DRBG instead of HMAC_DRBG yields a 15 to 20% increase in key - * generation speed on a recent x86 CPU (Intel Core i7-6567U at 3.30 GHz). - * - * Internally, it uses CTR mode with successive counter values, starting - * at zero (counter value expressed over 128 bits, big-endian convention). - * The counter is not allowed to reach 32768; thus, every 32768*16 bytes - * at most, the `update()` function is run (on an empty seed, if none is - * provided). The `update()` function computes the new AES-128 key by - * applying a custom hash function to the concatenation of a state-dependent - * word (encryption of an all-one block with the current key) and the new - * seed. The custom hash function uses Hirose's construction over AES-256; - * see the comments in `aesctr_drbg.c` for details. - * - * This DRBG does not follow an existing standard, and thus should be - * considered as inadequate for production use until it has been properly - * analysed. - */ - -/** - * \brief Class type for PRNG implementations. - * - * A `br_prng_class` instance references the methods implementing a PRNG. - * Constant instances of this structure are defined for each implemented - * PRNG. Such instances are also called "vtables". - */ -typedef struct br_prng_class_ br_prng_class; -struct br_prng_class_ { - /** - * \brief Size (in bytes) of the context structure appropriate for - * running this PRNG. - */ - size_t context_size; - - /** - * \brief Initialisation method. - * - * The context to initialise is provided as a pointer to its - * first field (the vtable pointer); this function sets that - * first field to a pointer to the vtable. - * - * The extra parameters depend on the implementation; each - * implementation defines what kind of extra parameters it - * expects (if any). - * - * Requirements on the initial seed depend on the implemented - * PRNG. - * - * \param ctx PRNG context to initialise. - * \param params extra parameters for the PRNG. - * \param seed initial seed. - * \param seed_len initial seed length (in bytes). - */ - void (*init)(const br_prng_class **ctx, const void *params, - const void *seed, size_t seed_len); - - /** - * \brief Random bytes generation. - * - * This method produces `len` pseudorandom bytes, in the `out` - * buffer. The context is updated accordingly. - * - * \param ctx PRNG context. - * \param out output buffer. - * \param len number of pseudorandom bytes to produce. - */ - void (*generate)(const br_prng_class **ctx, void *out, size_t len); - - /** - * \brief Inject additional seed bytes. - * - * The provided seed bytes are added into the PRNG internal - * entropy pool. - * - * \param ctx PRNG context. - * \param seed additional seed. - * \param seed_len additional seed length (in bytes). - */ - void (*update)(const br_prng_class **ctx, - const void *seed, size_t seed_len); -}; - -/** - * \brief Context for HMAC_DRBG. - * - * The context contents are opaque, except the first field, which - * supports OOP. - */ -typedef struct { - /** - * \brief Pointer to the vtable. - * - * This field is set with the initialisation method/function. - */ - const br_prng_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - unsigned char K[64]; - unsigned char V[64]; - const br_hash_class *digest_class; -#endif -} br_hmac_drbg_context; - -/** - * \brief Statically allocated, constant vtable for HMAC_DRBG. - */ -extern const br_prng_class br_hmac_drbg_vtable; - -/** - * \brief HMAC_DRBG initialisation. - * - * The context to initialise is provided as a pointer to its first field - * (the vtable pointer); this function sets that first field to a - * pointer to the vtable. - * - * The `seed` value is what is called, in NIST terminology, the - * concatenation of the "seed", "nonce" and "personalization string", in - * that order. - * - * The `digest_class` parameter defines the underlying hash function. - * Formally, the NIST standard specifies that the hash function shall - * be only SHA-1 or one of the SHA-2 functions. This implementation also - * works with any other implemented hash function (such as MD5), but - * this is non-standard and therefore not recommended. - * - * \param ctx HMAC_DRBG context to initialise. - * \param digest_class vtable for the underlying hash function. - * \param seed initial seed. - * \param seed_len initial seed length (in bytes). - */ -void br_hmac_drbg_init(br_hmac_drbg_context *ctx, - const br_hash_class *digest_class, const void *seed, size_t seed_len); - -/** - * \brief Random bytes generation with HMAC_DRBG. - * - * This method produces `len` pseudorandom bytes, in the `out` - * buffer. The context is updated accordingly. Formally, requesting - * more than 65536 bytes in one request falls out of specification - * limits (but it won't fail). - * - * \param ctx HMAC_DRBG context. - * \param out output buffer. - * \param len number of pseudorandom bytes to produce. - */ -void br_hmac_drbg_generate(br_hmac_drbg_context *ctx, void *out, size_t len); - -/** - * \brief Inject additional seed bytes in HMAC_DRBG. - * - * The provided seed bytes are added into the HMAC_DRBG internal - * entropy pool. The process does not _replace_ existing entropy, - * thus pushing non-random bytes (i.e. bytes which are known to the - * attackers) does not degrade the overall quality of generated bytes. - * - * \param ctx HMAC_DRBG context. - * \param seed additional seed. - * \param seed_len additional seed length (in bytes). - */ -void br_hmac_drbg_update(br_hmac_drbg_context *ctx, - const void *seed, size_t seed_len); - -/** - * \brief Get the hash function implementation used by a given instance of - * HMAC_DRBG. - * - * This calls MUST NOT be performed on a context which was not - * previously initialised. - * - * \param ctx HMAC_DRBG context. - * \return the hash function vtable. - */ -static inline const br_hash_class * -br_hmac_drbg_get_hash(const br_hmac_drbg_context *ctx) -{ - return ctx->digest_class; -} - -/** - * \brief Type for a provider of entropy seeds. - * - * A "seeder" is a function that is able to obtain random values from - * some source and inject them as entropy seed in a PRNG. A seeder - * shall guarantee that the total entropy of the injected seed is large - * enough to seed a PRNG for purposes of cryptographic key generation - * (i.e. at least 128 bits). - * - * A seeder may report a failure to obtain adequate entropy. Seeders - * shall endeavour to fix themselves transient errors by trying again; - * thus, callers may consider reported errors as permanent. - * - * \param ctx PRNG context to seed. - * \return 1 on success, 0 on error. - */ -typedef int (*br_prng_seeder)(const br_prng_class **ctx); - -/** - * \brief Get a seeder backed by the operating system or hardware. - * - * Get a seeder that feeds on RNG facilities provided by the current - * operating system or hardware. If no such facility is known, then 0 - * is returned. - * - * If `name` is not `NULL`, then `*name` is set to a symbolic string - * that identifies the seeder implementation. If no seeder is returned - * and `name` is not `NULL`, then `*name` is set to a pointer to the - * constant string `"none"`. - * - * \param name receiver for seeder name, or `NULL`. - * \return the system seeder, if available, or 0. - */ -br_prng_seeder br_prng_seeder_system(const char **name); - -/** - * \brief Context for AESCTR_DRBG. - * - * The context contents are opaque, except the first field, which - * supports OOP. - */ -typedef struct { - /** - * \brief Pointer to the vtable. - * - * This field is set with the initialisation method/function. - */ - const br_prng_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - br_aes_gen_ctr_keys sk; - uint32_t cc; -#endif -} br_aesctr_drbg_context; - -/** - * \brief Statically allocated, constant vtable for AESCTR_DRBG. - */ -extern const br_prng_class br_aesctr_drbg_vtable; - -/** - * \brief AESCTR_DRBG initialisation. - * - * The context to initialise is provided as a pointer to its first field - * (the vtable pointer); this function sets that first field to a - * pointer to the vtable. - * - * The internal AES key is first set to the all-zero key; then, the - * `br_aesctr_drbg_update()` function is called with the provided `seed`. - * The call is performed even if the seed length (`seed_len`) is zero. - * - * The `aesctr` parameter defines the underlying AES/CTR implementation. - * - * \param ctx AESCTR_DRBG context to initialise. - * \param aesctr vtable for the AES/CTR implementation. - * \param seed initial seed (can be `NULL` if `seed_len` is zero). - * \param seed_len initial seed length (in bytes). - */ -void br_aesctr_drbg_init(br_aesctr_drbg_context *ctx, - const br_block_ctr_class *aesctr, const void *seed, size_t seed_len); - -/** - * \brief Random bytes generation with AESCTR_DRBG. - * - * This method produces `len` pseudorandom bytes, in the `out` - * buffer. The context is updated accordingly. - * - * \param ctx AESCTR_DRBG context. - * \param out output buffer. - * \param len number of pseudorandom bytes to produce. - */ -void br_aesctr_drbg_generate(br_aesctr_drbg_context *ctx, - void *out, size_t len); - -/** - * \brief Inject additional seed bytes in AESCTR_DRBG. - * - * The provided seed bytes are added into the AESCTR_DRBG internal - * entropy pool. The process does not _replace_ existing entropy, - * thus pushing non-random bytes (i.e. bytes which are known to the - * attackers) does not degrade the overall quality of generated bytes. - * - * \param ctx AESCTR_DRBG context. - * \param seed additional seed. - * \param seed_len additional seed length (in bytes). - */ -void br_aesctr_drbg_update(br_aesctr_drbg_context *ctx, - const void *seed, size_t seed_len); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/tls/bearssl/bearssl_rsa.h b/src/tls/bearssl/bearssl_rsa.h deleted file mode 100644 index 805fb34cc..000000000 --- a/src/tls/bearssl/bearssl_rsa.h +++ /dev/null @@ -1,1366 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef BR_BEARSSL_RSA_H__ -#define BR_BEARSSL_RSA_H__ - -#include -#include - -#include "bearssl_rand.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** \file bearssl_rsa.h - * - * # RSA - * - * This file documents the RSA implementations provided with BearSSL. - * Note that the SSL engine accesses these implementations through a - * configurable API, so it is possible to, for instance, run a SSL - * server which uses a RSA engine which is not based on this code. - * - * ## Key Elements - * - * RSA public and private keys consist in lists of big integers. All - * such integers are represented with big-endian unsigned notation: - * first byte is the most significant, and the value is positive (so - * there is no dedicated "sign bit"). Public and private key structures - * thus contain, for each such integer, a pointer to the first value byte - * (`unsigned char *`), and a length (`size_t`) which is the number of - * relevant bytes. As a general rule, minimal-length encoding is not - * enforced: values may have extra leading bytes of value 0. - * - * RSA public keys consist in two integers: - * - * - the modulus (`n`); - * - the public exponent (`e`). - * - * RSA private keys, as defined in - * [PKCS#1](https://tools.ietf.org/html/rfc3447), contain eight integers: - * - * - the modulus (`n`); - * - the public exponent (`e`); - * - the private exponent (`d`); - * - the first prime factor (`p`); - * - the second prime factor (`q`); - * - the first reduced exponent (`dp`, which is `d` modulo `p-1`); - * - the second reduced exponent (`dq`, which is `d` modulo `q-1`); - * - the CRT coefficient (`iq`, the inverse of `q` modulo `p`). - * - * However, the implementations defined in BearSSL use only five of - * these integers: `p`, `q`, `dp`, `dq` and `iq`. - * - * ## Security Features and Limitations - * - * The implementations contained in BearSSL have the following limitations - * and features: - * - * - They are constant-time. This means that the execution time and - * memory access pattern may depend on the _lengths_ of the private - * key components, but not on their value, nor on the value of - * the operand. Note that this property is not achieved through - * random masking, but "true" constant-time code. - * - * - They support only private keys with two prime factors. RSA private - * keys with three or more prime factors are nominally supported, but - * rarely used; they may offer faster operations, at the expense of - * more code and potentially a reduction in security if there are - * "too many" prime factors. - * - * - The public exponent may have arbitrary length. Of course, it is - * a good idea to keep public exponents small, so that public key - * operations are fast; but, contrary to some widely deployed - * implementations, BearSSL has no problem with public exponents - * longer than 32 bits. - * - * - The two prime factors of the modulus need not have the same length - * (but severely imbalanced factor lengths might reduce security). - * Similarly, there is no requirement that the first factor (`p`) - * be greater than the second factor (`q`). - * - * - Prime factors and modulus must be smaller than a compile-time limit. - * This is made necessary by the use of fixed-size stack buffers, and - * the limit has been adjusted to keep stack usage under 2 kB for the - * RSA operations. Currently, the maximum modulus size is 4096 bits, - * and the maximum prime factor size is 2080 bits. - * - * - The RSA functions themselves do not enforce lower size limits, - * except that which is absolutely necessary for the operation to - * mathematically make sense (e.g. a PKCS#1 v1.5 signature with - * SHA-1 requires a modulus of at least 361 bits). It is up to users - * of this code to enforce size limitations when appropriate (e.g. - * the X.509 validation engine, by default, rejects RSA keys of - * less than 1017 bits). - * - * - Within the size constraints expressed above, arbitrary bit lengths - * are supported. There is no requirement that prime factors or - * modulus have a size multiple of 8 or 16. - * - * - When verifying PKCS#1 v1.5 signatures, both variants of the hash - * function identifying header (with and without the ASN.1 NULL) are - * supported. When producing such signatures, the variant with the - * ASN.1 NULL is used. - * - * ## Implementations - * - * Three RSA implementations are included: - * - * - The **i32** implementation internally represents big integers - * as arrays of 32-bit integers. It is perfunctory and portable, - * but not very efficient. - * - * - The **i31** implementation uses 32-bit integers, each containing - * 31 bits worth of integer data. The i31 implementation is somewhat - * faster than the i32 implementation (the reduced integer size makes - * carry propagation easier) for a similar code footprint, but uses - * very slightly larger stack buffers (about 4% bigger). - * - * - The **i62** implementation is similar to the i31 implementation, - * except that it internally leverages the 64x64->128 multiplication - * opcode. This implementation is available only on architectures - * where such an opcode exists. It is much faster than i31. - * - * - The **i15** implementation uses 16-bit integers, each containing - * 15 bits worth of integer data. Multiplication results fit on - * 32 bits, so this won't use the "widening" multiplication routine - * on ARM Cortex M0/M0+, for much better performance and constant-time - * execution. - */ - -/** - * \brief RSA public key. - * - * The structure references the modulus and the public exponent. Both - * integers use unsigned big-endian representation; extra leading bytes - * of value 0 are allowed. - */ -typedef struct { - /** \brief Modulus. */ - unsigned char *n; - /** \brief Modulus length (in bytes). */ - size_t nlen; - /** \brief Public exponent. */ - unsigned char *e; - /** \brief Public exponent length (in bytes). */ - size_t elen; -} br_rsa_public_key; - -/** - * \brief RSA private key. - * - * The structure references the private factors, reduced private - * exponents, and CRT coefficient. It also contains the bit length of - * the modulus. The big integers use unsigned big-endian representation; - * extra leading bytes of value 0 are allowed. However, the modulus bit - * length (`n_bitlen`) MUST be exact. - */ -typedef struct { - /** \brief Modulus bit length (in bits, exact value). */ - uint32_t n_bitlen; - /** \brief First prime factor. */ - unsigned char *p; - /** \brief First prime factor length (in bytes). */ - size_t plen; - /** \brief Second prime factor. */ - unsigned char *q; - /** \brief Second prime factor length (in bytes). */ - size_t qlen; - /** \brief First reduced private exponent. */ - unsigned char *dp; - /** \brief First reduced private exponent length (in bytes). */ - size_t dplen; - /** \brief Second reduced private exponent. */ - unsigned char *dq; - /** \brief Second reduced private exponent length (in bytes). */ - size_t dqlen; - /** \brief CRT coefficient. */ - unsigned char *iq; - /** \brief CRT coefficient length (in bytes). */ - size_t iqlen; -} br_rsa_private_key; - -/** - * \brief Type for a RSA public key engine. - * - * The public key engine performs the modular exponentiation of the - * provided value with the public exponent. The value is modified in - * place. - * - * The value length (`xlen`) is verified to have _exactly_ the same - * length as the modulus (actual modulus length, without extra leading - * zeros in the modulus representation in memory). If the length does - * not match, then this function returns 0 and `x[]` is unmodified. - * - * It `xlen` is correct, then `x[]` is modified. Returned value is 1 - * on success, 0 on error. Error conditions include an oversized `x[]` - * (the array has the same length as the modulus, but the numerical value - * is not lower than the modulus) and an invalid modulus (e.g. an even - * integer). If an error is reported, then the new contents of `x[]` are - * unspecified. - * - * \param x operand to exponentiate. - * \param xlen length of the operand (in bytes). - * \param pk RSA public key. - * \return 1 on success, 0 on error. - */ -typedef uint32_t (*br_rsa_public)(unsigned char *x, size_t xlen, - const br_rsa_public_key *pk); - -/** - * \brief Type for a RSA signature verification engine (PKCS#1 v1.5). - * - * Parameters are: - * - * - The signature itself. The provided array is NOT modified. - * - * - The encoded OID for the hash function. The provided array must begin - * with a single byte that contains the length of the OID value (in - * bytes), followed by exactly that many bytes. This parameter may - * also be `NULL`, in which case the raw hash value should be used - * with the PKCS#1 v1.5 "type 1" padding (as used in SSL/TLS up - * to TLS-1.1, with a 36-byte hash value). - * - * - The hash output length, in bytes. - * - * - The public key. - * - * - An output buffer for the hash value. The caller must still compare - * it with the hash of the data over which the signature is computed. - * - * **Constraints:** - * - * - Hash length MUST be no more than 64 bytes. - * - * - OID value length MUST be no more than 32 bytes (i.e. `hash_oid[0]` - * must have a value in the 0..32 range, inclusive). - * - * This function verifies that the signature length (`xlen`) matches the - * modulus length (this function returns 0 on mismatch). If the modulus - * size exceeds the maximum supported RSA size, then the function also - * returns 0. - * - * Returned value is 1 on success, 0 on error. - * - * Implementations of this type need not be constant-time. - * - * \param x signature buffer. - * \param xlen signature length (in bytes). - * \param hash_oid encoded hash algorithm OID (or `NULL`). - * \param hash_len expected hash value length (in bytes). - * \param pk RSA public key. - * \param hash_out output buffer for the hash value. - * \return 1 on success, 0 on error. - */ -typedef uint32_t (*br_rsa_pkcs1_vrfy)(const unsigned char *x, size_t xlen, - const unsigned char *hash_oid, size_t hash_len, - const br_rsa_public_key *pk, unsigned char *hash_out); - -/** - * \brief Type for a RSA encryption engine (OAEP). - * - * Parameters are: - * - * - A source of random bytes. The source must be already initialized. - * - * - A hash function, used internally with the mask generation function - * (MGF1). - * - * - A label. The `label` pointer may be `NULL` if `label_len` is zero - * (an empty label, which is the default in PKCS#1 v2.2). - * - * - The public key. - * - * - The destination buffer. Its maximum length (in bytes) is provided; - * if that length is lower than the public key length, then an error - * is reported. - * - * - The source message. - * - * The encrypted message output has exactly the same length as the modulus - * (mathematical length, in bytes, not counting extra leading zeros in the - * modulus representation in the public key). - * - * The source message (`src`, length `src_len`) may overlap with the - * destination buffer (`dst`, length `dst_max_len`). - * - * This function returns the actual encrypted message length, in bytes; - * on error, zero is returned. An error is reported if the output buffer - * is not large enough, or the public is invalid, or the public key - * modulus exceeds the maximum supported RSA size. - * - * \param rnd source of random bytes. - * \param dig hash function to use with MGF1. - * \param label label value (may be `NULL` if `label_len` is zero). - * \param label_len label length, in bytes. - * \param pk RSA public key. - * \param dst destination buffer. - * \param dst_max_len destination buffer length (maximum encrypted data size). - * \param src message to encrypt. - * \param src_len source message length (in bytes). - * \return encrypted message length (in bytes), or 0 on error. - */ -typedef size_t (*br_rsa_oaep_encrypt)( - const br_prng_class **rnd, const br_hash_class *dig, - const void *label, size_t label_len, - const br_rsa_public_key *pk, - void *dst, size_t dst_max_len, - const void *src, size_t src_len); - -/** - * \brief Type for a RSA private key engine. - * - * The `x[]` buffer is modified in place, and its length is inferred from - * the modulus length (`x[]` is assumed to have a length of - * `(sk->n_bitlen+7)/8` bytes). - * - * Returned value is 1 on success, 0 on error. - * - * \param x operand to exponentiate. - * \param sk RSA private key. - * \return 1 on success, 0 on error. - */ -typedef uint32_t (*br_rsa_private)(unsigned char *x, - const br_rsa_private_key *sk); - -/** - * \brief Type for a RSA signature generation engine (PKCS#1 v1.5). - * - * Parameters are: - * - * - The encoded OID for the hash function. The provided array must begin - * with a single byte that contains the length of the OID value (in - * bytes), followed by exactly that many bytes. This parameter may - * also be `NULL`, in which case the raw hash value should be used - * with the PKCS#1 v1.5 "type 1" padding (as used in SSL/TLS up - * to TLS-1.1, with a 36-byte hash value). - * - * - The hash value computes over the data to sign (its length is - * expressed in bytes). - * - * - The RSA private key. - * - * - The output buffer, that receives the signature. - * - * Returned value is 1 on success, 0 on error. Error conditions include - * a too small modulus for the provided hash OID and value, or some - * invalid key parameters. The signature length is exactly - * `(sk->n_bitlen+7)/8` bytes. - * - * This function is expected to be constant-time with regards to the - * private key bytes (lengths of the modulus and the individual factors - * may leak, though) and to the hashed data. - * - * \param hash_oid encoded hash algorithm OID (or `NULL`). - * \param hash hash value. - * \param hash_len hash value length (in bytes). - * \param sk RSA private key. - * \param x output buffer for the signature value. - * \return 1 on success, 0 on error. - */ -typedef uint32_t (*br_rsa_pkcs1_sign)(const unsigned char *hash_oid, - const unsigned char *hash, size_t hash_len, - const br_rsa_private_key *sk, unsigned char *x); - -/** - * \brief Encoded OID for SHA-1 (in RSA PKCS#1 signatures). - */ -#define BR_HASH_OID_SHA1 \ - ((const unsigned char *)"\x05\x2B\x0E\x03\x02\x1A") - -/** - * \brief Encoded OID for SHA-224 (in RSA PKCS#1 signatures). - */ -#define BR_HASH_OID_SHA224 \ - ((const unsigned char *)"\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04") - -/** - * \brief Encoded OID for SHA-256 (in RSA PKCS#1 signatures). - */ -#define BR_HASH_OID_SHA256 \ - ((const unsigned char *)"\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01") - -/** - * \brief Encoded OID for SHA-384 (in RSA PKCS#1 signatures). - */ -#define BR_HASH_OID_SHA384 \ - ((const unsigned char *)"\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02") - -/** - * \brief Encoded OID for SHA-512 (in RSA PKCS#1 signatures). - */ -#define BR_HASH_OID_SHA512 \ - ((const unsigned char *)"\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03") - -/** - * \brief Type for a RSA decryption engine (OAEP). - * - * Parameters are: - * - * - A hash function, used internally with the mask generation function - * (MGF1). - * - * - A label. The `label` pointer may be `NULL` if `label_len` is zero - * (an empty label, which is the default in PKCS#1 v2.2). - * - * - The private key. - * - * - The source and destination buffer. The buffer initially contains - * the encrypted message; the buffer contents are altered, and the - * decrypted message is written at the start of that buffer - * (decrypted message is always shorter than the encrypted message). - * - * If decryption fails in any way, then `*len` is unmodified, and the - * function returns 0. Otherwise, `*len` is set to the decrypted message - * length, and 1 is returned. The implementation is responsible for - * checking that the input message length matches the key modulus length, - * and that the padding is correct. - * - * Implementations MUST use constant-time check of the validity of the - * OAEP padding, at least until the leading byte and hash value have - * been checked. Whether overall decryption worked, and the length of - * the decrypted message, may leak. - * - * \param dig hash function to use with MGF1. - * \param label label value (may be `NULL` if `label_len` is zero). - * \param label_len label length, in bytes. - * \param sk RSA private key. - * \param data input/output buffer. - * \param len encrypted/decrypted message length. - * \return 1 on success, 0 on error. - */ -typedef uint32_t (*br_rsa_oaep_decrypt)( - const br_hash_class *dig, const void *label, size_t label_len, - const br_rsa_private_key *sk, void *data, size_t *len); - -/* - * RSA "i32" engine. Integers are internally represented as arrays of - * 32-bit integers, and the core multiplication primitive is the - * 32x32->64 multiplication. - */ - -/** - * \brief RSA public key engine "i32". - * - * \see br_rsa_public - * - * \param x operand to exponentiate. - * \param xlen length of the operand (in bytes). - * \param pk RSA public key. - * \return 1 on success, 0 on error. - */ -uint32_t br_rsa_i32_public(unsigned char *x, size_t xlen, - const br_rsa_public_key *pk); - -/** - * \brief RSA signature verification engine "i32". - * - * \see br_rsa_pkcs1_vrfy - * - * \param x signature buffer. - * \param xlen signature length (in bytes). - * \param hash_oid encoded hash algorithm OID (or `NULL`). - * \param hash_len expected hash value length (in bytes). - * \param pk RSA public key. - * \param hash_out output buffer for the hash value. - * \return 1 on success, 0 on error. - */ -uint32_t br_rsa_i32_pkcs1_vrfy(const unsigned char *x, size_t xlen, - const unsigned char *hash_oid, size_t hash_len, - const br_rsa_public_key *pk, unsigned char *hash_out); - -/** - * \brief RSA private key engine "i32". - * - * \see br_rsa_private - * - * \param x operand to exponentiate. - * \param sk RSA private key. - * \return 1 on success, 0 on error. - */ -uint32_t br_rsa_i32_private(unsigned char *x, - const br_rsa_private_key *sk); - -/** - * \brief RSA signature generation engine "i32". - * - * \see br_rsa_pkcs1_sign - * - * \param hash_oid encoded hash algorithm OID (or `NULL`). - * \param hash hash value. - * \param hash_len hash value length (in bytes). - * \param sk RSA private key. - * \param x output buffer for the hash value. - * \return 1 on success, 0 on error. - */ -uint32_t br_rsa_i32_pkcs1_sign(const unsigned char *hash_oid, - const unsigned char *hash, size_t hash_len, - const br_rsa_private_key *sk, unsigned char *x); - -/* - * RSA "i31" engine. Similar to i32, but only 31 bits are used per 32-bit - * word. This uses slightly more stack space (about 4% more) and code - * space, but it quite faster. - */ - -/** - * \brief RSA public key engine "i31". - * - * \see br_rsa_public - * - * \param x operand to exponentiate. - * \param xlen length of the operand (in bytes). - * \param pk RSA public key. - * \return 1 on success, 0 on error. - */ -uint32_t br_rsa_i31_public(unsigned char *x, size_t xlen, - const br_rsa_public_key *pk); - -/** - * \brief RSA signature verification engine "i31". - * - * \see br_rsa_pkcs1_vrfy - * - * \param x signature buffer. - * \param xlen signature length (in bytes). - * \param hash_oid encoded hash algorithm OID (or `NULL`). - * \param hash_len expected hash value length (in bytes). - * \param pk RSA public key. - * \param hash_out output buffer for the hash value. - * \return 1 on success, 0 on error. - */ -uint32_t br_rsa_i31_pkcs1_vrfy(const unsigned char *x, size_t xlen, - const unsigned char *hash_oid, size_t hash_len, - const br_rsa_public_key *pk, unsigned char *hash_out); - -/** - * \brief RSA private key engine "i31". - * - * \see br_rsa_private - * - * \param x operand to exponentiate. - * \param sk RSA private key. - * \return 1 on success, 0 on error. - */ -uint32_t br_rsa_i31_private(unsigned char *x, - const br_rsa_private_key *sk); - -/** - * \brief RSA signature generation engine "i31". - * - * \see br_rsa_pkcs1_sign - * - * \param hash_oid encoded hash algorithm OID (or `NULL`). - * \param hash hash value. - * \param hash_len hash value length (in bytes). - * \param sk RSA private key. - * \param x output buffer for the hash value. - * \return 1 on success, 0 on error. - */ -uint32_t br_rsa_i31_pkcs1_sign(const unsigned char *hash_oid, - const unsigned char *hash, size_t hash_len, - const br_rsa_private_key *sk, unsigned char *x); - -/* - * RSA "i62" engine. Similar to i31, but internal multiplication use - * 64x64->128 multiplications. This is available only on architecture - * that offer such an opcode. - */ - -/** - * \brief RSA public key engine "i62". - * - * This function is defined only on architecture that offer a 64x64->128 - * opcode. Use `br_rsa_i62_public_get()` to dynamically obtain a pointer - * to that function. - * - * \see br_rsa_public - * - * \param x operand to exponentiate. - * \param xlen length of the operand (in bytes). - * \param pk RSA public key. - * \return 1 on success, 0 on error. - */ -uint32_t br_rsa_i62_public(unsigned char *x, size_t xlen, - const br_rsa_public_key *pk); - -/** - * \brief RSA signature verification engine "i62". - * - * This function is defined only on architecture that offer a 64x64->128 - * opcode. Use `br_rsa_i62_pkcs1_vrfy_get()` to dynamically obtain a pointer - * to that function. - * - * \see br_rsa_pkcs1_vrfy - * - * \param x signature buffer. - * \param xlen signature length (in bytes). - * \param hash_oid encoded hash algorithm OID (or `NULL`). - * \param hash_len expected hash value length (in bytes). - * \param pk RSA public key. - * \param hash_out output buffer for the hash value. - * \return 1 on success, 0 on error. - */ -uint32_t br_rsa_i62_pkcs1_vrfy(const unsigned char *x, size_t xlen, - const unsigned char *hash_oid, size_t hash_len, - const br_rsa_public_key *pk, unsigned char *hash_out); - -/** - * \brief RSA private key engine "i62". - * - * This function is defined only on architecture that offer a 64x64->128 - * opcode. Use `br_rsa_i62_private_get()` to dynamically obtain a pointer - * to that function. - * - * \see br_rsa_private - * - * \param x operand to exponentiate. - * \param sk RSA private key. - * \return 1 on success, 0 on error. - */ -uint32_t br_rsa_i62_private(unsigned char *x, - const br_rsa_private_key *sk); - -/** - * \brief RSA signature generation engine "i62". - * - * This function is defined only on architecture that offer a 64x64->128 - * opcode. Use `br_rsa_i62_pkcs1_sign_get()` to dynamically obtain a pointer - * to that function. - * - * \see br_rsa_pkcs1_sign - * - * \param hash_oid encoded hash algorithm OID (or `NULL`). - * \param hash hash value. - * \param hash_len hash value length (in bytes). - * \param sk RSA private key. - * \param x output buffer for the hash value. - * \return 1 on success, 0 on error. - */ -uint32_t br_rsa_i62_pkcs1_sign(const unsigned char *hash_oid, - const unsigned char *hash, size_t hash_len, - const br_rsa_private_key *sk, unsigned char *x); - -/** - * \brief Get the RSA "i62" implementation (public key operations), - * if available. - * - * \return the implementation, or 0. - */ -br_rsa_public br_rsa_i62_public_get(void); - -/** - * \brief Get the RSA "i62" implementation (PKCS#1 signature verification), - * if available. - * - * \return the implementation, or 0. - */ -br_rsa_pkcs1_vrfy br_rsa_i62_pkcs1_vrfy_get(void); - -/** - * \brief Get the RSA "i62" implementation (private key operations), - * if available. - * - * \return the implementation, or 0. - */ -br_rsa_private br_rsa_i62_private_get(void); - -/** - * \brief Get the RSA "i62" implementation (PKCS#1 signature generation), - * if available. - * - * \return the implementation, or 0. - */ -br_rsa_pkcs1_sign br_rsa_i62_pkcs1_sign_get(void); - -/** - * \brief Get the RSA "i62" implementation (OAEP encryption), - * if available. - * - * \return the implementation, or 0. - */ -br_rsa_oaep_encrypt br_rsa_i62_oaep_encrypt_get(void); - -/** - * \brief Get the RSA "i62" implementation (OAEP decryption), - * if available. - * - * \return the implementation, or 0. - */ -br_rsa_oaep_decrypt br_rsa_i62_oaep_decrypt_get(void); - -/* - * RSA "i15" engine. Integers are represented as 15-bit integers, so - * the code uses only 32-bit multiplication (no 64-bit result), which - * is vastly faster (and constant-time) on the ARM Cortex M0/M0+. - */ - -/** - * \brief RSA public key engine "i15". - * - * \see br_rsa_public - * - * \param x operand to exponentiate. - * \param xlen length of the operand (in bytes). - * \param pk RSA public key. - * \return 1 on success, 0 on error. - */ -uint32_t br_rsa_i15_public(unsigned char *x, size_t xlen, - const br_rsa_public_key *pk); - -/** - * \brief RSA signature verification engine "i15". - * - * \see br_rsa_pkcs1_vrfy - * - * \param x signature buffer. - * \param xlen signature length (in bytes). - * \param hash_oid encoded hash algorithm OID (or `NULL`). - * \param hash_len expected hash value length (in bytes). - * \param pk RSA public key. - * \param hash_out output buffer for the hash value. - * \return 1 on success, 0 on error. - */ -uint32_t br_rsa_i15_pkcs1_vrfy(const unsigned char *x, size_t xlen, - const unsigned char *hash_oid, size_t hash_len, - const br_rsa_public_key *pk, unsigned char *hash_out); - -/** - * \brief RSA private key engine "i15". - * - * \see br_rsa_private - * - * \param x operand to exponentiate. - * \param sk RSA private key. - * \return 1 on success, 0 on error. - */ -uint32_t br_rsa_i15_private(unsigned char *x, - const br_rsa_private_key *sk); - -/** - * \brief RSA signature generation engine "i15". - * - * \see br_rsa_pkcs1_sign - * - * \param hash_oid encoded hash algorithm OID (or `NULL`). - * \param hash hash value. - * \param hash_len hash value length (in bytes). - * \param sk RSA private key. - * \param x output buffer for the hash value. - * \return 1 on success, 0 on error. - */ -uint32_t br_rsa_i15_pkcs1_sign(const unsigned char *hash_oid, - const unsigned char *hash, size_t hash_len, - const br_rsa_private_key *sk, unsigned char *x); - -/** - * \brief Get "default" RSA implementation (public-key operations). - * - * This returns the preferred implementation of RSA (public-key operations) - * on the current system. - * - * \return the default implementation. - */ -br_rsa_public br_rsa_public_get_default(void); - -/** - * \brief Get "default" RSA implementation (private-key operations). - * - * This returns the preferred implementation of RSA (private-key operations) - * on the current system. - * - * \return the default implementation. - */ -br_rsa_private br_rsa_private_get_default(void); - -/** - * \brief Get "default" RSA implementation (PKCS#1 signature verification). - * - * This returns the preferred implementation of RSA (signature verification) - * on the current system. - * - * \return the default implementation. - */ -br_rsa_pkcs1_vrfy br_rsa_pkcs1_vrfy_get_default(void); - -/** - * \brief Get "default" RSA implementation (PKCS#1 signature generation). - * - * This returns the preferred implementation of RSA (signature generation) - * on the current system. - * - * \return the default implementation. - */ -br_rsa_pkcs1_sign br_rsa_pkcs1_sign_get_default(void); - -/** - * \brief Get "default" RSA implementation (OAEP encryption). - * - * This returns the preferred implementation of RSA (OAEP encryption) - * on the current system. - * - * \return the default implementation. - */ -br_rsa_oaep_encrypt br_rsa_oaep_encrypt_get_default(void); - -/** - * \brief Get "default" RSA implementation (OAEP decryption). - * - * This returns the preferred implementation of RSA (OAEP decryption) - * on the current system. - * - * \return the default implementation. - */ -br_rsa_oaep_decrypt br_rsa_oaep_decrypt_get_default(void); - -/** - * \brief RSA decryption helper, for SSL/TLS. - * - * This function performs the RSA decryption for a RSA-based key exchange - * in a SSL/TLS server. The provided RSA engine is used. The `data` - * parameter points to the value to decrypt, of length `len` bytes. On - * success, the 48-byte pre-master secret is copied into `data`, starting - * at the first byte of that buffer; on error, the contents of `data` - * become indeterminate. - * - * This function first checks that the provided value length (`len`) is - * not lower than 59 bytes, and matches the RSA modulus length; if neither - * of this property is met, then this function returns 0 and the buffer - * is unmodified. - * - * Otherwise, decryption and then padding verification are performed, both - * in constant-time. A decryption error, or a bad padding, or an - * incorrect decrypted value length are reported with a returned value of - * 0; on success, 1 is returned. The caller (SSL server engine) is supposed - * to proceed with a random pre-master secret in case of error. - * - * \param core RSA private key engine. - * \param sk RSA private key. - * \param data input/output buffer. - * \param len length (in bytes) of the data to decrypt. - * \return 1 on success, 0 on error. - */ -uint32_t br_rsa_ssl_decrypt(br_rsa_private core, const br_rsa_private_key *sk, - unsigned char *data, size_t len); - -/** - * \brief RSA encryption (OAEP) with the "i15" engine. - * - * \see br_rsa_oaep_encrypt - * - * \param rnd source of random bytes. - * \param dig hash function to use with MGF1. - * \param label label value (may be `NULL` if `label_len` is zero). - * \param label_len label length, in bytes. - * \param pk RSA public key. - * \param dst destination buffer. - * \param dst_max_len destination buffer length (maximum encrypted data size). - * \param src message to encrypt. - * \param src_len source message length (in bytes). - * \return encrypted message length (in bytes), or 0 on error. - */ -size_t br_rsa_i15_oaep_encrypt( - const br_prng_class **rnd, const br_hash_class *dig, - const void *label, size_t label_len, - const br_rsa_public_key *pk, - void *dst, size_t dst_max_len, - const void *src, size_t src_len); - -/** - * \brief RSA decryption (OAEP) with the "i15" engine. - * - * \see br_rsa_oaep_decrypt - * - * \param dig hash function to use with MGF1. - * \param label label value (may be `NULL` if `label_len` is zero). - * \param label_len label length, in bytes. - * \param sk RSA private key. - * \param data input/output buffer. - * \param len encrypted/decrypted message length. - * \return 1 on success, 0 on error. - */ -uint32_t br_rsa_i15_oaep_decrypt( - const br_hash_class *dig, const void *label, size_t label_len, - const br_rsa_private_key *sk, void *data, size_t *len); - -/** - * \brief RSA encryption (OAEP) with the "i31" engine. - * - * \see br_rsa_oaep_encrypt - * - * \param rnd source of random bytes. - * \param dig hash function to use with MGF1. - * \param label label value (may be `NULL` if `label_len` is zero). - * \param label_len label length, in bytes. - * \param pk RSA public key. - * \param dst destination buffer. - * \param dst_max_len destination buffer length (maximum encrypted data size). - * \param src message to encrypt. - * \param src_len source message length (in bytes). - * \return encrypted message length (in bytes), or 0 on error. - */ -size_t br_rsa_i31_oaep_encrypt( - const br_prng_class **rnd, const br_hash_class *dig, - const void *label, size_t label_len, - const br_rsa_public_key *pk, - void *dst, size_t dst_max_len, - const void *src, size_t src_len); - -/** - * \brief RSA decryption (OAEP) with the "i31" engine. - * - * \see br_rsa_oaep_decrypt - * - * \param dig hash function to use with MGF1. - * \param label label value (may be `NULL` if `label_len` is zero). - * \param label_len label length, in bytes. - * \param sk RSA private key. - * \param data input/output buffer. - * \param len encrypted/decrypted message length. - * \return 1 on success, 0 on error. - */ -uint32_t br_rsa_i31_oaep_decrypt( - const br_hash_class *dig, const void *label, size_t label_len, - const br_rsa_private_key *sk, void *data, size_t *len); - -/** - * \brief RSA encryption (OAEP) with the "i32" engine. - * - * \see br_rsa_oaep_encrypt - * - * \param rnd source of random bytes. - * \param dig hash function to use with MGF1. - * \param label label value (may be `NULL` if `label_len` is zero). - * \param label_len label length, in bytes. - * \param pk RSA public key. - * \param dst destination buffer. - * \param dst_max_len destination buffer length (maximum encrypted data size). - * \param src message to encrypt. - * \param src_len source message length (in bytes). - * \return encrypted message length (in bytes), or 0 on error. - */ -size_t br_rsa_i32_oaep_encrypt( - const br_prng_class **rnd, const br_hash_class *dig, - const void *label, size_t label_len, - const br_rsa_public_key *pk, - void *dst, size_t dst_max_len, - const void *src, size_t src_len); - -/** - * \brief RSA decryption (OAEP) with the "i32" engine. - * - * \see br_rsa_oaep_decrypt - * - * \param dig hash function to use with MGF1. - * \param label label value (may be `NULL` if `label_len` is zero). - * \param label_len label length, in bytes. - * \param sk RSA private key. - * \param data input/output buffer. - * \param len encrypted/decrypted message length. - * \return 1 on success, 0 on error. - */ -uint32_t br_rsa_i32_oaep_decrypt( - const br_hash_class *dig, const void *label, size_t label_len, - const br_rsa_private_key *sk, void *data, size_t *len); - -/** - * \brief RSA encryption (OAEP) with the "i62" engine. - * - * This function is defined only on architecture that offer a 64x64->128 - * opcode. Use `br_rsa_i62_oaep_encrypt_get()` to dynamically obtain a pointer - * to that function. - * - * \see br_rsa_oaep_encrypt - * - * \param rnd source of random bytes. - * \param dig hash function to use with MGF1. - * \param label label value (may be `NULL` if `label_len` is zero). - * \param label_len label length, in bytes. - * \param pk RSA public key. - * \param dst destination buffer. - * \param dst_max_len destination buffer length (maximum encrypted data size). - * \param src message to encrypt. - * \param src_len source message length (in bytes). - * \return encrypted message length (in bytes), or 0 on error. - */ -size_t br_rsa_i62_oaep_encrypt( - const br_prng_class **rnd, const br_hash_class *dig, - const void *label, size_t label_len, - const br_rsa_public_key *pk, - void *dst, size_t dst_max_len, - const void *src, size_t src_len); - -/** - * \brief RSA decryption (OAEP) with the "i62" engine. - * - * This function is defined only on architecture that offer a 64x64->128 - * opcode. Use `br_rsa_i62_oaep_decrypt_get()` to dynamically obtain a pointer - * to that function. - * - * \see br_rsa_oaep_decrypt - * - * \param dig hash function to use with MGF1. - * \param label label value (may be `NULL` if `label_len` is zero). - * \param label_len label length, in bytes. - * \param sk RSA private key. - * \param data input/output buffer. - * \param len encrypted/decrypted message length. - * \return 1 on success, 0 on error. - */ -uint32_t br_rsa_i62_oaep_decrypt( - const br_hash_class *dig, const void *label, size_t label_len, - const br_rsa_private_key *sk, void *data, size_t *len); - -/** - * \brief Get buffer size to hold RSA private key elements. - * - * This macro returns the length (in bytes) of the buffer needed to - * receive the elements of a RSA private key, as generated by one of - * the `br_rsa_*_keygen()` functions. If the provided size is a constant - * expression, then the whole macro evaluates to a constant expression. - * - * \param size target key size (modulus size, in bits) - * \return the length of the private key buffer, in bytes. - */ -#define BR_RSA_KBUF_PRIV_SIZE(size) (5 * (((size) + 15) >> 4)) - -/** - * \brief Get buffer size to hold RSA public key elements. - * - * This macro returns the length (in bytes) of the buffer needed to - * receive the elements of a RSA public key, as generated by one of - * the `br_rsa_*_keygen()` functions. If the provided size is a constant - * expression, then the whole macro evaluates to a constant expression. - * - * \param size target key size (modulus size, in bits) - * \return the length of the public key buffer, in bytes. - */ -#define BR_RSA_KBUF_PUB_SIZE(size) (4 + (((size) + 7) >> 3)) - -/** - * \brief Type for RSA key pair generator implementation. - * - * This function generates a new RSA key pair whose modulus has bit - * length `size` bits. The private key elements are written in the - * `kbuf_priv` buffer, and pointer values and length fields to these - * elements are populated in the provided private key structure `sk`. - * Similarly, the public key elements are written in `kbuf_pub`, with - * pointers and lengths set in `pk`. - * - * If `pk` is `NULL`, then `kbuf_pub` may be `NULL`, and only the - * private key is set. - * - * If `pubexp` is not zero, then its value will be used as public - * exponent. Valid RSA public exponent values are odd integers - * greater than 1. If `pubexp` is zero, then the public exponent will - * have value 3. - * - * The provided PRNG (`rng_ctx`) must have already been initialized - * and seeded. - * - * Returned value is 1 on success, 0 on error. An error is reported - * if the requested range is outside of the supported key sizes, or - * if an invalid non-zero public exponent value is provided. Supported - * range starts at 512 bits, and up to an implementation-defined - * maximum (by default 4096 bits). Note that key sizes up to 768 bits - * have been broken in practice, and sizes lower than 2048 bits are - * usually considered to be weak and should not be used. - * - * \param rng_ctx source PRNG context (already initialized) - * \param sk RSA private key structure (destination) - * \param kbuf_priv buffer for private key elements - * \param pk RSA public key structure (destination), or `NULL` - * \param kbuf_pub buffer for public key elements, or `NULL` - * \param size target RSA modulus size (in bits) - * \param pubexp public exponent to use, or zero - * \return 1 on success, 0 on error (invalid parameters) - */ -typedef uint32_t (*br_rsa_keygen)( - const br_prng_class **rng_ctx, - br_rsa_private_key *sk, void *kbuf_priv, - br_rsa_public_key *pk, void *kbuf_pub, - unsigned size, uint32_t pubexp); - -/** - * \brief RSA key pair generation with the "i15" engine. - * - * \see br_rsa_keygen - * - * \param rng_ctx source PRNG context (already initialized) - * \param sk RSA private key structure (destination) - * \param kbuf_priv buffer for private key elements - * \param pk RSA public key structure (destination), or `NULL` - * \param kbuf_pub buffer for public key elements, or `NULL` - * \param size target RSA modulus size (in bits) - * \param pubexp public exponent to use, or zero - * \return 1 on success, 0 on error (invalid parameters) - */ -uint32_t br_rsa_i15_keygen( - const br_prng_class **rng_ctx, - br_rsa_private_key *sk, void *kbuf_priv, - br_rsa_public_key *pk, void *kbuf_pub, - unsigned size, uint32_t pubexp); - -/** - * \brief RSA key pair generation with the "i31" engine. - * - * \see br_rsa_keygen - * - * \param rng_ctx source PRNG context (already initialized) - * \param sk RSA private key structure (destination) - * \param kbuf_priv buffer for private key elements - * \param pk RSA public key structure (destination), or `NULL` - * \param kbuf_pub buffer for public key elements, or `NULL` - * \param size target RSA modulus size (in bits) - * \param pubexp public exponent to use, or zero - * \return 1 on success, 0 on error (invalid parameters) - */ -uint32_t br_rsa_i31_keygen( - const br_prng_class **rng_ctx, - br_rsa_private_key *sk, void *kbuf_priv, - br_rsa_public_key *pk, void *kbuf_pub, - unsigned size, uint32_t pubexp); - -/** - * \brief RSA key pair generation with the "i62" engine. - * - * This function is defined only on architecture that offer a 64x64->128 - * opcode. Use `br_rsa_i62_keygen_get()` to dynamically obtain a pointer - * to that function. - * - * \see br_rsa_keygen - * - * \param rng_ctx source PRNG context (already initialized) - * \param sk RSA private key structure (destination) - * \param kbuf_priv buffer for private key elements - * \param pk RSA public key structure (destination), or `NULL` - * \param kbuf_pub buffer for public key elements, or `NULL` - * \param size target RSA modulus size (in bits) - * \param pubexp public exponent to use, or zero - * \return 1 on success, 0 on error (invalid parameters) - */ -uint32_t br_rsa_i62_keygen( - const br_prng_class **rng_ctx, - br_rsa_private_key *sk, void *kbuf_priv, - br_rsa_public_key *pk, void *kbuf_pub, - unsigned size, uint32_t pubexp); - -/** - * \brief Get the RSA "i62" implementation (key pair generation), - * if available. - * - * \return the implementation, or 0. - */ -br_rsa_keygen br_rsa_i62_keygen_get(void); - -/** - * \brief Get "default" RSA implementation (key pair generation). - * - * This returns the preferred implementation of RSA (key pair generation) - * on the current system. - * - * \return the default implementation. - */ -br_rsa_keygen br_rsa_keygen_get_default(void); - -/** - * \brief Type for a modulus computing function. - * - * Such a function computes the public modulus from the private key. The - * encoded modulus (unsigned big-endian) is written on `n`, and the size - * (in bytes) is returned. If `n` is `NULL`, then the size is returned but - * the modulus itself is not computed. - * - * If the key size exceeds an internal limit, 0 is returned. - * - * \param n destination buffer (or `NULL`). - * \param sk RSA private key. - * \return the modulus length (in bytes), or 0. - */ -typedef size_t (*br_rsa_compute_modulus)(void *n, const br_rsa_private_key *sk); - -/** - * \brief Recompute RSA modulus ("i15" engine). - * - * \see br_rsa_compute_modulus - * - * \param n destination buffer (or `NULL`). - * \param sk RSA private key. - * \return the modulus length (in bytes), or 0. - */ -size_t br_rsa_i15_compute_modulus(void *n, const br_rsa_private_key *sk); - -/** - * \brief Recompute RSA modulus ("i31" engine). - * - * \see br_rsa_compute_modulus - * - * \param n destination buffer (or `NULL`). - * \param sk RSA private key. - * \return the modulus length (in bytes), or 0. - */ -size_t br_rsa_i31_compute_modulus(void *n, const br_rsa_private_key *sk); - -/** - * \brief Get "default" RSA implementation (recompute modulus). - * - * This returns the preferred implementation of RSA (recompute modulus) - * on the current system. - * - * \return the default implementation. - */ -br_rsa_compute_modulus br_rsa_compute_modulus_get_default(void); - -/** - * \brief Type for a public exponent computing function. - * - * Such a function recomputes the public exponent from the private key. - * 0 is returned if any of the following occurs: - * - * - Either `p` or `q` is not equal to 3 modulo 4. - * - * - The public exponent does not fit on 32 bits. - * - * - An internal limit is exceeded. - * - * - The private key is invalid in some way. - * - * For all private keys produced by the key generator functions - * (`br_rsa_keygen` type), this function succeeds and returns the true - * public exponent. The public exponent is always an odd integer greater - * than 1. - * - * \return the public exponent, or 0. - */ -typedef uint32_t (*br_rsa_compute_pubexp)(const br_rsa_private_key *sk); - -/** - * \brief Recompute RSA public exponent ("i15" engine). - * - * \see br_rsa_compute_pubexp - * - * \return the public exponent, or 0. - */ -uint32_t br_rsa_i15_compute_pubexp(const br_rsa_private_key *sk); - -/** - * \brief Recompute RSA public exponent ("i31" engine). - * - * \see br_rsa_compute_pubexp - * - * \return the public exponent, or 0. - */ -uint32_t br_rsa_i31_compute_pubexp(const br_rsa_private_key *sk); - -/** - * \brief Get "default" RSA implementation (recompute public exponent). - * - * This returns the preferred implementation of RSA (recompute public - * exponent) on the current system. - * - * \return the default implementation. - */ -br_rsa_compute_pubexp br_rsa_compute_pubexp_get_default(void); - -/** - * \brief Type for a private exponent computing function. - * - * An RSA private key (`br_rsa_private_key`) contains two reduced - * private exponents, which are sufficient to perform private key - * operations. However, standard encoding formats for RSA private keys - * require also a copy of the complete private exponent (non-reduced), - * which this function recomputes. - * - * This function succeeds if all the following conditions hold: - * - * - Both private factors `p` and `q` are equal to 3 modulo 4. - * - * - The provided public exponent `pubexp` is correct, and, in particular, - * is odd, relatively prime to `p-1` and `q-1`, and greater than 1. - * - * - No internal storage limit is exceeded. - * - * For all private keys produced by the key generator functions - * (`br_rsa_keygen` type), this function succeeds. Note that the API - * restricts the public exponent to a maximum size of 32 bits. - * - * The encoded private exponent is written in `d` (unsigned big-endian - * convention), and the length (in bytes) is returned. If `d` is `NULL`, - * then the exponent is not written anywhere, but the length is still - * returned. On error, 0 is returned. - * - * Not all error conditions are detected when `d` is `NULL`; therefore, the - * returned value shall be checked also when actually producing the value. - * - * \param d destination buffer (or `NULL`). - * \param sk RSA private key. - * \param pubexp the public exponent. - * \return the private exponent length (in bytes), or 0. - */ -typedef size_t (*br_rsa_compute_privexp)(void *d, - const br_rsa_private_key *sk, uint32_t pubexp); - -/** - * \brief Recompute RSA private exponent ("i15" engine). - * - * \see br_rsa_compute_privexp - * - * \param d destination buffer (or `NULL`). - * \param sk RSA private key. - * \param pubexp the public exponent. - * \return the private exponent length (in bytes), or 0. - */ -size_t br_rsa_i15_compute_privexp(void *d, - const br_rsa_private_key *sk, uint32_t pubexp); - -/** - * \brief Recompute RSA private exponent ("i31" engine). - * - * \see br_rsa_compute_privexp - * - * \param d destination buffer (or `NULL`). - * \param sk RSA private key. - * \param pubexp the public exponent. - * \return the private exponent length (in bytes), or 0. - */ -size_t br_rsa_i31_compute_privexp(void *d, - const br_rsa_private_key *sk, uint32_t pubexp); - -/** - * \brief Get "default" RSA implementation (recompute private exponent). - * - * This returns the preferred implementation of RSA (recompute private - * exponent) on the current system. - * - * \return the default implementation. - */ -br_rsa_compute_privexp br_rsa_compute_privexp_get_default(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/tls/bearssl/bearssl_ssl.h b/src/tls/bearssl/bearssl_ssl.h deleted file mode 100644 index a603fdbe8..000000000 --- a/src/tls/bearssl/bearssl_ssl.h +++ /dev/null @@ -1,4301 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef BR_BEARSSL_SSL_H__ -#define BR_BEARSSL_SSL_H__ - -#include -#include - -#include "bearssl_block.h" -#include "bearssl_hash.h" -#include "bearssl_hmac.h" -#include "bearssl_prf.h" -#include "bearssl_rand.h" -#include "bearssl_x509.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** \file bearssl_ssl.h - * - * # SSL - * - * For an overview of the SSL/TLS API, see [the BearSSL Web - * site](https://www.bearssl.org/api1.html). - * - * The `BR_TLS_*` constants correspond to the standard cipher suites and - * their values in the [IANA - * registry](http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4). - * - * The `BR_ALERT_*` constants are for standard TLS alert messages. When - * a fatal alert message is sent of received, then the SSL engine context - * status is set to the sum of that alert value (an integer in the 0..255 - * range) and a fixed offset (`BR_ERR_SEND_FATAL_ALERT` for a sent alert, - * `BR_ERR_RECV_FATAL_ALERT` for a received alert). - */ - -/** \brief Optimal input buffer size. */ -#define BR_SSL_BUFSIZE_INPUT (16384 + 325) - -/** \brief Optimal output buffer size. */ -#define BR_SSL_BUFSIZE_OUTPUT (16384 + 85) - -/** \brief Optimal buffer size for monodirectional engine - (shared input/output buffer). */ -#define BR_SSL_BUFSIZE_MONO BR_SSL_BUFSIZE_INPUT - -/** \brief Optimal buffer size for bidirectional engine - (single buffer split into two separate input/output buffers). */ -#define BR_SSL_BUFSIZE_BIDI (BR_SSL_BUFSIZE_INPUT + BR_SSL_BUFSIZE_OUTPUT) - -/* - * Constants for known SSL/TLS protocol versions (SSL 3.0, TLS 1.0, TLS 1.1 - * and TLS 1.2). Note that though there is a constant for SSL 3.0, that - * protocol version is not actually supported. - */ - -/** \brief Protocol version: SSL 3.0 (unsupported). */ -#define BR_SSL30 0x0300 -/** \brief Protocol version: TLS 1.0. */ -#define BR_TLS10 0x0301 -/** \brief Protocol version: TLS 1.1. */ -#define BR_TLS11 0x0302 -/** \brief Protocol version: TLS 1.2. */ -#define BR_TLS12 0x0303 - -/* - * Error constants. They are used to report the reason why a context has - * been marked as failed. - * - * Implementation note: SSL-level error codes should be in the 1..31 - * range. The 32..63 range is for certificate decoding and validation - * errors. Received fatal alerts imply an error code in the 256..511 range. - */ - -/** \brief SSL status: no error so far (0). */ -#define BR_ERR_OK 0 - -/** \brief SSL status: caller-provided parameter is incorrect. */ -#define BR_ERR_BAD_PARAM 1 - -/** \brief SSL status: operation requested by the caller cannot be applied - with the current context state (e.g. reading data while outgoing data - is waiting to be sent). */ -#define BR_ERR_BAD_STATE 2 - -/** \brief SSL status: incoming protocol or record version is unsupported. */ -#define BR_ERR_UNSUPPORTED_VERSION 3 - -/** \brief SSL status: incoming record version does not match the expected - version. */ -#define BR_ERR_BAD_VERSION 4 - -/** \brief SSL status: incoming record length is invalid. */ -#define BR_ERR_BAD_LENGTH 5 - -/** \brief SSL status: incoming record is too large to be processed, or - buffer is too small for the handshake message to send. */ -#define BR_ERR_TOO_LARGE 6 - -/** \brief SSL status: decryption found an invalid padding, or the record - MAC is not correct. */ -#define BR_ERR_BAD_MAC 7 - -/** \brief SSL status: no initial entropy was provided, and none can be - obtained from the OS. */ -#define BR_ERR_NO_RANDOM 8 - -/** \brief SSL status: incoming record type is unknown. */ -#define BR_ERR_UNKNOWN_TYPE 9 - -/** \brief SSL status: incoming record or message has wrong type with - regards to the current engine state. */ -#define BR_ERR_UNEXPECTED 10 - -/** \brief SSL status: ChangeCipherSpec message from the peer has invalid - contents. */ -#define BR_ERR_BAD_CCS 12 - -/** \brief SSL status: alert message from the peer has invalid contents - (odd length). */ -#define BR_ERR_BAD_ALERT 13 - -/** \brief SSL status: incoming handshake message decoding failed. */ -#define BR_ERR_BAD_HANDSHAKE 14 - -/** \brief SSL status: ServerHello contains a session ID which is larger - than 32 bytes. */ -#define BR_ERR_OVERSIZED_ID 15 - -/** \brief SSL status: server wants to use a cipher suite that we did - not claim to support. This is also reported if we tried to advertise - a cipher suite that we do not support. */ -#define BR_ERR_BAD_CIPHER_SUITE 16 - -/** \brief SSL status: server wants to use a compression that we did not - claim to support. */ -#define BR_ERR_BAD_COMPRESSION 17 - -/** \brief SSL status: server's max fragment length does not match - client's. */ -#define BR_ERR_BAD_FRAGLEN 18 - -/** \brief SSL status: secure renegotiation failed. */ -#define BR_ERR_BAD_SECRENEG 19 - -/** \brief SSL status: server sent an extension type that we did not - announce, or used the same extension type several times in a single - ServerHello. */ -#define BR_ERR_EXTRA_EXTENSION 20 - -/** \brief SSL status: invalid Server Name Indication contents (when - used by the server, this extension shall be empty). */ -#define BR_ERR_BAD_SNI 21 - -/** \brief SSL status: invalid ServerHelloDone from the server (length - is not 0). */ -#define BR_ERR_BAD_HELLO_DONE 22 - -/** \brief SSL status: internal limit exceeded (e.g. server's public key - is too large). */ -#define BR_ERR_LIMIT_EXCEEDED 23 - -/** \brief SSL status: Finished message from peer does not match the - expected value. */ -#define BR_ERR_BAD_FINISHED 24 - -/** \brief SSL status: session resumption attempt with distinct version - or cipher suite. */ -#define BR_ERR_RESUME_MISMATCH 25 - -/** \brief SSL status: unsupported or invalid algorithm (ECDHE curve, - signature algorithm, hash function). */ -#define BR_ERR_INVALID_ALGORITHM 26 - -/** \brief SSL status: invalid signature (on ServerKeyExchange from - server, or in CertificateVerify from client). */ -#define BR_ERR_BAD_SIGNATURE 27 - -/** \brief SSL status: peer's public key does not have the proper type - or is not allowed for requested operation. */ -#define BR_ERR_WRONG_KEY_USAGE 28 - -/** \brief SSL status: client did not send a certificate upon request, - or the client certificate could not be validated. */ -#define BR_ERR_NO_CLIENT_AUTH 29 - -/** \brief SSL status: I/O error or premature close on underlying - transport stream. This error code is set only by the simplified - I/O API ("br_sslio_*"). */ -#define BR_ERR_IO 31 - -/** \brief SSL status: base value for a received fatal alert. - - When a fatal alert is received from the peer, the alert value - is added to this constant. */ -#define BR_ERR_RECV_FATAL_ALERT 256 - -/** \brief SSL status: base value for a sent fatal alert. - - When a fatal alert is sent to the peer, the alert value is added - to this constant. */ -#define BR_ERR_SEND_FATAL_ALERT 512 - -/* ===================================================================== */ - -/** - * \brief Decryption engine for SSL. - * - * When processing incoming records, the SSL engine will use a decryption - * engine that uses a specific context structure, and has a set of - * methods (a vtable) that follows this template. - * - * The decryption engine is responsible for applying decryption, verifying - * MAC, and keeping track of the record sequence number. - */ -typedef struct br_sslrec_in_class_ br_sslrec_in_class; -struct br_sslrec_in_class_ { - /** - * \brief Context size (in bytes). - */ - size_t context_size; - - /** - * \brief Test validity of the incoming record length. - * - * This function returns 1 if the announced length for an - * incoming record is valid, 0 otherwise, - * - * \param ctx decryption engine context. - * \param record_len incoming record length. - * \return 1 of a valid length, 0 otherwise. - */ - int (*check_length)(const br_sslrec_in_class *const *ctx, - size_t record_len); - - /** - * \brief Decrypt the incoming record. - * - * This function may assume that the record length is valid - * (it has been previously tested with `check_length()`). - * Decryption is done in place; `*len` is updated with the - * cleartext length, and the address of the first plaintext - * byte is returned. If the record is correct but empty, then - * `*len` is set to 0 and a non-`NULL` pointer is returned. - * - * On decryption/MAC error, `NULL` is returned. - * - * \param ctx decryption engine context. - * \param record_type record type (23 for application data, etc). - * \param version record version. - * \param payload address of encrypted payload. - * \param len pointer to payload length (updated). - * \return pointer to plaintext, or `NULL` on error. - */ - unsigned char *(*decrypt)(const br_sslrec_in_class **ctx, - int record_type, unsigned version, - void *payload, size_t *len); -}; - -/** - * \brief Encryption engine for SSL. - * - * When building outgoing records, the SSL engine will use an encryption - * engine that uses a specific context structure, and has a set of - * methods (a vtable) that follows this template. - * - * The encryption engine is responsible for applying encryption and MAC, - * and keeping track of the record sequence number. - */ -typedef struct br_sslrec_out_class_ br_sslrec_out_class; -struct br_sslrec_out_class_ { - /** - * \brief Context size (in bytes). - */ - size_t context_size; - - /** - * \brief Compute maximum plaintext sizes and offsets. - * - * When this function is called, the `*start` and `*end` - * values contain offsets designating the free area in the - * outgoing buffer for plaintext data; that free area is - * preceded by a 5-byte space which will receive the record - * header. - * - * The `max_plaintext()` function is responsible for adjusting - * both `*start` and `*end` to make room for any record-specific - * header, MAC, padding, and possible split. - * - * \param ctx encryption engine context. - * \param start pointer to start of plaintext offset (updated). - * \param end pointer to start of plaintext offset (updated). - */ - void (*max_plaintext)(const br_sslrec_out_class *const *ctx, - size_t *start, size_t *end); - - /** - * \brief Perform record encryption. - * - * This function encrypts the record. The plaintext address and - * length are provided. Returned value is the start of the - * encrypted record (or sequence of records, if a split was - * performed), _including_ the 5-byte header, and `*len` is - * adjusted to the total size of the record(s), there again - * including the header(s). - * - * \param ctx decryption engine context. - * \param record_type record type (23 for application data, etc). - * \param version record version. - * \param plaintext address of plaintext. - * \param len pointer to plaintext length (updated). - * \return pointer to start of built record. - */ - unsigned char *(*encrypt)(const br_sslrec_out_class **ctx, - int record_type, unsigned version, - void *plaintext, size_t *len); -}; - -/** - * \brief Context for a no-encryption engine. - * - * The no-encryption engine processes outgoing records during the initial - * handshake, before encryption is applied. - */ -typedef struct { - /** \brief No-encryption engine vtable. */ - const br_sslrec_out_class *vtable; -} br_sslrec_out_clear_context; - -/** \brief Static, constant vtable for the no-encryption engine. */ -extern const br_sslrec_out_class br_sslrec_out_clear_vtable; - -/* ===================================================================== */ - -/** - * \brief Record decryption engine class, for CBC mode. - * - * This class type extends the decryption engine class with an - * initialisation method that receives the parameters needed - * for CBC processing: block cipher implementation, block cipher key, - * HMAC parameters (hash function, key, MAC length), and IV. If the - * IV is `NULL`, then a per-record IV will be used (TLS 1.1+). - */ -typedef struct br_sslrec_in_cbc_class_ br_sslrec_in_cbc_class; -struct br_sslrec_in_cbc_class_ { - /** - * \brief Superclass, as first vtable field. - */ - br_sslrec_in_class inner; - - /** - * \brief Engine initialisation method. - * - * This method sets the vtable field in the context. - * - * \param ctx context to initialise. - * \param bc_impl block cipher implementation (CBC decryption). - * \param bc_key block cipher key. - * \param bc_key_len block cipher key length (in bytes). - * \param dig_impl hash function for HMAC. - * \param mac_key HMAC key. - * \param mac_key_len HMAC key length (in bytes). - * \param mac_out_len HMAC output length (in bytes). - * \param iv initial IV (or `NULL`). - */ - void (*init)(const br_sslrec_in_cbc_class **ctx, - const br_block_cbcdec_class *bc_impl, - const void *bc_key, size_t bc_key_len, - const br_hash_class *dig_impl, - const void *mac_key, size_t mac_key_len, size_t mac_out_len, - const void *iv); -}; - -/** - * \brief Record encryption engine class, for CBC mode. - * - * This class type extends the encryption engine class with an - * initialisation method that receives the parameters needed - * for CBC processing: block cipher implementation, block cipher key, - * HMAC parameters (hash function, key, MAC length), and IV. If the - * IV is `NULL`, then a per-record IV will be used (TLS 1.1+). - */ -typedef struct br_sslrec_out_cbc_class_ br_sslrec_out_cbc_class; -struct br_sslrec_out_cbc_class_ { - /** - * \brief Superclass, as first vtable field. - */ - br_sslrec_out_class inner; - - /** - * \brief Engine initialisation method. - * - * This method sets the vtable field in the context. - * - * \param ctx context to initialise. - * \param bc_impl block cipher implementation (CBC encryption). - * \param bc_key block cipher key. - * \param bc_key_len block cipher key length (in bytes). - * \param dig_impl hash function for HMAC. - * \param mac_key HMAC key. - * \param mac_key_len HMAC key length (in bytes). - * \param mac_out_len HMAC output length (in bytes). - * \param iv initial IV (or `NULL`). - */ - void (*init)(const br_sslrec_out_cbc_class **ctx, - const br_block_cbcenc_class *bc_impl, - const void *bc_key, size_t bc_key_len, - const br_hash_class *dig_impl, - const void *mac_key, size_t mac_key_len, size_t mac_out_len, - const void *iv); -}; - -/** - * \brief Context structure for decrypting incoming records with - * CBC + HMAC. - * - * The first field points to the vtable. The other fields are opaque - * and shall not be accessed directly. - */ -typedef struct { - /** \brief Pointer to vtable. */ - const br_sslrec_in_cbc_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - uint64_t seq; - union { - const br_block_cbcdec_class *vtable; - br_aes_gen_cbcdec_keys aes; - br_des_gen_cbcdec_keys des; - } bc; - br_hmac_key_context mac; - size_t mac_len; - unsigned char iv[16]; - int explicit_IV; -#endif -} br_sslrec_in_cbc_context; - -/** - * \brief Static, constant vtable for record decryption with CBC. - */ -extern const br_sslrec_in_cbc_class br_sslrec_in_cbc_vtable; - -/** - * \brief Context structure for encrypting outgoing records with - * CBC + HMAC. - * - * The first field points to the vtable. The other fields are opaque - * and shall not be accessed directly. - */ -typedef struct { - /** \brief Pointer to vtable. */ - const br_sslrec_out_cbc_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - uint64_t seq; - union { - const br_block_cbcenc_class *vtable; - br_aes_gen_cbcenc_keys aes; - br_des_gen_cbcenc_keys des; - } bc; - br_hmac_key_context mac; - size_t mac_len; - unsigned char iv[16]; - int explicit_IV; -#endif -} br_sslrec_out_cbc_context; - -/** - * \brief Static, constant vtable for record encryption with CBC. - */ -extern const br_sslrec_out_cbc_class br_sslrec_out_cbc_vtable; - -/* ===================================================================== */ - -/** - * \brief Record decryption engine class, for GCM mode. - * - * This class type extends the decryption engine class with an - * initialisation method that receives the parameters needed - * for GCM processing: block cipher implementation, block cipher key, - * GHASH implementation, and 4-byte IV. - */ -typedef struct br_sslrec_in_gcm_class_ br_sslrec_in_gcm_class; -struct br_sslrec_in_gcm_class_ { - /** - * \brief Superclass, as first vtable field. - */ - br_sslrec_in_class inner; - - /** - * \brief Engine initialisation method. - * - * This method sets the vtable field in the context. - * - * \param ctx context to initialise. - * \param bc_impl block cipher implementation (CTR). - * \param key block cipher key. - * \param key_len block cipher key length (in bytes). - * \param gh_impl GHASH implementation. - * \param iv static IV (4 bytes). - */ - void (*init)(const br_sslrec_in_gcm_class **ctx, - const br_block_ctr_class *bc_impl, - const void *key, size_t key_len, - br_ghash gh_impl, - const void *iv); -}; - -/** - * \brief Record encryption engine class, for GCM mode. - * - * This class type extends the encryption engine class with an - * initialisation method that receives the parameters needed - * for GCM processing: block cipher implementation, block cipher key, - * GHASH implementation, and 4-byte IV. - */ -typedef struct br_sslrec_out_gcm_class_ br_sslrec_out_gcm_class; -struct br_sslrec_out_gcm_class_ { - /** - * \brief Superclass, as first vtable field. - */ - br_sslrec_out_class inner; - - /** - * \brief Engine initialisation method. - * - * This method sets the vtable field in the context. - * - * \param ctx context to initialise. - * \param bc_impl block cipher implementation (CTR). - * \param key block cipher key. - * \param key_len block cipher key length (in bytes). - * \param gh_impl GHASH implementation. - * \param iv static IV (4 bytes). - */ - void (*init)(const br_sslrec_out_gcm_class **ctx, - const br_block_ctr_class *bc_impl, - const void *key, size_t key_len, - br_ghash gh_impl, - const void *iv); -}; - -/** - * \brief Context structure for processing records with GCM. - * - * The same context structure is used for encrypting and decrypting. - * - * The first field points to the vtable. The other fields are opaque - * and shall not be accessed directly. - */ -typedef struct { - /** \brief Pointer to vtable. */ - union { - const void *gen; - const br_sslrec_in_gcm_class *in; - const br_sslrec_out_gcm_class *out; - } vtable; -#ifndef BR_DOXYGEN_IGNORE - uint64_t seq; - union { - const br_block_ctr_class *vtable; - br_aes_gen_ctr_keys aes; - } bc; - br_ghash gh; - unsigned char iv[4]; - unsigned char h[16]; -#endif -} br_sslrec_gcm_context; - -/** - * \brief Static, constant vtable for record decryption with GCM. - */ -extern const br_sslrec_in_gcm_class br_sslrec_in_gcm_vtable; - -/** - * \brief Static, constant vtable for record encryption with GCM. - */ -extern const br_sslrec_out_gcm_class br_sslrec_out_gcm_vtable; - -/* ===================================================================== */ - -/** - * \brief Record decryption engine class, for ChaCha20+Poly1305. - * - * This class type extends the decryption engine class with an - * initialisation method that receives the parameters needed - * for ChaCha20+Poly1305 processing: ChaCha20 implementation, - * Poly1305 implementation, key, and 12-byte IV. - */ -typedef struct br_sslrec_in_chapol_class_ br_sslrec_in_chapol_class; -struct br_sslrec_in_chapol_class_ { - /** - * \brief Superclass, as first vtable field. - */ - br_sslrec_in_class inner; - - /** - * \brief Engine initialisation method. - * - * This method sets the vtable field in the context. - * - * \param ctx context to initialise. - * \param ichacha ChaCha20 implementation. - * \param ipoly Poly1305 implementation. - * \param key secret key (32 bytes). - * \param iv static IV (12 bytes). - */ - void (*init)(const br_sslrec_in_chapol_class **ctx, - br_chacha20_run ichacha, - br_poly1305_run ipoly, - const void *key, const void *iv); -}; - -/** - * \brief Record encryption engine class, for ChaCha20+Poly1305. - * - * This class type extends the encryption engine class with an - * initialisation method that receives the parameters needed - * for ChaCha20+Poly1305 processing: ChaCha20 implementation, - * Poly1305 implementation, key, and 12-byte IV. - */ -typedef struct br_sslrec_out_chapol_class_ br_sslrec_out_chapol_class; -struct br_sslrec_out_chapol_class_ { - /** - * \brief Superclass, as first vtable field. - */ - br_sslrec_out_class inner; - - /** - * \brief Engine initialisation method. - * - * This method sets the vtable field in the context. - * - * \param ctx context to initialise. - * \param ichacha ChaCha20 implementation. - * \param ipoly Poly1305 implementation. - * \param key secret key (32 bytes). - * \param iv static IV (12 bytes). - */ - void (*init)(const br_sslrec_out_chapol_class **ctx, - br_chacha20_run ichacha, - br_poly1305_run ipoly, - const void *key, const void *iv); -}; - -/** - * \brief Context structure for processing records with ChaCha20+Poly1305. - * - * The same context structure is used for encrypting and decrypting. - * - * The first field points to the vtable. The other fields are opaque - * and shall not be accessed directly. - */ -typedef struct { - /** \brief Pointer to vtable. */ - union { - const void *gen; - const br_sslrec_in_chapol_class *in; - const br_sslrec_out_chapol_class *out; - } vtable; -#ifndef BR_DOXYGEN_IGNORE - uint64_t seq; - unsigned char key[32]; - unsigned char iv[12]; - br_chacha20_run ichacha; - br_poly1305_run ipoly; -#endif -} br_sslrec_chapol_context; - -/** - * \brief Static, constant vtable for record decryption with ChaCha20+Poly1305. - */ -extern const br_sslrec_in_chapol_class br_sslrec_in_chapol_vtable; - -/** - * \brief Static, constant vtable for record encryption with ChaCha20+Poly1305. - */ -extern const br_sslrec_out_chapol_class br_sslrec_out_chapol_vtable; - -/* ===================================================================== */ - -/** - * \brief Record decryption engine class, for CCM mode. - * - * This class type extends the decryption engine class with an - * initialisation method that receives the parameters needed - * for CCM processing: block cipher implementation, block cipher key, - * and 4-byte IV. - */ -typedef struct br_sslrec_in_ccm_class_ br_sslrec_in_ccm_class; -struct br_sslrec_in_ccm_class_ { - /** - * \brief Superclass, as first vtable field. - */ - br_sslrec_in_class inner; - - /** - * \brief Engine initialisation method. - * - * This method sets the vtable field in the context. - * - * \param ctx context to initialise. - * \param bc_impl block cipher implementation (CTR+CBC). - * \param key block cipher key. - * \param key_len block cipher key length (in bytes). - * \param iv static IV (4 bytes). - * \param tag_len tag length (in bytes) - */ - void (*init)(const br_sslrec_in_ccm_class **ctx, - const br_block_ctrcbc_class *bc_impl, - const void *key, size_t key_len, - const void *iv, size_t tag_len); -}; - -/** - * \brief Record encryption engine class, for CCM mode. - * - * This class type extends the encryption engine class with an - * initialisation method that receives the parameters needed - * for CCM processing: block cipher implementation, block cipher key, - * and 4-byte IV. - */ -typedef struct br_sslrec_out_ccm_class_ br_sslrec_out_ccm_class; -struct br_sslrec_out_ccm_class_ { - /** - * \brief Superclass, as first vtable field. - */ - br_sslrec_out_class inner; - - /** - * \brief Engine initialisation method. - * - * This method sets the vtable field in the context. - * - * \param ctx context to initialise. - * \param bc_impl block cipher implementation (CTR+CBC). - * \param key block cipher key. - * \param key_len block cipher key length (in bytes). - * \param iv static IV (4 bytes). - * \param tag_len tag length (in bytes) - */ - void (*init)(const br_sslrec_out_ccm_class **ctx, - const br_block_ctrcbc_class *bc_impl, - const void *key, size_t key_len, - const void *iv, size_t tag_len); -}; - -/** - * \brief Context structure for processing records with CCM. - * - * The same context structure is used for encrypting and decrypting. - * - * The first field points to the vtable. The other fields are opaque - * and shall not be accessed directly. - */ -typedef struct { - /** \brief Pointer to vtable. */ - union { - const void *gen; - const br_sslrec_in_ccm_class *in; - const br_sslrec_out_ccm_class *out; - } vtable; -#ifndef BR_DOXYGEN_IGNORE - uint64_t seq; - union { - const br_block_ctrcbc_class *vtable; - br_aes_gen_ctrcbc_keys aes; - } bc; - unsigned char iv[4]; - size_t tag_len; -#endif -} br_sslrec_ccm_context; - -/** - * \brief Static, constant vtable for record decryption with CCM. - */ -extern const br_sslrec_in_ccm_class br_sslrec_in_ccm_vtable; - -/** - * \brief Static, constant vtable for record encryption with CCM. - */ -extern const br_sslrec_out_ccm_class br_sslrec_out_ccm_vtable; - -/* ===================================================================== */ - -/** - * \brief Type for session parameters, to be saved for session resumption. - */ -typedef struct { - /** \brief Session ID buffer. */ - unsigned char session_id[32]; - /** \brief Session ID length (in bytes, at most 32). */ - unsigned char session_id_len; - /** \brief Protocol version. */ - uint16_t version; - /** \brief Cipher suite. */ - uint16_t cipher_suite; - /** \brief Master secret. */ - unsigned char master_secret[48]; -} br_ssl_session_parameters; - -#ifndef BR_DOXYGEN_IGNORE -/* - * Maximum number of cipher suites supported by a client or server. - */ -#define BR_MAX_CIPHER_SUITES 48 -#endif - -/** - * \brief Context structure for SSL engine. - * - * This structure is common to the client and server; both the client - * context (`br_ssl_client_context`) and the server context - * (`br_ssl_server_context`) include a `br_ssl_engine_context` as their - * first field. - * - * The engine context manages records, including alerts, closures, and - * transitions to new encryption/MAC algorithms. Processing of handshake - * records is delegated to externally provided code. This structure - * should not be used directly. - * - * Structure contents are opaque and shall not be accessed directly. - */ -typedef struct { -#ifndef BR_DOXYGEN_IGNORE - /* - * The error code. When non-zero, then the state is "failed" and - * no I/O may occur until reset. - */ - int err; - - /* - * Configured I/O buffers. They are either disjoint, or identical. - */ - unsigned char *ibuf, *obuf; - size_t ibuf_len, obuf_len; - - /* - * Maximum fragment length applies to outgoing records; incoming - * records can be processed as long as they fit in the input - * buffer. It is guaranteed that incoming records at least as big - * as max_frag_len can be processed. - */ - uint16_t max_frag_len; - unsigned char log_max_frag_len; - unsigned char peer_log_max_frag_len; - - /* - * Buffering management registers. - */ - size_t ixa, ixb, ixc; - size_t oxa, oxb, oxc; - unsigned char iomode; - unsigned char incrypt; - - /* - * Shutdown flag: when set to non-zero, incoming record bytes - * will not be accepted anymore. This is used after a close_notify - * has been received: afterwards, the engine no longer claims that - * it could receive bytes from the transport medium. - */ - unsigned char shutdown_recv; - - /* - * 'record_type_in' is set to the incoming record type when the - * record header has been received. - * 'record_type_out' is used to make the next outgoing record - * header when it is ready to go. - */ - unsigned char record_type_in, record_type_out; - - /* - * When a record is received, its version is extracted: - * -- if 'version_in' is 0, then it is set to the received version; - * -- otherwise, if the received version is not identical to - * the 'version_in' contents, then a failure is reported. - * - * This implements the SSL requirement that all records shall - * use the negotiated protocol version, once decided (in the - * ServerHello). It is up to the handshake handler to adjust this - * field when necessary. - */ - uint16_t version_in; - - /* - * 'version_out' is used when the next outgoing record is ready - * to go. - */ - uint16_t version_out; - - /* - * Record handler contexts. - */ - union { - const br_sslrec_in_class *vtable; - br_sslrec_in_cbc_context cbc; - br_sslrec_gcm_context gcm; - br_sslrec_chapol_context chapol; - br_sslrec_ccm_context ccm; - } in; - union { - const br_sslrec_out_class *vtable; - br_sslrec_out_clear_context clear; - br_sslrec_out_cbc_context cbc; - br_sslrec_gcm_context gcm; - br_sslrec_chapol_context chapol; - br_sslrec_ccm_context ccm; - } out; - - /* - * The "application data" flag. Value: - * 0 handshake is in process, no application data acceptable - * 1 application data can be sent and received - * 2 closing, no application data can be sent, but some - * can still be received (and discarded) - */ - unsigned char application_data; - - /* - * Context RNG. - * - * rng_init_done is initially 0. It is set to 1 when the - * basic structure of the RNG is set, and 2 when some - * entropy has been pushed in. The value 2 marks the RNG - * as "properly seeded". - * - * rng_os_rand_done is initially 0. It is set to 1 when - * some seeding from the OS or hardware has been attempted. - */ - br_hmac_drbg_context rng; - int rng_init_done; - int rng_os_rand_done; - - /* - * Supported minimum and maximum versions, and cipher suites. - */ - uint16_t version_min; - uint16_t version_max; - uint16_t suites_buf[BR_MAX_CIPHER_SUITES]; - unsigned char suites_num; - - /* - * For clients, the server name to send as a SNI extension. For - * servers, the name received in the SNI extension (if any). - */ - char server_name[256]; - - /* - * "Security parameters". These are filled by the handshake - * handler, and used when switching encryption state. - */ - unsigned char client_random[32]; - unsigned char server_random[32]; - br_ssl_session_parameters session; - - /* - * ECDHE elements: curve and point from the peer. The server also - * uses that buffer for the point to send to the client. - */ - unsigned char ecdhe_curve; - unsigned char ecdhe_point[133]; - unsigned char ecdhe_point_len; - - /* - * Secure renegotiation (RFC 5746): 'reneg' can be: - * 0 first handshake (server support is not known) - * 1 peer does not support secure renegotiation - * 2 peer supports secure renegotiation - * - * The saved_finished buffer contains the client and the - * server "Finished" values from the last handshake, in - * that order (12 bytes each). - */ - unsigned char reneg; - unsigned char saved_finished[24]; - - /* - * Behavioural flags. - */ - uint32_t flags; - - /* - * Context variables for the handshake processor. The 'pad' must - * be large enough to accommodate an RSA-encrypted pre-master - * secret, or an RSA signature; since we want to support up to - * RSA-4096, this means at least 512 bytes. (Other pad usages - * require its length to be at least 256.) - */ - struct { - uint32_t *dp; - uint32_t *rp; - const unsigned char *ip; - } cpu; - uint32_t dp_stack[32]; - uint32_t rp_stack[32]; - unsigned char pad[512]; - unsigned char *hbuf_in, *hbuf_out, *saved_hbuf_out; - size_t hlen_in, hlen_out; - void (*hsrun)(void *ctx); - - /* - * The 'action' value communicates OOB information between the - * engine and the handshake processor. - * - * From the engine: - * 0 invocation triggered by I/O - * 1 invocation triggered by explicit close - * 2 invocation triggered by explicit renegotiation - */ - unsigned char action; - - /* - * State for alert messages. Value is either 0, or the value of - * the alert level byte (level is either 1 for warning, or 2 for - * fatal; we convert all other values to 'fatal'). - */ - unsigned char alert; - - /* - * Closure flags. This flag is set when a close_notify has been - * received from the peer. - */ - unsigned char close_received; - - /* - * Multi-hasher for the handshake messages. The handshake handler - * is responsible for resetting it when appropriate. - */ - br_multihash_context mhash; - - /* - * Pointer to the X.509 engine. The engine is supposed to be - * already initialized. It is used to validate the peer's - * certificate. - */ - const br_x509_class **x509ctx; - - /* - * Certificate chain to send. This is used by both client and - * server, when they send their respective Certificate messages. - * If chain_len is 0, then chain may be NULL. - */ - const br_x509_certificate *chain; - size_t chain_len; - const unsigned char *cert_cur; - size_t cert_len; - - /* - * List of supported protocol names (ALPN extension). If unset, - * (number of names is 0), then: - * - the client sends no ALPN extension; - * - the server ignores any incoming ALPN extension. - * - * Otherwise: - * - the client sends an ALPN extension with all the names; - * - the server selects the first protocol in its list that - * the client also supports, or fails (fatal alert 120) - * if the client sends an ALPN extension and there is no - * match. - * - * The 'selected_protocol' field contains 1+n if the matching - * name has index n in the list (the value is 0 if no match was - * performed, e.g. the peer did not send an ALPN extension). - */ - const char **protocol_names; - uint16_t protocol_names_num; - uint16_t selected_protocol; - - /* - * Pointers to implementations; left to NULL for unsupported - * functions. For the raw hash functions, implementations are - * referenced from the multihasher (mhash field). - */ - br_tls_prf_impl prf10; - br_tls_prf_impl prf_sha256; - br_tls_prf_impl prf_sha384; - const br_block_cbcenc_class *iaes_cbcenc; - const br_block_cbcdec_class *iaes_cbcdec; - const br_block_ctr_class *iaes_ctr; - const br_block_ctrcbc_class *iaes_ctrcbc; - const br_block_cbcenc_class *ides_cbcenc; - const br_block_cbcdec_class *ides_cbcdec; - br_ghash ighash; - br_chacha20_run ichacha; - br_poly1305_run ipoly; - const br_sslrec_in_cbc_class *icbc_in; - const br_sslrec_out_cbc_class *icbc_out; - const br_sslrec_in_gcm_class *igcm_in; - const br_sslrec_out_gcm_class *igcm_out; - const br_sslrec_in_chapol_class *ichapol_in; - const br_sslrec_out_chapol_class *ichapol_out; - const br_sslrec_in_ccm_class *iccm_in; - const br_sslrec_out_ccm_class *iccm_out; - const br_ec_impl *iec; - br_rsa_pkcs1_vrfy irsavrfy; - br_ecdsa_vrfy iecdsa; -#endif -} br_ssl_engine_context; - -/** - * \brief Get currently defined engine behavioural flags. - * - * \param cc SSL engine context. - * \return the flags. - */ -static inline uint32_t -br_ssl_engine_get_flags(br_ssl_engine_context *cc) -{ - return cc->flags; -} - -/** - * \brief Set all engine behavioural flags. - * - * \param cc SSL engine context. - * \param flags new value for all flags. - */ -static inline void -br_ssl_engine_set_all_flags(br_ssl_engine_context *cc, uint32_t flags) -{ - cc->flags = flags; -} - -/** - * \brief Set some engine behavioural flags. - * - * The flags set in the `flags` parameter are set in the context; other - * flags are untouched. - * - * \param cc SSL engine context. - * \param flags additional set flags. - */ -static inline void -br_ssl_engine_add_flags(br_ssl_engine_context *cc, uint32_t flags) -{ - cc->flags |= flags; -} - -/** - * \brief Clear some engine behavioural flags. - * - * The flags set in the `flags` parameter are cleared from the context; other - * flags are untouched. - * - * \param cc SSL engine context. - * \param flags flags to remove. - */ -static inline void -br_ssl_engine_remove_flags(br_ssl_engine_context *cc, uint32_t flags) -{ - cc->flags &= ~flags; -} - -/** - * \brief Behavioural flag: enforce server preferences. - * - * If this flag is set, then the server will enforce its own cipher suite - * preference order; otherwise, it follows the client preferences. - */ -#define BR_OPT_ENFORCE_SERVER_PREFERENCES ((uint32_t)1 << 0) - -/** - * \brief Behavioural flag: disable renegotiation. - * - * If this flag is set, then renegotiations are rejected unconditionally: - * they won't be honoured if asked for programmatically, and requests from - * the peer are rejected. - */ -#define BR_OPT_NO_RENEGOTIATION ((uint32_t)1 << 1) - -/** - * \brief Behavioural flag: tolerate lack of client authentication. - * - * If this flag is set in a server and the server requests a client - * certificate, but the authentication fails (the client does not send - * a certificate, or the client's certificate chain cannot be validated), - * then the connection keeps on. Without this flag, a failed client - * authentication terminates the connection. - * - * Notes: - * - * - If the client's certificate can be validated and its public key is - * supported, then a wrong signature value terminates the connection - * regardless of that flag. - * - * - If using full-static ECDH, then a failure to validate the client's - * certificate prevents the handshake from succeeding. - */ -#define BR_OPT_TOLERATE_NO_CLIENT_AUTH ((uint32_t)1 << 2) - -/** - * \brief Behavioural flag: fail on application protocol mismatch. - * - * The ALPN extension ([RFC 7301](https://tools.ietf.org/html/rfc7301)) - * allows the client to send a list of application protocol names, and - * the server to select one. A mismatch is one of the following occurrences: - * - * - On the client: the client sends a list of names, the server - * responds with a protocol name which is _not_ part of the list of - * names sent by the client. - * - * - On the server: the client sends a list of names, and the server - * is also configured with a list of names, but there is no common - * protocol name between the two lists. - * - * Normal behaviour in case of mismatch is to report no matching name - * (`br_ssl_engine_get_selected_protocol()` returns `NULL`) and carry on. - * If the flag is set, then a mismatch implies a protocol failure (if - * the mismatch is detected by the server, it will send a fatal alert). - * - * Note: even with this flag, `br_ssl_engine_get_selected_protocol()` - * may still return `NULL` if the client or the server does not send an - * ALPN extension at all. - */ -#define BR_OPT_FAIL_ON_ALPN_MISMATCH ((uint32_t)1 << 3) - -/** - * \brief Set the minimum and maximum supported protocol versions. - * - * The two provided versions MUST be supported by the implementation - * (i.e. TLS 1.0, 1.1 and 1.2), and `version_max` MUST NOT be lower - * than `version_min`. - * - * \param cc SSL engine context. - * \param version_min minimum supported TLS version. - * \param version_max maximum supported TLS version. - */ -static inline void -br_ssl_engine_set_versions(br_ssl_engine_context *cc, - unsigned version_min, unsigned version_max) -{ - cc->version_min = version_min; - cc->version_max = version_max; -} - -/** - * \brief Set the list of cipher suites advertised by this context. - * - * The provided array is copied into the context. It is the caller - * responsibility to ensure that all provided suites will be supported - * by the context. The engine context has enough room to receive _all_ - * suites supported by the implementation. The provided array MUST NOT - * contain duplicates. - * - * If the engine is for a client, the "signaling" pseudo-cipher suite - * `TLS_FALLBACK_SCSV` can be added at the end of the list, if the - * calling application is performing a voluntary downgrade (voluntary - * downgrades are not recommended, but if such a downgrade is done, then - * adding the fallback pseudo-suite is a good idea). - * - * \param cc SSL engine context. - * \param suites cipher suites. - * \param suites_num number of cipher suites. - */ -void br_ssl_engine_set_suites(br_ssl_engine_context *cc, - const uint16_t *suites, size_t suites_num); - -/** - * \brief Set the X.509 engine. - * - * The caller shall ensure that the X.509 engine is properly initialised. - * - * \param cc SSL engine context. - * \param x509ctx X.509 certificate validation context. - */ -static inline void -br_ssl_engine_set_x509(br_ssl_engine_context *cc, const br_x509_class **x509ctx) -{ - cc->x509ctx = x509ctx; -} - -/** - * \brief Set the supported protocol names. - * - * Protocol names are part of the ALPN extension ([RFC - * 7301](https://tools.ietf.org/html/rfc7301)). Each protocol name is a - * character string, containing no more than 255 characters (256 with the - * terminating zero). When names are set, then: - * - * - The client will send an ALPN extension, containing the names. If - * the server responds with an ALPN extension, the client will verify - * that the response contains one of its name, and report that name - * through `br_ssl_engine_get_selected_protocol()`. - * - * - The server will parse incoming ALPN extension (from clients), and - * try to find a common protocol; if none is found, the connection - * is aborted with a fatal alert. On match, a response ALPN extension - * is sent, and name is reported through - * `br_ssl_engine_get_selected_protocol()`. - * - * The provided array is linked in, and must remain valid while the - * connection is live. - * - * Names MUST NOT be empty. Names MUST NOT be longer than 255 characters - * (excluding the terminating 0). - * - * \param ctx SSL engine context. - * \param names list of protocol names (zero-terminated). - * \param num number of protocol names (MUST be 1 or more). - */ -static inline void -br_ssl_engine_set_protocol_names(br_ssl_engine_context *ctx, - const char **names, size_t num) -{ - ctx->protocol_names = names; - ctx->protocol_names_num = num; -} - -/** - * \brief Get the selected protocol. - * - * If this context was initialised with a non-empty list of protocol - * names, and both client and server sent ALPN extensions during the - * handshake, and a common name was found, then that name is returned. - * Otherwise, `NULL` is returned. - * - * The returned pointer is one of the pointers provided to the context - * with `br_ssl_engine_set_protocol_names()`. - * - * \return the selected protocol, or `NULL`. - */ -static inline const char * -br_ssl_engine_get_selected_protocol(br_ssl_engine_context *ctx) -{ - unsigned k; - - k = ctx->selected_protocol; - return (k == 0 || k == 0xFFFF) ? NULL : ctx->protocol_names[k - 1]; -} - -/** - * \brief Set a hash function implementation (by ID). - * - * Hash functions set with this call will be used for SSL/TLS specific - * usages, not X.509 certificate validation. Only "standard" hash functions - * may be set (MD5, SHA-1, SHA-224, SHA-256, SHA-384, SHA-512). If `impl` - * is `NULL`, then the hash function support is removed, not added. - * - * \param ctx SSL engine context. - * \param id hash function identifier. - * \param impl hash function implementation (or `NULL`). - */ -static inline void -br_ssl_engine_set_hash(br_ssl_engine_context *ctx, - int id, const br_hash_class *impl) -{ - br_multihash_setimpl(&ctx->mhash, id, impl); -} - -/** - * \brief Get a hash function implementation (by ID). - * - * This function retrieves a hash function implementation which was - * set with `br_ssl_engine_set_hash()`. - * - * \param ctx SSL engine context. - * \param id hash function identifier. - * \return the hash function implementation (or `NULL`). - */ -static inline const br_hash_class * -br_ssl_engine_get_hash(br_ssl_engine_context *ctx, int id) -{ - return br_multihash_getimpl(&ctx->mhash, id); -} - -/** - * \brief Set the PRF implementation (for TLS 1.0 and 1.1). - * - * This function sets (or removes, if `impl` is `NULL`) the implementation - * for the PRF used in TLS 1.0 and 1.1. - * - * \param cc SSL engine context. - * \param impl PRF implementation (or `NULL`). - */ -static inline void -br_ssl_engine_set_prf10(br_ssl_engine_context *cc, br_tls_prf_impl impl) -{ - cc->prf10 = impl; -} - -/** - * \brief Set the PRF implementation with SHA-256 (for TLS 1.2). - * - * This function sets (or removes, if `impl` is `NULL`) the implementation - * for the SHA-256 variant of the PRF used in TLS 1.2. - * - * \param cc SSL engine context. - * \param impl PRF implementation (or `NULL`). - */ -static inline void -br_ssl_engine_set_prf_sha256(br_ssl_engine_context *cc, br_tls_prf_impl impl) -{ - cc->prf_sha256 = impl; -} - -/** - * \brief Set the PRF implementation with SHA-384 (for TLS 1.2). - * - * This function sets (or removes, if `impl` is `NULL`) the implementation - * for the SHA-384 variant of the PRF used in TLS 1.2. - * - * \param cc SSL engine context. - * \param impl PRF implementation (or `NULL`). - */ -static inline void -br_ssl_engine_set_prf_sha384(br_ssl_engine_context *cc, br_tls_prf_impl impl) -{ - cc->prf_sha384 = impl; -} - -/** - * \brief Set the AES/CBC implementations. - * - * \param cc SSL engine context. - * \param impl_enc AES/CBC encryption implementation (or `NULL`). - * \param impl_dec AES/CBC decryption implementation (or `NULL`). - */ -static inline void -br_ssl_engine_set_aes_cbc(br_ssl_engine_context *cc, - const br_block_cbcenc_class *impl_enc, - const br_block_cbcdec_class *impl_dec) -{ - cc->iaes_cbcenc = impl_enc; - cc->iaes_cbcdec = impl_dec; -} - -/** - * \brief Set the "default" AES/CBC implementations. - * - * This function configures in the engine the AES implementations that - * should provide best runtime performance on the local system, while - * still being safe (in particular, constant-time). It also sets the - * handlers for CBC records. - * - * \param cc SSL engine context. - */ -void br_ssl_engine_set_default_aes_cbc(br_ssl_engine_context *cc); - -/** - * \brief Set the AES/CTR implementation. - * - * \param cc SSL engine context. - * \param impl AES/CTR encryption/decryption implementation (or `NULL`). - */ -static inline void -br_ssl_engine_set_aes_ctr(br_ssl_engine_context *cc, - const br_block_ctr_class *impl) -{ - cc->iaes_ctr = impl; -} - -/** - * \brief Set the "default" implementations for AES/GCM (AES/CTR + GHASH). - * - * This function configures in the engine the AES/CTR and GHASH - * implementation that should provide best runtime performance on the local - * system, while still being safe (in particular, constant-time). It also - * sets the handlers for GCM records. - * - * \param cc SSL engine context. - */ -void br_ssl_engine_set_default_aes_gcm(br_ssl_engine_context *cc); - -/** - * \brief Set the DES/CBC implementations. - * - * \param cc SSL engine context. - * \param impl_enc DES/CBC encryption implementation (or `NULL`). - * \param impl_dec DES/CBC decryption implementation (or `NULL`). - */ -static inline void -br_ssl_engine_set_des_cbc(br_ssl_engine_context *cc, - const br_block_cbcenc_class *impl_enc, - const br_block_cbcdec_class *impl_dec) -{ - cc->ides_cbcenc = impl_enc; - cc->ides_cbcdec = impl_dec; -} - -/** - * \brief Set the "default" DES/CBC implementations. - * - * This function configures in the engine the DES implementations that - * should provide best runtime performance on the local system, while - * still being safe (in particular, constant-time). It also sets the - * handlers for CBC records. - * - * \param cc SSL engine context. - */ -void br_ssl_engine_set_default_des_cbc(br_ssl_engine_context *cc); - -/** - * \brief Set the GHASH implementation (used in GCM mode). - * - * \param cc SSL engine context. - * \param impl GHASH implementation (or `NULL`). - */ -static inline void -br_ssl_engine_set_ghash(br_ssl_engine_context *cc, br_ghash impl) -{ - cc->ighash = impl; -} - -/** - * \brief Set the ChaCha20 implementation. - * - * \param cc SSL engine context. - * \param ichacha ChaCha20 implementation (or `NULL`). - */ -static inline void -br_ssl_engine_set_chacha20(br_ssl_engine_context *cc, - br_chacha20_run ichacha) -{ - cc->ichacha = ichacha; -} - -/** - * \brief Set the Poly1305 implementation. - * - * \param cc SSL engine context. - * \param ipoly Poly1305 implementation (or `NULL`). - */ -static inline void -br_ssl_engine_set_poly1305(br_ssl_engine_context *cc, - br_poly1305_run ipoly) -{ - cc->ipoly = ipoly; -} - -/** - * \brief Set the "default" ChaCha20 and Poly1305 implementations. - * - * This function configures in the engine the ChaCha20 and Poly1305 - * implementations that should provide best runtime performance on the - * local system, while still being safe (in particular, constant-time). - * It also sets the handlers for ChaCha20+Poly1305 records. - * - * \param cc SSL engine context. - */ -void br_ssl_engine_set_default_chapol(br_ssl_engine_context *cc); - -/** - * \brief Set the AES/CTR+CBC implementation. - * - * \param cc SSL engine context. - * \param impl AES/CTR+CBC encryption/decryption implementation (or `NULL`). - */ -static inline void -br_ssl_engine_set_aes_ctrcbc(br_ssl_engine_context *cc, - const br_block_ctrcbc_class *impl) -{ - cc->iaes_ctrcbc = impl; -} - -/** - * \brief Set the "default" implementations for AES/CCM. - * - * This function configures in the engine the AES/CTR+CBC - * implementation that should provide best runtime performance on the local - * system, while still being safe (in particular, constant-time). It also - * sets the handlers for CCM records. - * - * \param cc SSL engine context. - */ -void br_ssl_engine_set_default_aes_ccm(br_ssl_engine_context *cc); - -/** - * \brief Set the record encryption and decryption engines for CBC + HMAC. - * - * \param cc SSL engine context. - * \param impl_in record CBC decryption implementation (or `NULL`). - * \param impl_out record CBC encryption implementation (or `NULL`). - */ -static inline void -br_ssl_engine_set_cbc(br_ssl_engine_context *cc, - const br_sslrec_in_cbc_class *impl_in, - const br_sslrec_out_cbc_class *impl_out) -{ - cc->icbc_in = impl_in; - cc->icbc_out = impl_out; -} - -/** - * \brief Set the record encryption and decryption engines for GCM. - * - * \param cc SSL engine context. - * \param impl_in record GCM decryption implementation (or `NULL`). - * \param impl_out record GCM encryption implementation (or `NULL`). - */ -static inline void -br_ssl_engine_set_gcm(br_ssl_engine_context *cc, - const br_sslrec_in_gcm_class *impl_in, - const br_sslrec_out_gcm_class *impl_out) -{ - cc->igcm_in = impl_in; - cc->igcm_out = impl_out; -} - -/** - * \brief Set the record encryption and decryption engines for CCM. - * - * \param cc SSL engine context. - * \param impl_in record CCM decryption implementation (or `NULL`). - * \param impl_out record CCM encryption implementation (or `NULL`). - */ -static inline void -br_ssl_engine_set_ccm(br_ssl_engine_context *cc, - const br_sslrec_in_ccm_class *impl_in, - const br_sslrec_out_ccm_class *impl_out) -{ - cc->iccm_in = impl_in; - cc->iccm_out = impl_out; -} - -/** - * \brief Set the record encryption and decryption engines for - * ChaCha20+Poly1305. - * - * \param cc SSL engine context. - * \param impl_in record ChaCha20 decryption implementation (or `NULL`). - * \param impl_out record ChaCha20 encryption implementation (or `NULL`). - */ -static inline void -br_ssl_engine_set_chapol(br_ssl_engine_context *cc, - const br_sslrec_in_chapol_class *impl_in, - const br_sslrec_out_chapol_class *impl_out) -{ - cc->ichapol_in = impl_in; - cc->ichapol_out = impl_out; -} - -/** - * \brief Set the EC implementation. - * - * The elliptic curve implementation will be used for ECDH and ECDHE - * cipher suites, and for ECDSA support. - * - * \param cc SSL engine context. - * \param iec EC implementation (or `NULL`). - */ -static inline void -br_ssl_engine_set_ec(br_ssl_engine_context *cc, const br_ec_impl *iec) -{ - cc->iec = iec; -} - -/** - * \brief Set the "default" EC implementation. - * - * This function sets the elliptic curve implementation for ECDH and - * ECDHE cipher suites, and for ECDSA support. It selects the fastest - * implementation on the current system. - * - * \param cc SSL engine context. - */ -void br_ssl_engine_set_default_ec(br_ssl_engine_context *cc); - -/** - * \brief Get the EC implementation configured in the provided engine. - * - * \param cc SSL engine context. - * \return the EC implementation. - */ -static inline const br_ec_impl * -br_ssl_engine_get_ec(br_ssl_engine_context *cc) -{ - return cc->iec; -} - -/** - * \brief Set the RSA signature verification implementation. - * - * On the client, this is used to verify the server's signature on its - * ServerKeyExchange message (for ECDHE_RSA cipher suites). On the server, - * this is used to verify the client's CertificateVerify message (if a - * client certificate is requested, and that certificate contains a RSA key). - * - * \param cc SSL engine context. - * \param irsavrfy RSA signature verification implementation. - */ -static inline void -br_ssl_engine_set_rsavrfy(br_ssl_engine_context *cc, br_rsa_pkcs1_vrfy irsavrfy) -{ - cc->irsavrfy = irsavrfy; -} - -/** - * \brief Set the "default" RSA implementation (signature verification). - * - * This function sets the RSA implementation (signature verification) - * to the fastest implementation available on the current platform. - * - * \param cc SSL engine context. - */ -void br_ssl_engine_set_default_rsavrfy(br_ssl_engine_context *cc); - -/** - * \brief Get the RSA implementation (signature verification) configured - * in the provided engine. - * - * \param cc SSL engine context. - * \return the RSA signature verification implementation. - */ -static inline br_rsa_pkcs1_vrfy -br_ssl_engine_get_rsavrfy(br_ssl_engine_context *cc) -{ - return cc->irsavrfy; -} - -/* - * \brief Set the ECDSA implementation (signature verification). - * - * On the client, this is used to verify the server's signature on its - * ServerKeyExchange message (for ECDHE_ECDSA cipher suites). On the server, - * this is used to verify the client's CertificateVerify message (if a - * client certificate is requested, that certificate contains an EC key, - * and full-static ECDH is not used). - * - * The ECDSA implementation will use the EC core implementation configured - * in the engine context. - * - * \param cc client context. - * \param iecdsa ECDSA verification implementation. - */ -static inline void -br_ssl_engine_set_ecdsa(br_ssl_engine_context *cc, br_ecdsa_vrfy iecdsa) -{ - cc->iecdsa = iecdsa; -} - -/** - * \brief Set the "default" ECDSA implementation (signature verification). - * - * This function sets the ECDSA implementation (signature verification) - * to the fastest implementation available on the current platform. This - * call also sets the elliptic curve implementation itself, there again - * to the fastest EC implementation available. - * - * \param cc SSL engine context. - */ -void br_ssl_engine_set_default_ecdsa(br_ssl_engine_context *cc); - -/** - * \brief Get the ECDSA implementation (signature verification) configured - * in the provided engine. - * - * \param cc SSL engine context. - * \return the ECDSA signature verification implementation. - */ -static inline br_ecdsa_vrfy -br_ssl_engine_get_ecdsa(br_ssl_engine_context *cc) -{ - return cc->iecdsa; -} - -/** - * \brief Set the I/O buffer for the SSL engine. - * - * Once this call has been made, `br_ssl_client_reset()` or - * `br_ssl_server_reset()` MUST be called before using the context. - * - * The provided buffer will be used as long as the engine context is - * used. The caller is responsible for keeping it available. - * - * If `bidi` is 0, then the engine will operate in half-duplex mode - * (it won't be able to send data while there is unprocessed incoming - * data in the buffer, and it won't be able to receive data while there - * is unsent data in the buffer). The optimal buffer size in half-duplex - * mode is `BR_SSL_BUFSIZE_MONO`; if the buffer is larger, then extra - * bytes are ignored. If the buffer is smaller, then this limits the - * capacity of the engine to support all allowed record sizes. - * - * If `bidi` is 1, then the engine will split the buffer into two - * parts, for separate handling of outgoing and incoming data. This - * enables full-duplex processing, but requires more RAM. The optimal - * buffer size in full-duplex mode is `BR_SSL_BUFSIZE_BIDI`; if the - * buffer is larger, then extra bytes are ignored. If the buffer is - * smaller, then the split will favour the incoming part, so that - * interoperability is maximised. - * - * \param cc SSL engine context - * \param iobuf I/O buffer. - * \param iobuf_len I/O buffer length (in bytes). - * \param bidi non-zero for full-duplex mode. - */ -void br_ssl_engine_set_buffer(br_ssl_engine_context *cc, - void *iobuf, size_t iobuf_len, int bidi); - -/** - * \brief Set the I/O buffers for the SSL engine. - * - * Once this call has been made, `br_ssl_client_reset()` or - * `br_ssl_server_reset()` MUST be called before using the context. - * - * This function is similar to `br_ssl_engine_set_buffer()`, except - * that it enforces full-duplex mode, and the two I/O buffers are - * provided as separate chunks. - * - * The macros `BR_SSL_BUFSIZE_INPUT` and `BR_SSL_BUFSIZE_OUTPUT` - * evaluate to the optimal (maximum) sizes for the input and output - * buffer, respectively. - * - * \param cc SSL engine context - * \param ibuf input buffer. - * \param ibuf_len input buffer length (in bytes). - * \param obuf output buffer. - * \param obuf_len output buffer length (in bytes). - */ -void br_ssl_engine_set_buffers_bidi(br_ssl_engine_context *cc, - void *ibuf, size_t ibuf_len, void *obuf, size_t obuf_len); - -/** - * \brief Inject some "initial entropy" in the context. - * - * This entropy will be added to what can be obtained from the - * underlying operating system, if that OS is supported. - * - * This function may be called several times; all injected entropy chunks - * are cumulatively mixed. - * - * If entropy gathering from the OS is supported and compiled in, then this - * step is optional. Otherwise, it is mandatory to inject randomness, and - * the caller MUST take care to push (as one or several successive calls) - * enough entropy to achieve cryptographic resistance (at least 80 bits, - * preferably 128 or more). The engine will report an error if no entropy - * was provided and none can be obtained from the OS. - * - * Take care that this function cannot assess the cryptographic quality of - * the provided bytes. - * - * In all generality, "entropy" must here be considered to mean "that - * which the attacker cannot predict". If your OS/architecture does not - * have a suitable source of randomness, then you can make do with the - * combination of a large enough secret value (possibly a copy of an - * asymmetric private key that you also store on the system) AND a - * non-repeating value (e.g. current time, provided that the local clock - * cannot be reset or altered by the attacker). - * - * \param cc SSL engine context. - * \param data extra entropy to inject. - * \param len length of the extra data (in bytes). - */ -void br_ssl_engine_inject_entropy(br_ssl_engine_context *cc, - const void *data, size_t len); - -/** - * \brief Get the "server name" in this engine. - * - * For clients, this is the name provided with `br_ssl_client_reset()`; - * for servers, this is the name received from the client as part of the - * ClientHello message. If there is no such name (e.g. the client did - * not send an SNI extension) then the returned string is empty - * (returned pointer points to a byte of value 0). - * - * The returned pointer refers to a buffer inside the context, which may - * be overwritten as part of normal SSL activity (even within the same - * connection, if a renegotiation occurs). - * - * \param cc SSL engine context. - * \return the server name (possibly empty). - */ -static inline const char * -br_ssl_engine_get_server_name(const br_ssl_engine_context *cc) -{ - return cc->server_name; -} - -/** - * \brief Get the protocol version. - * - * This function returns the protocol version that is used by the - * engine. That value is set after sending (for a server) or receiving - * (for a client) the ServerHello message. - * - * \param cc SSL engine context. - * \return the protocol version. - */ -static inline unsigned -br_ssl_engine_get_version(const br_ssl_engine_context *cc) -{ - return cc->session.version; -} - -/** - * \brief Get a copy of the session parameters. - * - * The session parameters are filled during the handshake, so this - * function shall not be called before completion of the handshake. - * The initial handshake is completed when the context first allows - * application data to be injected. - * - * This function copies the current session parameters into the provided - * structure. Beware that the session parameters include the master - * secret, which is sensitive data, to handle with great care. - * - * \param cc SSL engine context. - * \param pp destination structure for the session parameters. - */ -static inline void -br_ssl_engine_get_session_parameters(const br_ssl_engine_context *cc, - br_ssl_session_parameters *pp) -{ - memcpy(pp, &cc->session, sizeof *pp); -} - -/** - * \brief Set the session parameters to the provided values. - * - * This function is meant to be used in the client, before doing a new - * handshake; a session resumption will be attempted with these - * parameters. In the server, this function has no effect. - * - * \param cc SSL engine context. - * \param pp source structure for the session parameters. - */ -static inline void -br_ssl_engine_set_session_parameters(br_ssl_engine_context *cc, - const br_ssl_session_parameters *pp) -{ - memcpy(&cc->session, pp, sizeof *pp); -} - -/** - * \brief Get identifier for the curve used for key exchange. - * - * If the cipher suite uses ECDHE, then this function returns the - * identifier for the curve used for transient parameters. This is - * defined during the course of the handshake, when the ServerKeyExchange - * is sent (on the server) or received (on the client). If the - * cipher suite does not use ECDHE (e.g. static ECDH, or RSA key - * exchange), then this value is indeterminate. - * - * @param cc SSL engine context. - * @return the ECDHE curve identifier. - */ -static inline int -br_ssl_engine_get_ecdhe_curve(br_ssl_engine_context *cc) -{ - return cc->ecdhe_curve; -} - -/** - * \brief Get the current engine state. - * - * An SSL engine (client or server) has, at any time, a state which is - * the combination of zero, one or more of these flags: - * - * - `BR_SSL_CLOSED` - * - * Engine is finished, no more I/O (until next reset). - * - * - `BR_SSL_SENDREC` - * - * Engine has some bytes to send to the peer. - * - * - `BR_SSL_RECVREC` - * - * Engine expects some bytes from the peer. - * - * - `BR_SSL_SENDAPP` - * - * Engine may receive application data to send (or flush). - * - * - `BR_SSL_RECVAPP` - * - * Engine has obtained some application data from the peer, - * that should be read by the caller. - * - * If no flag at all is set (state value is 0), then the engine is not - * fully initialised yet. - * - * The `BR_SSL_CLOSED` flag is exclusive; when it is set, no other flag - * is set. To distinguish between a normal closure and an error, use - * `br_ssl_engine_last_error()`. - * - * Generally speaking, `BR_SSL_SENDREC` and `BR_SSL_SENDAPP` are mutually - * exclusive: the input buffer, at any point, either accumulates - * plaintext data, or contains an assembled record that is being sent. - * Similarly, `BR_SSL_RECVREC` and `BR_SSL_RECVAPP` are mutually exclusive. - * This may change in a future library version. - * - * \param cc SSL engine context. - * \return the current engine state. - */ -unsigned br_ssl_engine_current_state(const br_ssl_engine_context *cc); - -/** \brief SSL engine state: closed or failed. */ -#define BR_SSL_CLOSED 0x0001 -/** \brief SSL engine state: record data is ready to be sent to the peer. */ -#define BR_SSL_SENDREC 0x0002 -/** \brief SSL engine state: engine may receive records from the peer. */ -#define BR_SSL_RECVREC 0x0004 -/** \brief SSL engine state: engine may accept application data to send. */ -#define BR_SSL_SENDAPP 0x0008 -/** \brief SSL engine state: engine has received application data. */ -#define BR_SSL_RECVAPP 0x0010 - -/** - * \brief Get the engine error indicator. - * - * The error indicator is `BR_ERR_OK` (0) if no error was encountered - * since the last call to `br_ssl_client_reset()` or - * `br_ssl_server_reset()`. Other status values are "sticky": they - * remain set, and prevent all I/O activity, until cleared. Only the - * reset calls clear the error indicator. - * - * \param cc SSL engine context. - * \return 0, or a non-zero error code. - */ -static inline int -br_ssl_engine_last_error(const br_ssl_engine_context *cc) -{ - return cc->err; -} - -/* - * There are four I/O operations, each identified by a symbolic name: - * - * sendapp inject application data in the engine - * recvapp retrieving application data from the engine - * sendrec sending records on the transport medium - * recvrec receiving records from the transport medium - * - * Terminology works thus: in a layered model where the SSL engine sits - * between the application and the network, "send" designates operations - * where bytes flow from application to network, and "recv" for the - * reverse operation. Application data (the plaintext that is to be - * conveyed through SSL) is "app", while encrypted records are "rec". - * Note that from the SSL engine point of view, "sendapp" and "recvrec" - * designate bytes that enter the engine ("inject" operation), while - * "recvapp" and "sendrec" designate bytes that exit the engine - * ("extract" operation). - * - * For the operation 'xxx', two functions are defined: - * - * br_ssl_engine_xxx_buf - * Returns a pointer and length to the buffer to use for that - * operation. '*len' is set to the number of bytes that may be read - * from the buffer (extract operation) or written to the buffer - * (inject operation). If no byte may be exchanged for that operation - * at that point, then '*len' is set to zero, and NULL is returned. - * The engine state is unmodified by this call. - * - * br_ssl_engine_xxx_ack - * Informs the engine that 'len' bytes have been read from the buffer - * (extract operation) or written to the buffer (inject operation). - * The 'len' value MUST NOT be zero. The 'len' value MUST NOT exceed - * that which was obtained from a preceding br_ssl_engine_xxx_buf() - * call. - */ - -/** - * \brief Get buffer for application data to send. - * - * If the engine is ready to accept application data to send to the - * peer, then this call returns a pointer to the buffer where such - * data shall be written, and its length is written in `*len`. - * Otherwise, `*len` is set to 0 and `NULL` is returned. - * - * \param cc SSL engine context. - * \param len receives the application data output buffer length, or 0. - * \return the application data output buffer, or `NULL`. - */ -unsigned char *br_ssl_engine_sendapp_buf( - const br_ssl_engine_context *cc, size_t *len); - -/** - * \brief Inform the engine of some new application data. - * - * After writing `len` bytes in the buffer returned by - * `br_ssl_engine_sendapp_buf()`, the application shall call this - * function to trigger any relevant processing. The `len` parameter - * MUST NOT be 0, and MUST NOT exceed the value obtained in the - * `br_ssl_engine_sendapp_buf()` call. - * - * \param cc SSL engine context. - * \param len number of bytes pushed (not zero). - */ -void br_ssl_engine_sendapp_ack(br_ssl_engine_context *cc, size_t len); - -/** - * \brief Get buffer for received application data. - * - * If the engine has received application data from the peer, hen this - * call returns a pointer to the buffer from where such data shall be - * read, and its length is written in `*len`. Otherwise, `*len` is set - * to 0 and `NULL` is returned. - * - * \param cc SSL engine context. - * \param len receives the application data input buffer length, or 0. - * \return the application data input buffer, or `NULL`. - */ -unsigned char *br_ssl_engine_recvapp_buf( - const br_ssl_engine_context *cc, size_t *len); - -/** - * \brief Acknowledge some received application data. - * - * After reading `len` bytes from the buffer returned by - * `br_ssl_engine_recvapp_buf()`, the application shall call this - * function to trigger any relevant processing. The `len` parameter - * MUST NOT be 0, and MUST NOT exceed the value obtained in the - * `br_ssl_engine_recvapp_buf()` call. - * - * \param cc SSL engine context. - * \param len number of bytes read (not zero). - */ -void br_ssl_engine_recvapp_ack(br_ssl_engine_context *cc, size_t len); - -/** - * \brief Get buffer for record data to send. - * - * If the engine has prepared some records to send to the peer, then this - * call returns a pointer to the buffer from where such data shall be - * read, and its length is written in `*len`. Otherwise, `*len` is set - * to 0 and `NULL` is returned. - * - * \param cc SSL engine context. - * \param len receives the record data output buffer length, or 0. - * \return the record data output buffer, or `NULL`. - */ -unsigned char *br_ssl_engine_sendrec_buf( - const br_ssl_engine_context *cc, size_t *len); - -/** - * \brief Acknowledge some sent record data. - * - * After reading `len` bytes from the buffer returned by - * `br_ssl_engine_sendrec_buf()`, the application shall call this - * function to trigger any relevant processing. The `len` parameter - * MUST NOT be 0, and MUST NOT exceed the value obtained in the - * `br_ssl_engine_sendrec_buf()` call. - * - * \param cc SSL engine context. - * \param len number of bytes read (not zero). - */ -void br_ssl_engine_sendrec_ack(br_ssl_engine_context *cc, size_t len); - -/** - * \brief Get buffer for incoming records. - * - * If the engine is ready to accept records from the peer, then this - * call returns a pointer to the buffer where such data shall be - * written, and its length is written in `*len`. Otherwise, `*len` is - * set to 0 and `NULL` is returned. - * - * \param cc SSL engine context. - * \param len receives the record data input buffer length, or 0. - * \return the record data input buffer, or `NULL`. - */ -unsigned char *br_ssl_engine_recvrec_buf( - const br_ssl_engine_context *cc, size_t *len); - -/** - * \brief Inform the engine of some new record data. - * - * After writing `len` bytes in the buffer returned by - * `br_ssl_engine_recvrec_buf()`, the application shall call this - * function to trigger any relevant processing. The `len` parameter - * MUST NOT be 0, and MUST NOT exceed the value obtained in the - * `br_ssl_engine_recvrec_buf()` call. - * - * \param cc SSL engine context. - * \param len number of bytes pushed (not zero). - */ -void br_ssl_engine_recvrec_ack(br_ssl_engine_context *cc, size_t len); - -/** - * \brief Flush buffered application data. - * - * If some application data has been buffered in the engine, then wrap - * it into a record and mark it for sending. If no application data has - * been buffered but the engine would be ready to accept some, AND the - * `force` parameter is non-zero, then an empty record is assembled and - * marked for sending. In all other cases, this function does nothing. - * - * Empty records are technically legal, but not all existing SSL/TLS - * implementations support them. Empty records can be useful as a - * transparent "keep-alive" mechanism to maintain some low-level - * network activity. - * - * \param cc SSL engine context. - * \param force non-zero to force sending an empty record. - */ -void br_ssl_engine_flush(br_ssl_engine_context *cc, int force); - -/** - * \brief Initiate a closure. - * - * If, at that point, the context is open and in ready state, then a - * `close_notify` alert is assembled and marked for sending; this - * triggers the closure protocol. Otherwise, no such alert is assembled. - * - * \param cc SSL engine context. - */ -void br_ssl_engine_close(br_ssl_engine_context *cc); - -/** - * \brief Initiate a renegotiation. - * - * If the engine is failed or closed, or if the peer is known not to - * support secure renegotiation (RFC 5746), or if renegotiations have - * been disabled with the `BR_OPT_NO_RENEGOTIATION` flag, or if there - * is buffered incoming application data, then this function returns 0 - * and nothing else happens. - * - * Otherwise, this function returns 1, and a renegotiation attempt is - * triggered (if a handshake is already ongoing at that point, then - * no new handshake is triggered). - * - * \param cc SSL engine context. - * \return 1 on success, 0 on error. - */ -int br_ssl_engine_renegotiate(br_ssl_engine_context *cc); - -/** - * \brief Export key material from a connected SSL engine (RFC 5705). - * - * This calls compute a secret key of arbitrary length from the master - * secret of a connected SSL engine. If the provided context is not - * currently in "application data" state (initial handshake is not - * finished, another handshake is ongoing, or the connection failed or - * was closed), then this function returns 0. Otherwise, a secret key of - * length `len` bytes is computed and written in the buffer pointed to - * by `dst`, and 1 is returned. - * - * The computed key follows the specification described in RFC 5705. - * That RFC includes two key computations, with and without a "context - * value". If `context` is `NULL`, then the variant without context is - * used; otherwise, the `context_len` bytes located at the address - * pointed to by `context` are used in the computation. Note that it - * is possible to have a "with context" key with a context length of - * zero bytes, by setting `context` to a non-`NULL` value but - * `context_len` to 0. - * - * When context bytes are used, the context length MUST NOT exceed - * 65535 bytes. - * - * \param cc SSL engine context. - * \param dst destination buffer for exported key. - * \param len exported key length (in bytes). - * \param label disambiguation label. - * \param context context value (or `NULL`). - * \param context_len context length (in bytes). - * \return 1 on success, 0 on error. - */ -int br_ssl_key_export(br_ssl_engine_context *cc, - void *dst, size_t len, const char *label, - const void *context, size_t context_len); - -/* - * Pre-declaration for the SSL client context. - */ -typedef struct br_ssl_client_context_ br_ssl_client_context; - -/** - * \brief Type for the client certificate, if requested by the server. - */ -typedef struct { - /** - * \brief Authentication type. - * - * This is either `BR_AUTH_RSA` (RSA signature), `BR_AUTH_ECDSA` - * (ECDSA signature), or `BR_AUTH_ECDH` (static ECDH key exchange). - */ - int auth_type; - - /** - * \brief Hash function for computing the CertificateVerify. - * - * This is the symbolic identifier for the hash function that - * will be used to produce the hash of handshake messages, to - * be signed into the CertificateVerify. For full static ECDH - * (client and server certificates are both EC in the same - * curve, and static ECDH is used), this value is set to -1. - * - * Take care that with TLS 1.0 and 1.1, that value MUST match - * the protocol requirements: value must be 0 (MD5+SHA-1) for - * a RSA signature, or 2 (SHA-1) for an ECDSA signature. Only - * TLS 1.2 allows for other hash functions. - */ - int hash_id; - - /** - * \brief Certificate chain to send to the server. - * - * This is an array of `br_x509_certificate` objects, each - * normally containing a DER-encoded certificate. The client - * code does not try to decode these elements. If there is no - * chain to send to the server, then this pointer shall be - * set to `NULL`. - */ - const br_x509_certificate *chain; - - /** - * \brief Certificate chain length (number of certificates). - * - * If there is no chain to send to the server, then this value - * shall be set to 0. - */ - size_t chain_len; - -} br_ssl_client_certificate; - -/* - * Note: the constants below for signatures match the TLS constants. - */ - -/** \brief Client authentication type: static ECDH. */ -#define BR_AUTH_ECDH 0 -/** \brief Client authentication type: RSA signature. */ -#define BR_AUTH_RSA 1 -/** \brief Client authentication type: ECDSA signature. */ -#define BR_AUTH_ECDSA 3 - -/** - * \brief Class type for a certificate handler (client side). - * - * A certificate handler selects a client certificate chain to send to - * the server, upon explicit request from that server. It receives - * the list of trust anchor DN from the server, and supported types - * of certificates and signatures, and returns the chain to use. It - * is also invoked to perform the corresponding private key operation - * (a signature, or an ECDH computation). - * - * The SSL client engine will first push the trust anchor DN with - * `start_name_list()`, `start_name()`, `append_name()`, `end_name()` - * and `end_name_list()`. Then it will call `choose()`, to select the - * actual chain (and signature/hash algorithms). Finally, it will call - * either `do_sign()` or `do_keyx()`, depending on the algorithm choices. - */ -typedef struct br_ssl_client_certificate_class_ br_ssl_client_certificate_class; -struct br_ssl_client_certificate_class_ { - /** - * \brief Context size (in bytes). - */ - size_t context_size; - - /** - * \brief Begin reception of a list of trust anchor names. This - * is called while parsing the incoming CertificateRequest. - * - * \param pctx certificate handler context. - */ - void (*start_name_list)(const br_ssl_client_certificate_class **pctx); - - /** - * \brief Begin reception of a new trust anchor name. - * - * The total encoded name length is provided; it is less than - * 65535 bytes. - * - * \param pctx certificate handler context. - * \param len encoded name length (in bytes). - */ - void (*start_name)(const br_ssl_client_certificate_class **pctx, - size_t len); - - /** - * \brief Receive some more bytes for the current trust anchor name. - * - * The provided reference (`data`) points to a transient buffer - * they may be reused as soon as this function returns. The chunk - * length (`len`) is never zero. - * - * \param pctx certificate handler context. - * \param data anchor name chunk. - * \param len anchor name chunk length (in bytes). - */ - void (*append_name)(const br_ssl_client_certificate_class **pctx, - const unsigned char *data, size_t len); - - /** - * \brief End current trust anchor name. - * - * This function is called when all the encoded anchor name data - * has been provided. - * - * \param pctx certificate handler context. - */ - void (*end_name)(const br_ssl_client_certificate_class **pctx); - - /** - * \brief End list of trust anchor names. - * - * This function is called when all the anchor names in the - * CertificateRequest message have been obtained. - * - * \param pctx certificate handler context. - */ - void (*end_name_list)(const br_ssl_client_certificate_class **pctx); - - /** - * \brief Select client certificate and algorithms. - * - * This callback function shall fill the provided `choices` - * structure with the selected algorithms and certificate chain. - * The `hash_id`, `chain` and `chain_len` fields must be set. If - * the client cannot or does not wish to send a certificate, - * then it shall set `chain` to `NULL` and `chain_len` to 0. - * - * The `auth_types` parameter describes the authentication types, - * signature algorithms and hash functions that are supported by - * both the client context and the server, and compatible with - * the current protocol version. This is a bit field with the - * following contents: - * - * - If RSA signatures with hash function x are supported, then - * bit x is set. - * - * - If ECDSA signatures with hash function x are supported, - * then bit 8+x is set. - * - * - If static ECDH is supported, with a RSA-signed certificate, - * then bit 16 is set. - * - * - If static ECDH is supported, with an ECDSA-signed certificate, - * then bit 17 is set. - * - * Notes: - * - * - When using TLS 1.0 or 1.1, the hash function for RSA - * signatures is always the special MD5+SHA-1 (id 0), and the - * hash function for ECDSA signatures is always SHA-1 (id 2). - * - * - When using TLS 1.2, the list of hash functions is trimmed - * down to include only hash functions that the client context - * can support. The actual server list can be obtained with - * `br_ssl_client_get_server_hashes()`; that list may be used - * to select the certificate chain to send to the server. - * - * \param pctx certificate handler context. - * \param cc SSL client context. - * \param auth_types supported authentication types and algorithms. - * \param choices destination structure for the policy choices. - */ - void (*choose)(const br_ssl_client_certificate_class **pctx, - const br_ssl_client_context *cc, uint32_t auth_types, - br_ssl_client_certificate *choices); - - /** - * \brief Perform key exchange (client part). - * - * This callback is invoked in case of a full static ECDH key - * exchange: - * - * - the cipher suite uses `ECDH_RSA` or `ECDH_ECDSA`; - * - * - the server requests a client certificate; - * - * - the client has, and sends, a client certificate that - * uses an EC key in the same curve as the server's key, - * and chooses static ECDH (the `hash_id` field in the choice - * structure was set to -1). - * - * In that situation, this callback is invoked to compute the - * client-side ECDH: the provided `data` (of length `*len` bytes) - * is the server's public key point (as decoded from its - * certificate), and the client shall multiply that point with - * its own private key, and write back the X coordinate of the - * resulting point in the same buffer, starting at offset 0. - * The `*len` value shall be modified to designate the actual - * length of the X coordinate. - * - * The callback must uphold the following: - * - * - If the input array does not have the proper length for - * an encoded curve point, then an error (0) shall be reported. - * - * - If the input array has the proper length, then processing - * MUST be constant-time, even if the data is not a valid - * encoded point. - * - * - This callback MUST check that the input point is valid. - * - * Returned value is 1 on success, 0 on error. - * - * \param pctx certificate handler context. - * \param data server public key point. - * \param len public key point length / X coordinate length. - * \return 1 on success, 0 on error. - */ - uint32_t (*do_keyx)(const br_ssl_client_certificate_class **pctx, - unsigned char *data, size_t *len); - - /** - * \brief Perform a signature (client authentication). - * - * This callback is invoked when a client certificate was sent, - * and static ECDH is not used. It shall compute a signature, - * using the client's private key, over the provided hash value - * (which is the hash of all previous handshake messages). - * - * On input, the hash value to sign is in `data`, of size - * `hv_len`; the involved hash function is identified by - * `hash_id`. The signature shall be computed and written - * back into `data`; the total size of that buffer is `len` - * bytes. - * - * This callback shall verify that the signature length does not - * exceed `len` bytes, and abstain from writing the signature if - * it does not fit. - * - * For RSA signatures, the `hash_id` may be 0, in which case - * this is the special header-less signature specified in TLS 1.0 - * and 1.1, with a 36-byte hash value. Otherwise, normal PKCS#1 - * v1.5 signatures shall be computed. - * - * For ECDSA signatures, the signature value shall use the ASN.1 - * based encoding. - * - * Returned value is the signature length (in bytes), or 0 on error. - * - * \param pctx certificate handler context. - * \param hash_id hash function identifier. - * \param hv_len hash value length (in bytes). - * \param data input/output buffer (hash value, then signature). - * \param len total buffer length (in bytes). - * \return signature length (in bytes) on success, or 0 on error. - */ - size_t (*do_sign)(const br_ssl_client_certificate_class **pctx, - int hash_id, size_t hv_len, unsigned char *data, size_t len); -}; - -/** - * \brief A single-chain RSA client certificate handler. - * - * This handler uses a single certificate chain, with a RSA - * signature. The list of trust anchor DN is ignored. - * - * Apart from the first field (vtable pointer), its contents are - * opaque and shall not be accessed directly. - */ -typedef struct { - /** \brief Pointer to vtable. */ - const br_ssl_client_certificate_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - const br_x509_certificate *chain; - size_t chain_len; - const br_rsa_private_key *sk; - br_rsa_pkcs1_sign irsasign; -#endif -} br_ssl_client_certificate_rsa_context; - -/** - * \brief A single-chain EC client certificate handler. - * - * This handler uses a single certificate chain, with a RSA - * signature. The list of trust anchor DN is ignored. - * - * This handler may support both static ECDH, and ECDSA signatures - * (either usage may be selectively disabled). - * - * Apart from the first field (vtable pointer), its contents are - * opaque and shall not be accessed directly. - */ -typedef struct { - /** \brief Pointer to vtable. */ - const br_ssl_client_certificate_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - const br_x509_certificate *chain; - size_t chain_len; - const br_ec_private_key *sk; - unsigned allowed_usages; - unsigned issuer_key_type; - const br_multihash_context *mhash; - const br_ec_impl *iec; - br_ecdsa_sign iecdsa; -#endif -} br_ssl_client_certificate_ec_context; - -/** - * \brief Context structure for a SSL client. - * - * The first field (called `eng`) is the SSL engine; all functions that - * work on a `br_ssl_engine_context` structure shall take as parameter - * a pointer to that field. The other structure fields are opaque and - * must not be accessed directly. - */ -struct br_ssl_client_context_ { - /** - * \brief The encapsulated engine context. - */ - br_ssl_engine_context eng; - -#ifndef BR_DOXYGEN_IGNORE - /* - * Minimum ClientHello length; padding with an extension (RFC - * 7685) is added if necessary to match at least that length. - * Such padding is nominally unnecessary, but it has been used - * to work around some server implementation bugs. - */ - uint16_t min_clienthello_len; - - /* - * Bit field for algorithms (hash + signature) supported by the - * server when requesting a client certificate. - */ - uint32_t hashes; - - /* - * Server's public key curve. - */ - int server_curve; - - /* - * Context for certificate handler. - */ - const br_ssl_client_certificate_class **client_auth_vtable; - - /* - * Client authentication type. - */ - unsigned char auth_type; - - /* - * Hash function to use for the client signature. This is 0xFF - * if static ECDH is used. - */ - unsigned char hash_id; - - /* - * For the core certificate handlers, thus avoiding (in most - * cases) the need for an externally provided policy context. - */ - union { - const br_ssl_client_certificate_class *vtable; - br_ssl_client_certificate_rsa_context single_rsa; - br_ssl_client_certificate_ec_context single_ec; - } client_auth; - - /* - * Implementations. - */ - br_rsa_public irsapub; -#endif -}; - -/** - * \brief Get the hash functions and signature algorithms supported by - * the server. - * - * This value is a bit field: - * - * - If RSA (PKCS#1 v1.5) is supported with hash function of ID `x`, - * then bit `x` is set (hash function ID is 0 for the special MD5+SHA-1, - * or 2 to 6 for the SHA family). - * - * - If ECDSA is supported with hash function of ID `x`, then bit `8+x` - * is set. - * - * - Newer algorithms are symbolic 16-bit identifiers that do not - * represent signature algorithm and hash function separately. If - * the TLS-level identifier is `0x0800+x` for a `x` in the 0..15 - * range, then bit `16+x` is set. - * - * "New algorithms" are currently defined only in draft documents, so - * this support is subject to possible change. Right now (early 2017), - * this maps ed25519 (EdDSA on Curve25519) to bit 23, and ed448 (EdDSA - * on Curve448) to bit 24. If the identifiers on the wire change in - * future document, then the decoding mechanism in BearSSL will be - * amended to keep mapping ed25519 and ed448 on bits 23 and 24, - * respectively. Mapping of other new algorithms (e.g. RSA/PSS) is not - * guaranteed yet. - * - * \param cc client context. - * \return the server-supported hash functions and signature algorithms. - */ -static inline uint32_t -br_ssl_client_get_server_hashes(const br_ssl_client_context *cc) -{ - return cc->hashes; -} - -/** - * \brief Get the server key curve. - * - * This function returns the ID for the curve used by the server's public - * key. This is set when the server's certificate chain is processed; - * this value is 0 if the server's key is not an EC key. - * - * \return the server's public key curve ID, or 0. - */ -static inline int -br_ssl_client_get_server_curve(const br_ssl_client_context *cc) -{ - return cc->server_curve; -} - -/* - * Each br_ssl_client_init_xxx() function sets the list of supported - * cipher suites and used implementations, as specified by the profile - * name 'xxx'. Defined profile names are: - * - * full all supported versions and suites; constant-time implementations - * TODO: add other profiles - */ - -/** - * \brief SSL client profile: full. - * - * This function initialises the provided SSL client context with - * all supported algorithms and cipher suites. It also initialises - * a companion X.509 validation engine with all supported algorithms, - * and the provided trust anchors; the X.509 engine will be used by - * the client context to validate the server's certificate. - * - * \param cc client context to initialise. - * \param xc X.509 validation context to initialise. - * \param trust_anchors trust anchors to use. - * \param trust_anchors_num number of trust anchors. - */ -void br_ssl_client_init_full(br_ssl_client_context *cc, - br_x509_minimal_context *xc, - const br_x509_trust_anchor *trust_anchors, size_t trust_anchors_num); - -/** - * \brief Clear the complete contents of a SSL client context. - * - * Everything is cleared, including the reference to the configured buffer, - * implementations, cipher suites and state. This is a preparatory step - * to assembling a custom profile. - * - * \param cc client context to clear. - */ -void br_ssl_client_zero(br_ssl_client_context *cc); - -/** - * \brief Set an externally provided client certificate handler context. - * - * The handler's methods are invoked when the server requests a client - * certificate. - * - * \param cc client context. - * \param pctx certificate handler context (pointer to its vtable field). - */ -static inline void -br_ssl_client_set_client_certificate(br_ssl_client_context *cc, - const br_ssl_client_certificate_class **pctx) -{ - cc->client_auth_vtable = pctx; -} - -/** - * \brief Set the RSA public-key operations implementation. - * - * This will be used to encrypt the pre-master secret with the server's - * RSA public key (RSA-encryption cipher suites only). - * - * \param cc client context. - * \param irsapub RSA public-key encryption implementation. - */ -static inline void -br_ssl_client_set_rsapub(br_ssl_client_context *cc, br_rsa_public irsapub) -{ - cc->irsapub = irsapub; -} - -/** - * \brief Set the "default" RSA implementation for public-key operations. - * - * This sets the RSA implementation in the client context (for encrypting - * the pre-master secret, in `TLS_RSA_*` cipher suites) to the fastest - * available on the current platform. - * - * \param cc client context. - */ -void br_ssl_client_set_default_rsapub(br_ssl_client_context *cc); - -/** - * \brief Set the minimum ClientHello length (RFC 7685 padding). - * - * If this value is set and the ClientHello would be shorter, then - * the Pad ClientHello extension will be added with enough padding bytes - * to reach the target size. Because of the extension header, the resulting - * size will sometimes be slightly more than `len` bytes if the target - * size cannot be exactly met. - * - * The target length relates to the _contents_ of the ClientHello, not - * counting its 4-byte header. For instance, if `len` is set to 512, - * then the padding will bring the ClientHello size to 516 bytes with its - * header, and 521 bytes when counting the 5-byte record header. - * - * \param cc client context. - * \param len minimum ClientHello length (in bytes). - */ -static inline void -br_ssl_client_set_min_clienthello_len(br_ssl_client_context *cc, uint16_t len) -{ - cc->min_clienthello_len = len; -} - -/** - * \brief Prepare or reset a client context for a new connection. - * - * The `server_name` parameter is used to fill the SNI extension; the - * X.509 "minimal" engine will also match that name against the server - * names included in the server's certificate. If the parameter is - * `NULL` then no SNI extension will be sent, and the X.509 "minimal" - * engine (if used for server certificate validation) will not check - * presence of any specific name in the received certificate. - * - * Therefore, setting the `server_name` to `NULL` shall be reserved - * to cases where alternate or additional methods are used to ascertain - * that the right server public key is used (e.g. a "known key" model). - * - * If `resume_session` is non-zero and the context was previously used - * then the session parameters may be reused (depending on whether the - * server previously sent a non-empty session ID, and accepts the session - * resumption). The session parameters for session resumption can also - * be set explicitly with `br_ssl_engine_set_session_parameters()`. - * - * On failure, the context is marked as failed, and this function - * returns 0. A possible failure condition is when no initial entropy - * was injected, and none could be obtained from the OS (either OS - * randomness gathering is not supported, or it failed). - * - * \param cc client context. - * \param server_name target server name, or `NULL`. - * \param resume_session non-zero to try session resumption. - * \return 0 on failure, 1 on success. - */ -int br_ssl_client_reset(br_ssl_client_context *cc, - const char *server_name, int resume_session); - -/** - * \brief Forget any session in the context. - * - * This means that the next handshake that uses this context will - * necessarily be a full handshake (this applies both to new connections - * and to renegotiations). - * - * \param cc client context. - */ -static inline void -br_ssl_client_forget_session(br_ssl_client_context *cc) -{ - cc->eng.session.session_id_len = 0; -} - -/** - * \brief Set client certificate chain and key (single RSA case). - * - * This function sets a client certificate chain, that the client will - * send to the server whenever a client certificate is requested. This - * certificate uses an RSA public key; the corresponding private key is - * invoked for authentication. Trust anchor names sent by the server are - * ignored. - * - * The provided chain and private key are linked in the client context; - * they must remain valid as long as they may be used, i.e. normally - * for the duration of the connection, since they might be invoked - * again upon renegotiations. - * - * \param cc SSL client context. - * \param chain client certificate chain (SSL order: EE comes first). - * \param chain_len client chain length (number of certificates). - * \param sk client private key. - * \param irsasign RSA signature implementation (PKCS#1 v1.5). - */ -void br_ssl_client_set_single_rsa(br_ssl_client_context *cc, - const br_x509_certificate *chain, size_t chain_len, - const br_rsa_private_key *sk, br_rsa_pkcs1_sign irsasign); - -/* - * \brief Set the client certificate chain and key (single EC case). - * - * This function sets a client certificate chain, that the client will - * send to the server whenever a client certificate is requested. This - * certificate uses an EC public key; the corresponding private key is - * invoked for authentication. Trust anchor names sent by the server are - * ignored. - * - * The provided chain and private key are linked in the client context; - * they must remain valid as long as they may be used, i.e. normally - * for the duration of the connection, since they might be invoked - * again upon renegotiations. - * - * The `allowed_usages` is a combination of usages, namely - * `BR_KEYTYPE_KEYX` and/or `BR_KEYTYPE_SIGN`. The `BR_KEYTYPE_KEYX` - * value allows full static ECDH, while the `BR_KEYTYPE_SIGN` value - * allows ECDSA signatures. If ECDSA signatures are used, then an ECDSA - * signature implementation must be provided; otherwise, the `iecdsa` - * parameter may be 0. - * - * The `cert_issuer_key_type` value is either `BR_KEYTYPE_RSA` or - * `BR_KEYTYPE_EC`; it is the type of the public key used the the CA - * that issued (signed) the client certificate. That value is used with - * full static ECDH: support of the certificate by the server depends - * on how the certificate was signed. (Note: when using TLS 1.2, this - * parameter is ignored; but its value matters for TLS 1.0 and 1.1.) - * - * \param cc server context. - * \param chain server certificate chain to send. - * \param chain_len chain length (number of certificates). - * \param sk server private key (EC). - * \param allowed_usages allowed private key usages. - * \param cert_issuer_key_type issuing CA's key type. - * \param iec EC core implementation. - * \param iecdsa ECDSA signature implementation ("asn1" format). - */ -void br_ssl_client_set_single_ec(br_ssl_client_context *cc, - const br_x509_certificate *chain, size_t chain_len, - const br_ec_private_key *sk, unsigned allowed_usages, - unsigned cert_issuer_key_type, - const br_ec_impl *iec, br_ecdsa_sign iecdsa); - -/** - * \brief Type for a "translated cipher suite", as an array of two - * 16-bit integers. - * - * The first element is the cipher suite identifier (as used on the wire). - * The second element is the concatenation of four 4-bit elements which - * characterise the cipher suite contents. In most to least significant - * order, these 4-bit elements are: - * - * - Bits 12 to 15: key exchange + server key type - * - * | val | symbolic constant | suite type | details | - * | :-- | :----------------------- | :---------- | :----------------------------------------------- | - * | 0 | `BR_SSLKEYX_RSA` | RSA | RSA key exchange, key is RSA (encryption) | - * | 1 | `BR_SSLKEYX_ECDHE_RSA` | ECDHE_RSA | ECDHE key exchange, key is RSA (signature) | - * | 2 | `BR_SSLKEYX_ECDHE_ECDSA` | ECDHE_ECDSA | ECDHE key exchange, key is EC (signature) | - * | 3 | `BR_SSLKEYX_ECDH_RSA` | ECDH_RSA | Key is EC (key exchange), cert signed with RSA | - * | 4 | `BR_SSLKEYX_ECDH_ECDSA` | ECDH_ECDSA | Key is EC (key exchange), cert signed with ECDSA | - * - * - Bits 8 to 11: symmetric encryption algorithm - * - * | val | symbolic constant | symmetric encryption | key strength (bits) | - * | :-- | :--------------------- | :------------------- | :------------------ | - * | 0 | `BR_SSLENC_3DES_CBC` | 3DES/CBC | 168 | - * | 1 | `BR_SSLENC_AES128_CBC` | AES-128/CBC | 128 | - * | 2 | `BR_SSLENC_AES256_CBC` | AES-256/CBC | 256 | - * | 3 | `BR_SSLENC_AES128_GCM` | AES-128/GCM | 128 | - * | 4 | `BR_SSLENC_AES256_GCM` | AES-256/GCM | 256 | - * | 5 | `BR_SSLENC_CHACHA20` | ChaCha20/Poly1305 | 256 | - * - * - Bits 4 to 7: MAC algorithm - * - * | val | symbolic constant | MAC type | details | - * | :-- | :----------------- | :----------- | :------------------------------------ | - * | 0 | `BR_SSLMAC_AEAD` | AEAD | No dedicated MAC (encryption is AEAD) | - * | 2 | `BR_SSLMAC_SHA1` | HMAC/SHA-1 | Value matches `br_sha1_ID` | - * | 4 | `BR_SSLMAC_SHA256` | HMAC/SHA-256 | Value matches `br_sha256_ID` | - * | 5 | `BR_SSLMAC_SHA384` | HMAC/SHA-384 | Value matches `br_sha384_ID` | - * - * - Bits 0 to 3: hash function for PRF when used with TLS-1.2 - * - * | val | symbolic constant | hash function | details | - * | :-- | :----------------- | :------------ | :----------------------------------- | - * | 4 | `BR_SSLPRF_SHA256` | SHA-256 | Value matches `br_sha256_ID` | - * | 5 | `BR_SSLPRF_SHA384` | SHA-384 | Value matches `br_sha384_ID` | - * - * For instance, cipher suite `TLS_RSA_WITH_AES_128_GCM_SHA256` has - * standard identifier 0x009C, and is translated to 0x0304, for, in - * that order: RSA key exchange (0), AES-128/GCM (3), AEAD integrity (0), - * SHA-256 in the TLS PRF (4). - */ -typedef uint16_t br_suite_translated[2]; - -#ifndef BR_DOXYGEN_IGNORE -/* - * Constants are already documented in the br_suite_translated type. - */ - -#define BR_SSLKEYX_RSA 0 -#define BR_SSLKEYX_ECDHE_RSA 1 -#define BR_SSLKEYX_ECDHE_ECDSA 2 -#define BR_SSLKEYX_ECDH_RSA 3 -#define BR_SSLKEYX_ECDH_ECDSA 4 - -#define BR_SSLENC_3DES_CBC 0 -#define BR_SSLENC_AES128_CBC 1 -#define BR_SSLENC_AES256_CBC 2 -#define BR_SSLENC_AES128_GCM 3 -#define BR_SSLENC_AES256_GCM 4 -#define BR_SSLENC_CHACHA20 5 - -#define BR_SSLMAC_AEAD 0 -#define BR_SSLMAC_SHA1 br_sha1_ID -#define BR_SSLMAC_SHA256 br_sha256_ID -#define BR_SSLMAC_SHA384 br_sha384_ID - -#define BR_SSLPRF_SHA256 br_sha256_ID -#define BR_SSLPRF_SHA384 br_sha384_ID - -#endif - -/* - * Pre-declaration for the SSL server context. - */ -typedef struct br_ssl_server_context_ br_ssl_server_context; - -/** - * \brief Type for the server policy choices, taken after analysis of - * the client message (ClientHello). - */ -typedef struct { - /** - * \brief Cipher suite to use with that client. - */ - uint16_t cipher_suite; - - /** - * \brief Hash function or algorithm for signing the ServerKeyExchange. - * - * This parameter is ignored for `TLS_RSA_*` and `TLS_ECDH_*` - * cipher suites; it is used only for `TLS_ECDHE_*` suites, in - * which the server _signs_ the ephemeral EC Diffie-Hellman - * parameters sent to the client. - * - * This identifier must be one of the following values: - * - * - `0xFF00 + id`, where `id` is a hash function identifier - * (0 for MD5+SHA-1, or 2 to 6 for one of the SHA functions); - * - * - a full 16-bit identifier, lower than `0xFF00`. - * - * If the first option is used, then the SSL engine will - * compute the hash of the data that is to be signed, with the - * designated hash function. The `do_sign()` method will be - * invoked with that hash value provided in the the `data` - * buffer. - * - * If the second option is used, then the SSL engine will NOT - * compute a hash on the data; instead, it will provide the - * to-be-signed data itself in `data`, i.e. the concatenation of - * the client random, server random, and encoded ECDH - * parameters. Furthermore, with TLS-1.2 and later, the 16-bit - * identifier will be used "as is" in the protocol, in the - * SignatureAndHashAlgorithm; for instance, `0x0401` stands for - * RSA PKCS#1 v1.5 signature (the `01`) with SHA-256 as hash - * function (the `04`). - * - * Take care that with TLS 1.0 and 1.1, the hash function is - * constrainted by the protocol: RSA signature must use - * MD5+SHA-1 (so use `0xFF00`), while ECDSA must use SHA-1 - * (`0xFF02`). Since TLS 1.0 and 1.1 don't include a - * SignatureAndHashAlgorithm field in their ServerKeyExchange - * messages, any value below `0xFF00` will be usable to send the - * raw ServerKeyExchange data to the `do_sign()` callback, but - * that callback must still follow the protocol requirements - * when generating the signature. - */ - unsigned algo_id; - - /** - * \brief Certificate chain to send to the client. - * - * This is an array of `br_x509_certificate` objects, each - * normally containing a DER-encoded certificate. The server - * code does not try to decode these elements. - */ - const br_x509_certificate *chain; - - /** - * \brief Certificate chain length (number of certificates). - */ - size_t chain_len; - -} br_ssl_server_choices; - -/** - * \brief Class type for a policy handler (server side). - * - * A policy handler selects the policy parameters for a connection - * (cipher suite and other algorithms, and certificate chain to send to - * the client); it also performs the server-side computations involving - * its permanent private key. - * - * The SSL server engine will invoke first `choose()`, once the - * ClientHello message has been received, then either `do_keyx()` - * `do_sign()`, depending on the cipher suite. - */ -typedef struct br_ssl_server_policy_class_ br_ssl_server_policy_class; -struct br_ssl_server_policy_class_ { - /** - * \brief Context size (in bytes). - */ - size_t context_size; - - /** - * \brief Select algorithms and certificates for this connection. - * - * This callback function shall fill the provided `choices` - * structure with the policy choices for this connection. This - * entails selecting the cipher suite, hash function for signing - * the ServerKeyExchange (applicable only to ECDHE cipher suites), - * and certificate chain to send. - * - * The callback receives a pointer to the server context that - * contains the relevant data. In particular, the functions - * `br_ssl_server_get_client_suites()`, - * `br_ssl_server_get_client_hashes()` and - * `br_ssl_server_get_client_curves()` can be used to obtain - * the cipher suites, hash functions and elliptic curves - * supported by both the client and server, respectively. The - * `br_ssl_engine_get_version()` and `br_ssl_engine_get_server_name()` - * functions yield the protocol version and requested server name - * (SNI), respectively. - * - * This function may modify its context structure (`pctx`) in - * arbitrary ways to keep track of its own choices. - * - * This function shall return 1 if appropriate policy choices - * could be made, or 0 if this connection cannot be pursued. - * - * \param pctx policy context. - * \param cc SSL server context. - * \param choices destination structure for the policy choices. - * \return 1 on success, 0 on error. - */ - int (*choose)(const br_ssl_server_policy_class **pctx, - const br_ssl_server_context *cc, - br_ssl_server_choices *choices); - - /** - * \brief Perform key exchange (server part). - * - * This callback is invoked to perform the server-side cryptographic - * operation for a key exchange that is not ECDHE. This callback - * uses the private key. - * - * **For RSA key exchange**, the provided `data` (of length `*len` - * bytes) shall be decrypted with the server's private key, and - * the 48-byte premaster secret copied back to the first 48 bytes - * of `data`. - * - * - The caller makes sure that `*len` is at least 59 bytes. - * - * - This callback MUST check that the provided length matches - * that of the key modulus; it shall report an error otherwise. - * - * - If the length matches that of the RSA key modulus, then - * processing MUST be constant-time, even if decryption fails, - * or the padding is incorrect, or the plaintext message length - * is not exactly 48 bytes. - * - * - This callback needs not check the two first bytes of the - * obtained pre-master secret (the caller will do that). - * - * - If an error is reported (0), then what the callback put - * in the first 48 bytes of `data` is unimportant (the caller - * will use random bytes instead). - * - * **For ECDH key exchange**, the provided `data` (of length `*len` - * bytes) is the elliptic curve point from the client. The - * callback shall multiply it with its private key, and store - * the resulting X coordinate in `data`, starting at offset 0, - * and set `*len` to the length of the X coordinate. - * - * - If the input array does not have the proper length for - * an encoded curve point, then an error (0) shall be reported. - * - * - If the input array has the proper length, then processing - * MUST be constant-time, even if the data is not a valid - * encoded point. - * - * - This callback MUST check that the input point is valid. - * - * Returned value is 1 on success, 0 on error. - * - * \param pctx policy context. - * \param data key exchange data from the client. - * \param len key exchange data length (in bytes). - * \return 1 on success, 0 on error. - */ - uint32_t (*do_keyx)(const br_ssl_server_policy_class **pctx, - unsigned char *data, size_t *len); - - /** - * \brief Perform a signature (for a ServerKeyExchange message). - * - * This callback function is invoked for ECDHE cipher suites. On - * input, the hash value or message to sign is in `data`, of - * size `hv_len`; the involved hash function or algorithm is - * identified by `algo_id`. The signature shall be computed and - * written back into `data`; the total size of that buffer is - * `len` bytes. - * - * This callback shall verify that the signature length does not - * exceed `len` bytes, and abstain from writing the signature if - * it does not fit. - * - * The `algo_id` value matches that which was written in the - * `choices` structures by the `choose()` callback. This will be - * one of the following: - * - * - `0xFF00 + id` for a hash function identifier `id`. In - * that case, the `data` buffer contains a hash value - * already computed over the data that is to be signed, - * of length `hv_len`. The `id` may be 0 to designate the - * special MD5+SHA-1 concatenation (old-style RSA signing). - * - * - Another value, lower than `0xFF00`. The `data` buffer - * then contains the raw, non-hashed data to be signed - * (concatenation of the client and server randoms and - * ECDH parameters). The callback is responsible to apply - * any relevant hashing as part of the signing process. - * - * Returned value is the signature length (in bytes), or 0 on error. - * - * \param pctx policy context. - * \param algo_id hash function / algorithm identifier. - * \param data input/output buffer (message/hash, then signature). - * \param hv_len hash value or message length (in bytes). - * \param len total buffer length (in bytes). - * \return signature length (in bytes) on success, or 0 on error. - */ - size_t (*do_sign)(const br_ssl_server_policy_class **pctx, - unsigned algo_id, - unsigned char *data, size_t hv_len, size_t len); -}; - -/** - * \brief A single-chain RSA policy handler. - * - * This policy context uses a single certificate chain, and a RSA - * private key. The context can be restricted to only signatures or - * only key exchange. - * - * Apart from the first field (vtable pointer), its contents are - * opaque and shall not be accessed directly. - */ -typedef struct { - /** \brief Pointer to vtable. */ - const br_ssl_server_policy_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - const br_x509_certificate *chain; - size_t chain_len; - const br_rsa_private_key *sk; - unsigned allowed_usages; - br_rsa_private irsacore; - br_rsa_pkcs1_sign irsasign; -#endif -} br_ssl_server_policy_rsa_context; - -/** - * \brief A single-chain EC policy handler. - * - * This policy context uses a single certificate chain, and an EC - * private key. The context can be restricted to only signatures or - * only key exchange. - * - * Due to how TLS is defined, this context must be made aware whether - * the server certificate was itself signed with RSA or ECDSA. The code - * does not try to decode the certificate to obtain that information. - * - * Apart from the first field (vtable pointer), its contents are - * opaque and shall not be accessed directly. - */ -typedef struct { - /** \brief Pointer to vtable. */ - const br_ssl_server_policy_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - const br_x509_certificate *chain; - size_t chain_len; - const br_ec_private_key *sk; - unsigned allowed_usages; - unsigned cert_issuer_key_type; - const br_multihash_context *mhash; - const br_ec_impl *iec; - br_ecdsa_sign iecdsa; -#endif -} br_ssl_server_policy_ec_context; - -/** - * \brief Class type for a session parameter cache. - * - * Session parameters are saved in the cache with `save()`, and - * retrieved with `load()`. The cache implementation can apply any - * storage and eviction strategy that it sees fit. The SSL server - * context that performs the request is provided, so that its - * functionalities may be used by the implementation (e.g. hash - * functions or random number generation). - */ -typedef struct br_ssl_session_cache_class_ br_ssl_session_cache_class; -struct br_ssl_session_cache_class_ { - /** - * \brief Context size (in bytes). - */ - size_t context_size; - - /** - * \brief Record a session. - * - * This callback should record the provided session parameters. - * The `params` structure is transient, so its contents shall - * be copied into the cache. The session ID has been randomly - * generated and always has length exactly 32 bytes. - * - * \param ctx session cache context. - * \param server_ctx SSL server context. - * \param params session parameters to save. - */ - void (*save)(const br_ssl_session_cache_class **ctx, - br_ssl_server_context *server_ctx, - const br_ssl_session_parameters *params); - - /** - * \brief Lookup a session in the cache. - * - * The session ID to lookup is in `params` and always has length - * exactly 32 bytes. If the session parameters are found in the - * cache, then the parameters shall be copied into the `params` - * structure. Returned value is 1 on successful lookup, 0 - * otherwise. - * - * \param ctx session cache context. - * \param server_ctx SSL server context. - * \param params destination for session parameters. - * \return 1 if found, 0 otherwise. - */ - int (*load)(const br_ssl_session_cache_class **ctx, - br_ssl_server_context *server_ctx, - br_ssl_session_parameters *params); -}; - -/** - * \brief Context for a basic cache system. - * - * The system stores session parameters in a buffer provided at - * initialisation time. Each entry uses exactly 100 bytes, and - * buffer sizes up to 4294967295 bytes are supported. - * - * Entries are evicted with a LRU (Least Recently Used) policy. A - * search tree is maintained to keep lookups fast even with large - * caches. - * - * Apart from the first field (vtable pointer), the structure - * contents are opaque and shall not be accessed directly. - */ -typedef struct { - /** \brief Pointer to vtable. */ - const br_ssl_session_cache_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - unsigned char *store; - size_t store_len, store_ptr; - unsigned char index_key[32]; - const br_hash_class *hash; - int init_done; - uint32_t head, tail, root; -#endif -} br_ssl_session_cache_lru; - -/** - * \brief Initialise a LRU session cache with the provided storage space. - * - * The provided storage space must remain valid as long as the cache - * is used. Arbitrary lengths are supported, up to 4294967295 bytes; - * each entry uses up exactly 100 bytes. - * - * \param cc session cache context. - * \param store storage space for cached entries. - * \param store_len storage space length (in bytes). - */ -void br_ssl_session_cache_lru_init(br_ssl_session_cache_lru *cc, - unsigned char *store, size_t store_len); - -/** - * \brief Forget an entry in an LRU session cache. - * - * The session cache context must have been initialised. The entry - * with the provided session ID (of exactly 32 bytes) is looked for - * in the cache; if located, it is disabled. - * - * \param cc session cache context. - * \param id session ID to forget. - */ -void br_ssl_session_cache_lru_forget( - br_ssl_session_cache_lru *cc, const unsigned char *id); - -/** - * \brief Context structure for a SSL server. - * - * The first field (called `eng`) is the SSL engine; all functions that - * work on a `br_ssl_engine_context` structure shall take as parameter - * a pointer to that field. The other structure fields are opaque and - * must not be accessed directly. - */ -struct br_ssl_server_context_ { - /** - * \brief The encapsulated engine context. - */ - br_ssl_engine_context eng; - -#ifndef BR_DOXYGEN_IGNORE - /* - * Maximum version from the client. - */ - uint16_t client_max_version; - - /* - * Session cache. - */ - const br_ssl_session_cache_class **cache_vtable; - - /* - * Translated cipher suites supported by the client. The list - * is trimmed to include only the cipher suites that the - * server also supports; they are in the same order as in the - * client message. - */ - br_suite_translated client_suites[BR_MAX_CIPHER_SUITES]; - unsigned char client_suites_num; - - /* - * Hash functions supported by the client, with ECDSA and RSA - * (bit mask). For hash function with id 'x', set bit index is - * x for RSA, x+8 for ECDSA. For newer algorithms, with ID - * 0x08**, bit 16+k is set for algorithm 0x0800+k. - */ - uint32_t hashes; - - /* - * Curves supported by the client (bit mask, for named curves). - */ - uint32_t curves; - - /* - * Context for chain handler. - */ - const br_ssl_server_policy_class **policy_vtable; - uint16_t sign_hash_id; - - /* - * For the core handlers, thus avoiding (in most cases) the - * need for an externally provided policy context. - */ - union { - const br_ssl_server_policy_class *vtable; - br_ssl_server_policy_rsa_context single_rsa; - br_ssl_server_policy_ec_context single_ec; - } chain_handler; - - /* - * Buffer for the ECDHE private key. - */ - unsigned char ecdhe_key[70]; - size_t ecdhe_key_len; - - /* - * Trust anchor names for client authentication. "ta_names" and - * "tas" cannot be both non-NULL. - */ - const br_x500_name *ta_names; - const br_x509_trust_anchor *tas; - size_t num_tas; - size_t cur_dn_index; - const unsigned char *cur_dn; - size_t cur_dn_len; - - /* - * Buffer for the hash value computed over all handshake messages - * prior to CertificateVerify, and identifier for the hash function. - */ - unsigned char hash_CV[64]; - size_t hash_CV_len; - int hash_CV_id; - - /* - * Server-specific implementations. - * (none for now) - */ -#endif -}; - -/* - * Each br_ssl_server_init_xxx() function sets the list of supported - * cipher suites and used implementations, as specified by the profile - * name 'xxx'. Defined profile names are: - * - * full_rsa all supported algorithm, server key type is RSA - * full_ec all supported algorithm, server key type is EC - * TODO: add other profiles - * - * Naming scheme for "minimal" profiles: min123 - * - * -- character 1: key exchange - * r = RSA - * e = ECDHE_RSA - * f = ECDHE_ECDSA - * u = ECDH_RSA - * v = ECDH_ECDSA - * -- character 2: version / PRF - * 0 = TLS 1.0 / 1.1 with MD5+SHA-1 - * 2 = TLS 1.2 with SHA-256 - * 3 = TLS 1.2 with SHA-384 - * -- character 3: encryption - * a = AES/CBC - * d = 3DES/CBC - * g = AES/GCM - * c = ChaCha20+Poly1305 - */ - -/** - * \brief SSL server profile: full_rsa. - * - * This function initialises the provided SSL server context with - * all supported algorithms and cipher suites that rely on a RSA - * key pair. - * - * \param cc server context to initialise. - * \param chain server certificate chain. - * \param chain_len certificate chain length (number of certificate). - * \param sk RSA private key. - */ -void br_ssl_server_init_full_rsa(br_ssl_server_context *cc, - const br_x509_certificate *chain, size_t chain_len, - const br_rsa_private_key *sk); - -/** - * \brief SSL server profile: full_ec. - * - * This function initialises the provided SSL server context with - * all supported algorithms and cipher suites that rely on an EC - * key pair. - * - * The key type of the CA that issued the server's certificate must - * be provided, since it matters for ECDH cipher suites (ECDH_RSA - * suites require a RSA-powered CA). The key type is either - * `BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC`. - * - * \param cc server context to initialise. - * \param chain server certificate chain. - * \param chain_len chain length (number of certificates). - * \param cert_issuer_key_type certificate issuer's key type. - * \param sk EC private key. - */ -void br_ssl_server_init_full_ec(br_ssl_server_context *cc, - const br_x509_certificate *chain, size_t chain_len, - unsigned cert_issuer_key_type, const br_ec_private_key *sk); - -/** - * \brief SSL server profile: minr2g. - * - * This profile uses only TLS_RSA_WITH_AES_128_GCM_SHA256. Server key is - * RSA, and RSA key exchange is used (not forward secure, but uses little - * CPU in the client). - * - * \param cc server context to initialise. - * \param chain server certificate chain. - * \param chain_len certificate chain length (number of certificate). - * \param sk RSA private key. - */ -void br_ssl_server_init_minr2g(br_ssl_server_context *cc, - const br_x509_certificate *chain, size_t chain_len, - const br_rsa_private_key *sk); - -/** - * \brief SSL server profile: mine2g. - * - * This profile uses only TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256. Server key - * is RSA, and ECDHE key exchange is used. This suite provides forward - * security, with a higher CPU expense on the client, and a somewhat - * larger code footprint (compared to "minr2g"). - * - * \param cc server context to initialise. - * \param chain server certificate chain. - * \param chain_len certificate chain length (number of certificate). - * \param sk RSA private key. - */ -void br_ssl_server_init_mine2g(br_ssl_server_context *cc, - const br_x509_certificate *chain, size_t chain_len, - const br_rsa_private_key *sk); - -/** - * \brief SSL server profile: minf2g. - * - * This profile uses only TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256. - * Server key is EC, and ECDHE key exchange is used. This suite provides - * forward security, with a higher CPU expense on the client and server - * (by a factor of about 3 to 4), and a somewhat larger code footprint - * (compared to "minu2g" and "minv2g"). - * - * \param cc server context to initialise. - * \param chain server certificate chain. - * \param chain_len certificate chain length (number of certificate). - * \param sk EC private key. - */ -void br_ssl_server_init_minf2g(br_ssl_server_context *cc, - const br_x509_certificate *chain, size_t chain_len, - const br_ec_private_key *sk); - -/** - * \brief SSL server profile: minu2g. - * - * This profile uses only TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256. - * Server key is EC, and ECDH key exchange is used; the issuing CA used - * a RSA key. - * - * The "minu2g" and "minv2g" profiles do not provide forward secrecy, - * but are the lightest on the server (for CPU usage), and are rather - * inexpensive on the client as well. - * - * \param cc server context to initialise. - * \param chain server certificate chain. - * \param chain_len certificate chain length (number of certificate). - * \param sk EC private key. - */ -void br_ssl_server_init_minu2g(br_ssl_server_context *cc, - const br_x509_certificate *chain, size_t chain_len, - const br_ec_private_key *sk); - -/** - * \brief SSL server profile: minv2g. - * - * This profile uses only TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256. - * Server key is EC, and ECDH key exchange is used; the issuing CA used - * an EC key. - * - * The "minu2g" and "minv2g" profiles do not provide forward secrecy, - * but are the lightest on the server (for CPU usage), and are rather - * inexpensive on the client as well. - * - * \param cc server context to initialise. - * \param chain server certificate chain. - * \param chain_len certificate chain length (number of certificate). - * \param sk EC private key. - */ -void br_ssl_server_init_minv2g(br_ssl_server_context *cc, - const br_x509_certificate *chain, size_t chain_len, - const br_ec_private_key *sk); - -/** - * \brief SSL server profile: mine2c. - * - * This profile uses only TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256. - * Server key is RSA, and ECDHE key exchange is used. This suite - * provides forward security. - * - * \param cc server context to initialise. - * \param chain server certificate chain. - * \param chain_len certificate chain length (number of certificate). - * \param sk RSA private key. - */ -void br_ssl_server_init_mine2c(br_ssl_server_context *cc, - const br_x509_certificate *chain, size_t chain_len, - const br_rsa_private_key *sk); - -/** - * \brief SSL server profile: minf2c. - * - * This profile uses only TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256. - * Server key is EC, and ECDHE key exchange is used. This suite provides - * forward security. - * - * \param cc server context to initialise. - * \param chain server certificate chain. - * \param chain_len certificate chain length (number of certificate). - * \param sk EC private key. - */ -void br_ssl_server_init_minf2c(br_ssl_server_context *cc, - const br_x509_certificate *chain, size_t chain_len, - const br_ec_private_key *sk); - -/** - * \brief Get the supported client suites. - * - * This function shall be called only after the ClientHello has been - * processed, typically from the policy engine. The returned array - * contains the cipher suites that are supported by both the client - * and the server; these suites are in client preference order, unless - * the `BR_OPT_ENFORCE_SERVER_PREFERENCES` flag was set, in which case - * they are in server preference order. - * - * The suites are _translated_, which means that each suite is given - * as two 16-bit integers: the standard suite identifier, and its - * translated version, broken down into its individual components, - * as explained with the `br_suite_translated` type. - * - * The returned array is allocated in the context and will be rewritten - * by each handshake. - * - * \param cc server context. - * \param num receives the array size (number of suites). - * \return the translated common cipher suites, in preference order. - */ -static inline const br_suite_translated * -br_ssl_server_get_client_suites(const br_ssl_server_context *cc, size_t *num) -{ - *num = cc->client_suites_num; - return cc->client_suites; -} - -/** - * \brief Get the hash functions and signature algorithms supported by - * the client. - * - * This value is a bit field: - * - * - If RSA (PKCS#1 v1.5) is supported with hash function of ID `x`, - * then bit `x` is set (hash function ID is 0 for the special MD5+SHA-1, - * or 2 to 6 for the SHA family). - * - * - If ECDSA is supported with hash function of ID `x`, then bit `8+x` - * is set. - * - * - Newer algorithms are symbolic 16-bit identifiers that do not - * represent signature algorithm and hash function separately. If - * the TLS-level identifier is `0x0800+x` for a `x` in the 0..15 - * range, then bit `16+x` is set. - * - * "New algorithms" are currently defined only in draft documents, so - * this support is subject to possible change. Right now (early 2017), - * this maps ed25519 (EdDSA on Curve25519) to bit 23, and ed448 (EdDSA - * on Curve448) to bit 24. If the identifiers on the wire change in - * future document, then the decoding mechanism in BearSSL will be - * amended to keep mapping ed25519 and ed448 on bits 23 and 24, - * respectively. Mapping of other new algorithms (e.g. RSA/PSS) is not - * guaranteed yet. - * - * \param cc server context. - * \return the client-supported hash functions and signature algorithms. - */ -static inline uint32_t -br_ssl_server_get_client_hashes(const br_ssl_server_context *cc) -{ - return cc->hashes; -} - -/** - * \brief Get the elliptic curves supported by the client. - * - * This is a bit field (bit x is set if curve of ID x is supported). - * - * \param cc server context. - * \return the client-supported elliptic curves. - */ -static inline uint32_t -br_ssl_server_get_client_curves(const br_ssl_server_context *cc) -{ - return cc->curves; -} - -/** - * \brief Clear the complete contents of a SSL server context. - * - * Everything is cleared, including the reference to the configured buffer, - * implementations, cipher suites and state. This is a preparatory step - * to assembling a custom profile. - * - * \param cc server context to clear. - */ -void br_ssl_server_zero(br_ssl_server_context *cc); - -/** - * \brief Set an externally provided policy context. - * - * The policy context's methods are invoked to decide the cipher suite - * and certificate chain, and to perform operations involving the server's - * private key. - * - * \param cc server context. - * \param pctx policy context (pointer to its vtable field). - */ -static inline void -br_ssl_server_set_policy(br_ssl_server_context *cc, - const br_ssl_server_policy_class **pctx) -{ - cc->policy_vtable = pctx; -} - -/** - * \brief Set the server certificate chain and key (single RSA case). - * - * This function uses a policy context included in the server context. - * It configures use of a single server certificate chain with a RSA - * private key. The `allowed_usages` is a combination of usages, namely - * `BR_KEYTYPE_KEYX` and/or `BR_KEYTYPE_SIGN`; this enables or disables - * the corresponding cipher suites (i.e. `TLS_RSA_*` use the RSA key for - * key exchange, while `TLS_ECDHE_RSA_*` use the RSA key for signatures). - * - * \param cc server context. - * \param chain server certificate chain to send to the client. - * \param chain_len chain length (number of certificates). - * \param sk server private key (RSA). - * \param allowed_usages allowed private key usages. - * \param irsacore RSA core implementation. - * \param irsasign RSA signature implementation (PKCS#1 v1.5). - */ -void br_ssl_server_set_single_rsa(br_ssl_server_context *cc, - const br_x509_certificate *chain, size_t chain_len, - const br_rsa_private_key *sk, unsigned allowed_usages, - br_rsa_private irsacore, br_rsa_pkcs1_sign irsasign); - -/** - * \brief Set the server certificate chain and key (single EC case). - * - * This function uses a policy context included in the server context. - * It configures use of a single server certificate chain with an EC - * private key. The `allowed_usages` is a combination of usages, namely - * `BR_KEYTYPE_KEYX` and/or `BR_KEYTYPE_SIGN`; this enables or disables - * the corresponding cipher suites (i.e. `TLS_ECDH_*` use the EC key for - * key exchange, while `TLS_ECDHE_ECDSA_*` use the EC key for signatures). - * - * In order to support `TLS_ECDH_*` cipher suites (non-ephemeral ECDH), - * the algorithm type of the key used by the issuing CA to sign the - * server's certificate must be provided, as `cert_issuer_key_type` - * parameter (this value is either `BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC`). - * - * \param cc server context. - * \param chain server certificate chain to send. - * \param chain_len chain length (number of certificates). - * \param sk server private key (EC). - * \param allowed_usages allowed private key usages. - * \param cert_issuer_key_type issuing CA's key type. - * \param iec EC core implementation. - * \param iecdsa ECDSA signature implementation ("asn1" format). - */ -void br_ssl_server_set_single_ec(br_ssl_server_context *cc, - const br_x509_certificate *chain, size_t chain_len, - const br_ec_private_key *sk, unsigned allowed_usages, - unsigned cert_issuer_key_type, - const br_ec_impl *iec, br_ecdsa_sign iecdsa); - -/** - * \brief Activate client certificate authentication. - * - * The trust anchor encoded X.500 names (DN) to send to the client are - * provided. A client certificate will be requested and validated through - * the X.509 validator configured in the SSL engine. If `num` is 0, then - * client certificate authentication is disabled. - * - * If the client does not send a certificate, or on validation failure, - * the handshake aborts. Unauthenticated clients can be tolerated by - * setting the `BR_OPT_TOLERATE_NO_CLIENT_AUTH` flag. - * - * The provided array is linked in, not copied, so that pointer must - * remain valid as long as anchor names may be used. - * - * \param cc server context. - * \param ta_names encoded trust anchor names. - * \param num number of encoded trust anchor names. - */ -static inline void -br_ssl_server_set_trust_anchor_names(br_ssl_server_context *cc, - const br_x500_name *ta_names, size_t num) -{ - cc->ta_names = ta_names; - cc->tas = NULL; - cc->num_tas = num; -} - -/** - * \brief Activate client certificate authentication. - * - * This is a variant for `br_ssl_server_set_trust_anchor_names()`: the - * trust anchor names are provided not as an array of stand-alone names - * (`br_x500_name` structures), but as an array of trust anchors - * (`br_x509_trust_anchor` structures). The server engine itself will - * only use the `dn` field of each trust anchor. This is meant to allow - * defining a single array of trust anchors, to be used here and in the - * X.509 validation engine itself. - * - * The provided array is linked in, not copied, so that pointer must - * remain valid as long as anchor names may be used. - * - * \param cc server context. - * \param tas trust anchors (only names are used). - * \param num number of trust anchors. - */ -static inline void -br_ssl_server_set_trust_anchor_names_alt(br_ssl_server_context *cc, - const br_x509_trust_anchor *tas, size_t num) -{ - cc->ta_names = NULL; - cc->tas = tas; - cc->num_tas = num; -} - -/** - * \brief Configure the cache for session parameters. - * - * The cache context is provided as a pointer to its first field (vtable - * pointer). - * - * \param cc server context. - * \param vtable session cache context. - */ -static inline void -br_ssl_server_set_cache(br_ssl_server_context *cc, - const br_ssl_session_cache_class **vtable) -{ - cc->cache_vtable = vtable; -} - -/** - * \brief Prepare or reset a server context for handling an incoming client. - * - * \param cc server context. - * \return 1 on success, 0 on error. - */ -int br_ssl_server_reset(br_ssl_server_context *cc); - -/* ===================================================================== */ - -/* - * Context for the simplified I/O context. The transport medium is accessed - * through the low_read() and low_write() callback functions, each with - * its own opaque context pointer. - * - * low_read() read some bytes, at most 'len' bytes, into data[]. The - * returned value is the number of read bytes, or -1 on error. - * The 'len' parameter is guaranteed never to exceed 20000, - * so the length always fits in an 'int' on all platforms. - * - * low_write() write up to 'len' bytes, to be read from data[]. The - * returned value is the number of written bytes, or -1 on - * error. The 'len' parameter is guaranteed never to exceed - * 20000, so the length always fits in an 'int' on all - * parameters. - * - * A socket closure (if the transport medium is a socket) should be reported - * as an error (-1). The callbacks shall endeavour to block until at least - * one byte can be read or written; a callback returning 0 at times is - * acceptable, but this normally leads to the callback being immediately - * called again, so the callback should at least always try to block for - * some time if no I/O can take place. - * - * The SSL engine naturally applies some buffering, so the callbacks need - * not apply buffers of their own. - */ -/** - * \brief Context structure for the simplified SSL I/O wrapper. - * - * This structure is initialised with `br_sslio_init()`. Its contents - * are opaque and shall not be accessed directly. - */ -typedef struct { -#ifndef BR_DOXYGEN_IGNORE - br_ssl_engine_context *engine; - int (*low_read)(void *read_context, - unsigned char *data, size_t len); - void *read_context; - int (*low_write)(void *write_context, - const unsigned char *data, size_t len); - void *write_context; -#endif -} br_sslio_context; - -/** - * \brief Initialise a simplified I/O wrapper context. - * - * The simplified I/O wrapper offers a simpler read/write API for a SSL - * engine (client or server), using the provided callback functions for - * reading data from, or writing data to, the transport medium. - * - * The callback functions have the following semantics: - * - * - Each callback receives an opaque context value (of type `void *`) - * that the callback may use arbitrarily (or possibly ignore). - * - * - `low_read()` reads at least one byte, at most `len` bytes, from - * the transport medium. Read bytes shall be written in `data`. - * - * - `low_write()` writes at least one byte, at most `len` bytes, unto - * the transport medium. The bytes to write are read from `data`. - * - * - The `len` parameter is never zero, and is always lower than 20000. - * - * - The number of processed bytes (read or written) is returned. Since - * that number is less than 20000, it always fits on an `int`. - * - * - On error, the callbacks return -1. Reaching end-of-stream is an - * error. Errors are permanent: the SSL connection is terminated. - * - * - Callbacks SHOULD NOT return 0. This is tolerated, as long as - * callbacks endeavour to block for some non-negligible amount of - * time until at least one byte can be sent or received (if a - * callback returns 0, then the wrapper invokes it again - * immediately). - * - * - Callbacks MAY return as soon as at least one byte is processed; - * they MAY also insist on reading or writing _all_ requested bytes. - * Since SSL is a self-terminated protocol (each record has a length - * header), this does not change semantics. - * - * - Callbacks need not apply any buffering (for performance) since SSL - * itself uses buffers. - * - * \param ctx wrapper context to initialise. - * \param engine SSL engine to wrap. - * \param low_read callback for reading data from the transport. - * \param read_context context pointer for `low_read()`. - * \param low_write callback for writing data on the transport. - * \param write_context context pointer for `low_write()`. - */ -void br_sslio_init(br_sslio_context *ctx, - br_ssl_engine_context *engine, - int (*low_read)(void *read_context, - unsigned char *data, size_t len), - void *read_context, - int (*low_write)(void *write_context, - const unsigned char *data, size_t len), - void *write_context); - -/** - * \brief Read some application data from a SSL connection. - * - * If `len` is zero, then this function returns 0 immediately. In - * all other cases, it never returns 0. - * - * This call returns only when at least one byte has been obtained. - * Returned value is the number of bytes read, or -1 on error. The - * number of bytes always fits on an 'int' (data from a single SSL/TLS - * record is returned). - * - * On error or SSL closure, this function returns -1. The caller should - * inspect the error status on the SSL engine to distinguish between - * normal closure and error. - * - * \param cc SSL wrapper context. - * \param dst destination buffer for application data. - * \param len maximum number of bytes to obtain. - * \return number of bytes obtained, or -1 on error. - */ -int br_sslio_read(br_sslio_context *cc, void *dst, size_t len); - -/** - * \brief Read application data from a SSL connection. - * - * This calls returns only when _all_ requested `len` bytes are read, - * or an error is reached. Returned value is 0 on success, -1 on error. - * A normal (verified) SSL closure before that many bytes are obtained - * is reported as an error by this function. - * - * \param cc SSL wrapper context. - * \param dst destination buffer for application data. - * \param len number of bytes to obtain. - * \return 0 on success, or -1 on error. - */ -int br_sslio_read_all(br_sslio_context *cc, void *dst, size_t len); - -#ifdef ARDUINO -int br_sslio_read_available(br_sslio_context *cc); -int br_sslio_peek(br_sslio_context *cc, void *dst, size_t len); -#endif - -/** - * \brief Write some application data unto a SSL connection. - * - * If `len` is zero, then this function returns 0 immediately. In - * all other cases, it never returns 0. - * - * This call returns only when at least one byte has been written. - * Returned value is the number of bytes written, or -1 on error. The - * number of bytes always fits on an 'int' (less than 20000). - * - * On error or SSL closure, this function returns -1. The caller should - * inspect the error status on the SSL engine to distinguish between - * normal closure and error. - * - * **Important:** SSL is buffered; a "written" byte is a byte that was - * injected into the wrapped SSL engine, but this does not necessarily mean - * that it has been scheduled for sending. Use `br_sslio_flush()` to - * ensure that all pending data has been sent to the transport medium. - * - * \param cc SSL wrapper context. - * \param src source buffer for application data. - * \param len maximum number of bytes to write. - * \return number of bytes written, or -1 on error. - */ -int br_sslio_write(br_sslio_context *cc, const void *src, size_t len); - -/** - * \brief Write application data unto a SSL connection. - * - * This calls returns only when _all_ requested `len` bytes have been - * written, or an error is reached. Returned value is 0 on success, -1 - * on error. A normal (verified) SSL closure before that many bytes are - * written is reported as an error by this function. - * - * **Important:** SSL is buffered; a "written" byte is a byte that was - * injected into the wrapped SSL engine, but this does not necessarily mean - * that it has been scheduled for sending. Use `br_sslio_flush()` to - * ensure that all pending data has been sent to the transport medium. - * - * \param cc SSL wrapper context. - * \param src source buffer for application data. - * \param len number of bytes to write. - * \return 0 on success, or -1 on error. - */ -int br_sslio_write_all(br_sslio_context *cc, const void *src, size_t len); - -/** - * \brief Flush pending data. - * - * This call makes sure that any buffered application data in the - * provided context (including the wrapped SSL engine) has been sent - * to the transport medium (i.e. accepted by the `low_write()` callback - * method). If there is no such pending data, then this function does - * nothing (and returns a success, i.e. 0). - * - * If the underlying transport medium has its own buffers, then it is - * up to the caller to ensure the corresponding flushing. - * - * Returned value is 0 on success, -1 on error. - * - * \param cc SSL wrapper context. - * \return 0 on success, or -1 on error. - */ -int br_sslio_flush(br_sslio_context *cc); - -/** - * \brief Close the SSL connection. - * - * This call runs the SSL closure protocol (sending a `close_notify`, - * receiving the response `close_notify`). When it returns, the SSL - * connection is finished. It is still up to the caller to manage the - * possible transport-level termination, if applicable (alternatively, - * the underlying transport stream may be reused for non-SSL messages). - * - * Returned value is 0 on success, -1 on error. A failure by the peer - * to process the complete closure protocol (i.e. sending back the - * `close_notify`) is an error. - * - * \param cc SSL wrapper context. - * \return 0 on success, or -1 on error. - */ -int br_sslio_close(br_sslio_context *cc); - -/* ===================================================================== */ - -/* - * Symbolic constants for cipher suites. - */ - -/* From RFC 5246 */ -#define BR_TLS_NULL_WITH_NULL_NULL 0x0000 -#define BR_TLS_RSA_WITH_NULL_MD5 0x0001 -#define BR_TLS_RSA_WITH_NULL_SHA 0x0002 -#define BR_TLS_RSA_WITH_NULL_SHA256 0x003B -#define BR_TLS_RSA_WITH_RC4_128_MD5 0x0004 -#define BR_TLS_RSA_WITH_RC4_128_SHA 0x0005 -#define BR_TLS_RSA_WITH_3DES_EDE_CBC_SHA 0x000A -#define BR_TLS_RSA_WITH_AES_128_CBC_SHA 0x002F -#define BR_TLS_RSA_WITH_AES_256_CBC_SHA 0x0035 -#define BR_TLS_RSA_WITH_AES_128_CBC_SHA256 0x003C -#define BR_TLS_RSA_WITH_AES_256_CBC_SHA256 0x003D -#define BR_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA 0x000D -#define BR_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA 0x0010 -#define BR_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA 0x0013 -#define BR_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA 0x0016 -#define BR_TLS_DH_DSS_WITH_AES_128_CBC_SHA 0x0030 -#define BR_TLS_DH_RSA_WITH_AES_128_CBC_SHA 0x0031 -#define BR_TLS_DHE_DSS_WITH_AES_128_CBC_SHA 0x0032 -#define BR_TLS_DHE_RSA_WITH_AES_128_CBC_SHA 0x0033 -#define BR_TLS_DH_DSS_WITH_AES_256_CBC_SHA 0x0036 -#define BR_TLS_DH_RSA_WITH_AES_256_CBC_SHA 0x0037 -#define BR_TLS_DHE_DSS_WITH_AES_256_CBC_SHA 0x0038 -#define BR_TLS_DHE_RSA_WITH_AES_256_CBC_SHA 0x0039 -#define BR_TLS_DH_DSS_WITH_AES_128_CBC_SHA256 0x003E -#define BR_TLS_DH_RSA_WITH_AES_128_CBC_SHA256 0x003F -#define BR_TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 0x0040 -#define BR_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 0x0067 -#define BR_TLS_DH_DSS_WITH_AES_256_CBC_SHA256 0x0068 -#define BR_TLS_DH_RSA_WITH_AES_256_CBC_SHA256 0x0069 -#define BR_TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 0x006A -#define BR_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 0x006B -#define BR_TLS_DH_anon_WITH_RC4_128_MD5 0x0018 -#define BR_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA 0x001B -#define BR_TLS_DH_anon_WITH_AES_128_CBC_SHA 0x0034 -#define BR_TLS_DH_anon_WITH_AES_256_CBC_SHA 0x003A -#define BR_TLS_DH_anon_WITH_AES_128_CBC_SHA256 0x006C -#define BR_TLS_DH_anon_WITH_AES_256_CBC_SHA256 0x006D - -/* From RFC 4492 */ -#define BR_TLS_ECDH_ECDSA_WITH_NULL_SHA 0xC001 -#define BR_TLS_ECDH_ECDSA_WITH_RC4_128_SHA 0xC002 -#define BR_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA 0xC003 -#define BR_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA 0xC004 -#define BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA 0xC005 -#define BR_TLS_ECDHE_ECDSA_WITH_NULL_SHA 0xC006 -#define BR_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA 0xC007 -#define BR_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA 0xC008 -#define BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0xC009 -#define BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0xC00A -#define BR_TLS_ECDH_RSA_WITH_NULL_SHA 0xC00B -#define BR_TLS_ECDH_RSA_WITH_RC4_128_SHA 0xC00C -#define BR_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA 0xC00D -#define BR_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA 0xC00E -#define BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA 0xC00F -#define BR_TLS_ECDHE_RSA_WITH_NULL_SHA 0xC010 -#define BR_TLS_ECDHE_RSA_WITH_RC4_128_SHA 0xC011 -#define BR_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA 0xC012 -#define BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 0xC013 -#define BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 0xC014 -#define BR_TLS_ECDH_anon_WITH_NULL_SHA 0xC015 -#define BR_TLS_ECDH_anon_WITH_RC4_128_SHA 0xC016 -#define BR_TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA 0xC017 -#define BR_TLS_ECDH_anon_WITH_AES_128_CBC_SHA 0xC018 -#define BR_TLS_ECDH_anon_WITH_AES_256_CBC_SHA 0xC019 - -/* From RFC 5288 */ -#define BR_TLS_RSA_WITH_AES_128_GCM_SHA256 0x009C -#define BR_TLS_RSA_WITH_AES_256_GCM_SHA384 0x009D -#define BR_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 0x009E -#define BR_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 0x009F -#define BR_TLS_DH_RSA_WITH_AES_128_GCM_SHA256 0x00A0 -#define BR_TLS_DH_RSA_WITH_AES_256_GCM_SHA384 0x00A1 -#define BR_TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 0x00A2 -#define BR_TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 0x00A3 -#define BR_TLS_DH_DSS_WITH_AES_128_GCM_SHA256 0x00A4 -#define BR_TLS_DH_DSS_WITH_AES_256_GCM_SHA384 0x00A5 -#define BR_TLS_DH_anon_WITH_AES_128_GCM_SHA256 0x00A6 -#define BR_TLS_DH_anon_WITH_AES_256_GCM_SHA384 0x00A7 - -/* From RFC 5289 */ -#define BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 0xC023 -#define BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 0xC024 -#define BR_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 0xC025 -#define BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 0xC026 -#define BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 0xC027 -#define BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 0xC028 -#define BR_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 0xC029 -#define BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 0xC02A -#define BR_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0xC02B -#define BR_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 0xC02C -#define BR_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 0xC02D -#define BR_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 0xC02E -#define BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0xC02F -#define BR_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0xC030 -#define BR_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 0xC031 -#define BR_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 0xC032 - -/* From RFC 6655 and 7251 */ -#define BR_TLS_RSA_WITH_AES_128_CCM 0xC09C -#define BR_TLS_RSA_WITH_AES_256_CCM 0xC09D -#define BR_TLS_RSA_WITH_AES_128_CCM_8 0xC0A0 -#define BR_TLS_RSA_WITH_AES_256_CCM_8 0xC0A1 -#define BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM 0xC0AC -#define BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM 0xC0AD -#define BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 0xC0AE -#define BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 0xC0AF - -/* From RFC 7905 */ -#define BR_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA8 -#define BR_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA9 -#define BR_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCCAA -#define BR_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAB -#define BR_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAC -#define BR_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAD -#define BR_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAE - -/* From RFC 7507 */ -#define BR_TLS_FALLBACK_SCSV 0x5600 - -/* - * Symbolic constants for alerts. - */ -#define BR_ALERT_CLOSE_NOTIFY 0 -#define BR_ALERT_UNEXPECTED_MESSAGE 10 -#define BR_ALERT_BAD_RECORD_MAC 20 -#define BR_ALERT_RECORD_OVERFLOW 22 -#define BR_ALERT_DECOMPRESSION_FAILURE 30 -#define BR_ALERT_HANDSHAKE_FAILURE 40 -#define BR_ALERT_BAD_CERTIFICATE 42 -#define BR_ALERT_UNSUPPORTED_CERTIFICATE 43 -#define BR_ALERT_CERTIFICATE_REVOKED 44 -#define BR_ALERT_CERTIFICATE_EXPIRED 45 -#define BR_ALERT_CERTIFICATE_UNKNOWN 46 -#define BR_ALERT_ILLEGAL_PARAMETER 47 -#define BR_ALERT_UNKNOWN_CA 48 -#define BR_ALERT_ACCESS_DENIED 49 -#define BR_ALERT_DECODE_ERROR 50 -#define BR_ALERT_DECRYPT_ERROR 51 -#define BR_ALERT_PROTOCOL_VERSION 70 -#define BR_ALERT_INSUFFICIENT_SECURITY 71 -#define BR_ALERT_INTERNAL_ERROR 80 -#define BR_ALERT_USER_CANCELED 90 -#define BR_ALERT_NO_RENEGOTIATION 100 -#define BR_ALERT_UNSUPPORTED_EXTENSION 110 -#define BR_ALERT_NO_APPLICATION_PROTOCOL 120 - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/tls/bearssl/bearssl_x509.h b/src/tls/bearssl/bearssl_x509.h deleted file mode 100644 index 49d2fba0d..000000000 --- a/src/tls/bearssl/bearssl_x509.h +++ /dev/null @@ -1,1397 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef BR_BEARSSL_X509_H__ -#define BR_BEARSSL_X509_H__ - -#include -#include - -#include "bearssl_ec.h" -#include "bearssl_hash.h" -#include "bearssl_rsa.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** \file bearssl_x509.h - * - * # X.509 Certificate Chain Processing - * - * An X.509 processing engine receives an X.509 chain, chunk by chunk, - * as received from a SSL/TLS client or server (the client receives the - * server's certificate chain, and the server receives the client's - * certificate chain if it requested a client certificate). The chain - * is thus injected in the engine in SSL order (end-entity first). - * - * The engine's job is to return the public key to use for SSL/TLS. - * How exactly that key is obtained and verified is entirely up to the - * engine. - * - * **The "known key" engine** returns a public key which is already known - * from out-of-band information (e.g. the client _remembers_ the key from - * a previous connection, as in the usual SSH model). This is the simplest - * engine since it simply ignores the chain, thereby avoiding the need - * for any decoding logic. - * - * **The "minimal" engine** implements minimal X.509 decoding and chain - * validation: - * - * - The provided chain should validate "as is". There is no attempt - * at reordering, skipping or downloading extra certificates. - * - * - X.509 v1, v2 and v3 certificates are supported. - * - * - Trust anchors are a DN and a public key. Each anchor is either a - * "CA" anchor, or a non-CA. - * - * - If the end-entity certificate matches a non-CA anchor (subject DN - * is equal to the non-CA name, and public key is also identical to - * the anchor key), then this is a _direct trust_ case and the - * remaining certificates are ignored. - * - * - Unless direct trust is applied, the chain must be verifiable up to - * a certificate whose issuer DN matches the DN from a "CA" trust anchor, - * and whose signature is verifiable against that anchor's public key. - * Subsequent certificates in the chain are ignored. - * - * - The engine verifies subject/issuer DN matching, and enforces - * processing of Basic Constraints and Key Usage extensions. The - * Authority Key Identifier, Subject Key Identifier, Issuer Alt Name, - * Subject Directory Attribute, CRL Distribution Points, Freshest CRL, - * Authority Info Access and Subject Info Access extensions are - * ignored. The Subject Alt Name is decoded for the end-entity - * certificate under some conditions (see below). Other extensions - * are ignored if non-critical, or imply chain rejection if critical. - * - * - The Subject Alt Name extension is parsed for names of type `dNSName` - * when decoding the end-entity certificate, and only if there is a - * server name to match. If there is no SAN extension, then the - * Common Name from the subjectDN is used. That name matching is - * case-insensitive and honours a single starting wildcard (i.e. if - * the name in the certificate starts with "`*.`" then this matches - * any word as first element). Note: this name matching is performed - * also in the "direct trust" model. - * - * - DN matching is byte-to-byte equality (a future version might - * include some limited processing for case-insensitive matching and - * whitespace normalisation). - * - * - Successful validation produces a public key type but also a set - * of allowed usages (`BR_KEYTYPE_KEYX` and/or `BR_KEYTYPE_SIGN`). - * The caller is responsible for checking that the key type and - * usages are compatible with the expected values (e.g. with the - * selected cipher suite, when the client validates the server's - * certificate). - * - * **Important caveats:** - * - * - The "minimal" engine does not check revocation status. The relevant - * extensions are ignored, and CRL or OCSP responses are not gathered - * or checked. - * - * - The "minimal" engine does not currently support Name Constraints - * (some basic functionality to handle sub-domains may be added in a - * later version). - * - * - The decoder is not "validating" in the sense that it won't reject - * some certificates with invalid field values when these fields are - * not actually processed. - */ - -/* - * X.509 error codes are in the 32..63 range. - */ - -/** \brief X.509 status: validation was successful; this is not actually - an error. */ -#define BR_ERR_X509_OK 32 - -/** \brief X.509 status: invalid value in an ASN.1 structure. */ -#define BR_ERR_X509_INVALID_VALUE 33 - -/** \brief X.509 status: truncated certificate. */ -#define BR_ERR_X509_TRUNCATED 34 - -/** \brief X.509 status: empty certificate chain (no certificate at all). */ -#define BR_ERR_X509_EMPTY_CHAIN 35 - -/** \brief X.509 status: decoding error: inner element extends beyond - outer element size. */ -#define BR_ERR_X509_INNER_TRUNC 36 - -/** \brief X.509 status: decoding error: unsupported tag class (application - or private). */ -#define BR_ERR_X509_BAD_TAG_CLASS 37 - -/** \brief X.509 status: decoding error: unsupported tag value. */ -#define BR_ERR_X509_BAD_TAG_VALUE 38 - -/** \brief X.509 status: decoding error: indefinite length. */ -#define BR_ERR_X509_INDEFINITE_LENGTH 39 - -/** \brief X.509 status: decoding error: extraneous element. */ -#define BR_ERR_X509_EXTRA_ELEMENT 40 - -/** \brief X.509 status: decoding error: unexpected element. */ -#define BR_ERR_X509_UNEXPECTED 41 - -/** \brief X.509 status: decoding error: expected constructed element, but - is primitive. */ -#define BR_ERR_X509_NOT_CONSTRUCTED 42 - -/** \brief X.509 status: decoding error: expected primitive element, but - is constructed. */ -#define BR_ERR_X509_NOT_PRIMITIVE 43 - -/** \brief X.509 status: decoding error: BIT STRING length is not multiple - of 8. */ -#define BR_ERR_X509_PARTIAL_BYTE 44 - -/** \brief X.509 status: decoding error: BOOLEAN value has invalid length. */ -#define BR_ERR_X509_BAD_BOOLEAN 45 - -/** \brief X.509 status: decoding error: value is off-limits. */ -#define BR_ERR_X509_OVERFLOW 46 - -/** \brief X.509 status: invalid distinguished name. */ -#define BR_ERR_X509_BAD_DN 47 - -/** \brief X.509 status: invalid date/time representation. */ -#define BR_ERR_X509_BAD_TIME 48 - -/** \brief X.509 status: certificate contains unsupported features that - cannot be ignored. */ -#define BR_ERR_X509_UNSUPPORTED 49 - -/** \brief X.509 status: key or signature size exceeds internal limits. */ -#define BR_ERR_X509_LIMIT_EXCEEDED 50 - -/** \brief X.509 status: key type does not match that which was expected. */ -#define BR_ERR_X509_WRONG_KEY_TYPE 51 - -/** \brief X.509 status: signature is invalid. */ -#define BR_ERR_X509_BAD_SIGNATURE 52 - -/** \brief X.509 status: validation time is unknown. */ -#define BR_ERR_X509_TIME_UNKNOWN 53 - -/** \brief X.509 status: certificate is expired or not yet valid. */ -#define BR_ERR_X509_EXPIRED 54 - -/** \brief X.509 status: issuer/subject DN mismatch in the chain. */ -#define BR_ERR_X509_DN_MISMATCH 55 - -/** \brief X.509 status: expected server name was not found in the chain. */ -#define BR_ERR_X509_BAD_SERVER_NAME 56 - -/** \brief X.509 status: unknown critical extension in certificate. */ -#define BR_ERR_X509_CRITICAL_EXTENSION 57 - -/** \brief X.509 status: not a CA, or path length constraint violation */ -#define BR_ERR_X509_NOT_CA 58 - -/** \brief X.509 status: Key Usage extension prohibits intended usage. */ -#define BR_ERR_X509_FORBIDDEN_KEY_USAGE 59 - -/** \brief X.509 status: public key found in certificate is too small. */ -#define BR_ERR_X509_WEAK_PUBLIC_KEY 60 - -/** \brief X.509 status: chain could not be linked to a trust anchor. */ -#define BR_ERR_X509_NOT_TRUSTED 62 - -/** - * \brief Aggregate structure for public keys. - */ -typedef struct { - /** \brief Key type: `BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC` */ - unsigned char key_type; - /** \brief Actual public key. */ - union { - /** \brief RSA public key. */ - br_rsa_public_key rsa; - /** \brief EC public key. */ - br_ec_public_key ec; - } key; -} br_x509_pkey; - -/** - * \brief Distinguished Name (X.500) structure. - * - * The DN is DER-encoded. - */ -typedef struct { - /** \brief Encoded DN data. */ - unsigned char *data; - /** \brief Encoded DN length (in bytes). */ - size_t len; -} br_x500_name; - -/** - * \brief Trust anchor structure. - */ -typedef struct { - /** \brief Encoded DN (X.500 name). */ - br_x500_name dn; - /** \brief Anchor flags (e.g. `BR_X509_TA_CA`). */ - unsigned flags; - /** \brief Anchor public key. */ - br_x509_pkey pkey; -} br_x509_trust_anchor; - -/** - * \brief Trust anchor flag: CA. - * - * A "CA" anchor is deemed fit to verify signatures on certificates. - * A "non-CA" anchor is accepted only for direct trust (server's - * certificate name and key match the anchor). - */ -#define BR_X509_TA_CA 0x0001 - -/* - * Key type: combination of a basic key type (low 4 bits) and some - * optional flags. - * - * For a public key, the basic key type only is set. - * - * For an expected key type, the flags indicate the intended purpose(s) - * for the key; the basic key type may be set to 0 to indicate that any - * key type compatible with the indicated purpose is acceptable. - */ -/** \brief Key type: algorithm is RSA. */ -#define BR_KEYTYPE_RSA 1 -/** \brief Key type: algorithm is EC. */ -#define BR_KEYTYPE_EC 2 - -/** - * \brief Key type: usage is "key exchange". - * - * This value is combined (with bitwise OR) with the algorithm - * (`BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC`) when informing the X.509 - * validation engine that it should find a public key of that type, - * fit for key exchanges (e.g. `TLS_RSA_*` and `TLS_ECDH_*` cipher - * suites). - */ -#define BR_KEYTYPE_KEYX 0x10 - -/** - * \brief Key type: usage is "signature". - * - * This value is combined (with bitwise OR) with the algorithm - * (`BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC`) when informing the X.509 - * validation engine that it should find a public key of that type, - * fit for signatures (e.g. `TLS_ECDHE_*` cipher suites). - */ -#define BR_KEYTYPE_SIGN 0x20 - -/* - * start_chain Called when a new chain is started. If 'server_name' - * is not NULL and non-empty, then it is a name that - * should be looked for in the EE certificate (in the - * SAN extension as dNSName, or in the subjectDN's CN - * if there is no SAN extension). - * The caller ensures that the provided 'server_name' - * pointer remains valid throughout validation. - * - * start_cert Begins a new certificate in the chain. The provided - * length is in bytes; this is the total certificate length. - * - * append Get some additional bytes for the current certificate. - * - * end_cert Ends the current certificate. - * - * end_chain Called at the end of the chain. Returned value is - * 0 on success, or a non-zero error code. - * - * get_pkey Returns the EE certificate public key. - * - * For a complete chain, start_chain() and end_chain() are always - * called. For each certificate, start_cert(), some append() calls, then - * end_cert() are called, in that order. There may be no append() call - * at all if the certificate is empty (which is not valid but may happen - * if the peer sends exactly that). - * - * get_pkey() shall return a pointer to a structure that is valid as - * long as a new chain is not started. This may be a sub-structure - * within the context for the engine. This function MAY return a valid - * pointer to a public key even in some cases of validation failure, - * depending on the validation engine. - */ - -/** - * \brief Class type for an X.509 engine. - * - * A certificate chain validation uses a caller-allocated context, which - * contains the running state for that validation. Methods are called - * in due order: - * - * - `start_chain()` is called at the start of the validation. - * - Certificates are processed one by one, in SSL order (end-entity - * comes first). For each certificate, the following methods are - * called: - * - * - `start_cert()` at the beginning of the certificate. - * - `append()` is called zero, one or more times, to provide - * the certificate (possibly in chunks). - * - `end_cert()` at the end of the certificate. - * - * - `end_chain()` is called when the last certificate in the chain - * was processed. - * - `get_pkey()` is called after chain processing, if the chain - * validation was successful. - * - * A context structure may be reused; the `start_chain()` method shall - * ensure (re)initialisation. - */ -typedef struct br_x509_class_ br_x509_class; -struct br_x509_class_ { - /** - * \brief X.509 context size, in bytes. - */ - size_t context_size; - - /** - * \brief Start a new chain. - * - * This method shall set the vtable (first field) of the context - * structure. - * - * The `server_name`, if not `NULL`, will be considered as a - * fully qualified domain name, to be matched against the `dNSName` - * elements of the end-entity certificate's SAN extension (if there - * is no SAN, then the Common Name from the subjectDN will be used). - * If `server_name` is `NULL` then no such matching is performed. - * - * \param ctx validation context. - * \param server_name server name to match (or `NULL`). - */ - void (*start_chain)(const br_x509_class **ctx, - const char *server_name); - - /** - * \brief Start a new certificate. - * - * \param ctx validation context. - * \param length new certificate length (in bytes). - */ - void (*start_cert)(const br_x509_class **ctx, uint32_t length); - - /** - * \brief Receive some bytes for the current certificate. - * - * This function may be called several times in succession for - * a given certificate. The caller guarantees that for each - * call, `len` is not zero, and the sum of all chunk lengths - * for a certificate matches the total certificate length which - * was provided in the previous `start_cert()` call. - * - * If the new certificate is empty (no byte at all) then this - * function won't be called at all. - * - * \param ctx validation context. - * \param buf certificate data chunk. - * \param len certificate data chunk length (in bytes). - */ - void (*append)(const br_x509_class **ctx, - const unsigned char *buf, size_t len); - - /** - * \brief Finish the current certificate. - * - * This function is called when the end of the current certificate - * is reached. - * - * \param ctx validation context. - */ - void (*end_cert)(const br_x509_class **ctx); - - /** - * \brief Finish the chain. - * - * This function is called at the end of the chain. It shall - * return either 0 if the validation was successful, or a - * non-zero error code. The `BR_ERR_X509_*` constants are - * error codes, though other values may be possible. - * - * \param ctx validation context. - * \return 0 on success, or a non-zero error code. - */ - unsigned (*end_chain)(const br_x509_class **ctx); - - /** - * \brief Get the resulting end-entity public key. - * - * The decoded public key is returned. The returned pointer - * may be valid only as long as the context structure is - * unmodified, i.e. it may cease to be valid if the context - * is released or reused. - * - * This function _may_ return `NULL` if the validation failed. - * However, returning a public key does not mean that the - * validation was wholly successful; some engines may return - * a decoded public key even if the chain did not end on a - * trusted anchor. - * - * If validation succeeded and `usage` is not `NULL`, then - * `*usage` is filled with a combination of `BR_KEYTYPE_SIGN` - * and/or `BR_KEYTYPE_KEYX` that specifies the validated key - * usage types. It is the caller's responsibility to check - * that value against the intended use of the public key. - * - * \param ctx validation context. - * \return the end-entity public key, or `NULL`. - */ - const br_x509_pkey *(*get_pkey)( - const br_x509_class *const *ctx, unsigned *usages); -}; - -/** - * \brief The "known key" X.509 engine structure. - * - * The structure contents are opaque (they shall not be accessed directly), - * except for the first field (the vtable). - * - * The "known key" engine returns an externally configured public key, - * and totally ignores the certificate contents. - */ -typedef struct { - /** \brief Reference to the context vtable. */ - const br_x509_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - br_x509_pkey pkey; - unsigned usages; -#endif -} br_x509_knownkey_context; - -/** - * \brief Class instance for the "known key" X.509 engine. - */ -extern const br_x509_class br_x509_knownkey_vtable; - -/** - * \brief Initialize a "known key" X.509 engine with a known RSA public key. - * - * The `usages` parameter indicates the allowed key usages for that key - * (`BR_KEYTYPE_KEYX` and/or `BR_KEYTYPE_SIGN`). - * - * The provided pointers are linked in, not copied, so they must remain - * valid while the public key may be in usage. - * - * \param ctx context to initialise. - * \param pk known public key. - * \param usages allowed key usages. - */ -void br_x509_knownkey_init_rsa(br_x509_knownkey_context *ctx, - const br_rsa_public_key *pk, unsigned usages); - -/** - * \brief Initialize a "known key" X.509 engine with a known EC public key. - * - * The `usages` parameter indicates the allowed key usages for that key - * (`BR_KEYTYPE_KEYX` and/or `BR_KEYTYPE_SIGN`). - * - * The provided pointers are linked in, not copied, so they must remain - * valid while the public key may be in usage. - * - * \param ctx context to initialise. - * \param pk known public key. - * \param usages allowed key usages. - */ -void br_x509_knownkey_init_ec(br_x509_knownkey_context *ctx, - const br_ec_public_key *pk, unsigned usages); - -#ifndef BR_DOXYGEN_IGNORE -/* - * The minimal X.509 engine has some state buffers which must be large - * enough to simultaneously accommodate: - * -- the public key extracted from the current certificate; - * -- the signature on the current certificate or on the previous - * certificate; - * -- the public key extracted from the EE certificate. - * - * We store public key elements in their raw unsigned big-endian - * encoding. We want to support up to RSA-4096 with a short (up to 64 - * bits) public exponent, thus a buffer for a public key must have - * length at least 520 bytes. Similarly, a RSA-4096 signature has length - * 512 bytes. - * - * Though RSA public exponents can formally be as large as the modulus - * (mathematically, even larger exponents would work, but PKCS#1 forbids - * them), exponents that do not fit on 32 bits are extremely rare, - * notably because some widespread implementations (e.g. Microsoft's - * CryptoAPI) don't support them. Moreover, large public exponent do not - * seem to imply any tangible security benefit, and they increase the - * cost of public key operations. The X.509 "minimal" engine will tolerate - * public exponents of arbitrary size as long as the modulus and the - * exponent can fit together in the dedicated buffer. - * - * EC public keys are shorter than RSA public keys; even with curve - * NIST P-521 (the largest curve we care to support), a public key is - * encoded over 133 bytes only. - */ -#define BR_X509_BUFSIZE_KEY 520 -#define BR_X509_BUFSIZE_SIG 512 -#endif - -/** - * \brief Type for receiving a name element. - * - * An array of such structures can be provided to the X.509 decoding - * engines. If the specified elements are found in the certificate - * subject DN or the SAN extension, then the name contents are copied - * as zero-terminated strings into the buffer. - * - * The decoder converts TeletexString and BMPString to UTF8String, and - * ensures that the resulting string is zero-terminated. If the string - * does not fit in the provided buffer, then the copy is aborted and an - * error is reported. - */ -typedef struct { - /** - * \brief Element OID. - * - * For X.500 name elements (to be extracted from the subject DN), - * this is the encoded OID for the requested name element; the - * first byte shall contain the length of the DER-encoded OID - * value, followed by the OID value (for instance, OID 2.5.4.3, - * for id-at-commonName, will be `03 55 04 03`). This is - * equivalent to full DER encoding with the length but without - * the tag. - * - * For SAN name elements, the first byte (`oid[0]`) has value 0, - * followed by another byte that matches the expected GeneralName - * tag. Allowed second byte values are then: - * - * - 1: `rfc822Name` - * - * - 2: `dNSName` - * - * - 6: `uniformResourceIdentifier` - * - * - 0: `otherName` - * - * If first and second byte are 0, then this is a SAN element of - * type `otherName`; the `oid[]` array should then contain, right - * after the two bytes of value 0, an encoded OID (with the same - * conventions as for X.500 name elements). If a match is found - * for that OID, then the corresponding name element will be - * extracted, as long as it is a supported string type. - */ - const unsigned char *oid; - - /** - * \brief Destination buffer. - */ - char *buf; - - /** - * \brief Length (in bytes) of the destination buffer. - * - * The buffer MUST NOT be smaller than 1 byte. - */ - size_t len; - - /** - * \brief Decoding status. - * - * Status is 0 if the name element was not found, 1 if it was - * found and decoded, or -1 on error. Error conditions include - * an unrecognised encoding, an invalid encoding, or a string - * too large for the destination buffer. - */ - int status; - -} br_name_element; - -/** - * \brief The "minimal" X.509 engine structure. - * - * The structure contents are opaque (they shall not be accessed directly), - * except for the first field (the vtable). - * - * The "minimal" engine performs a rudimentary but serviceable X.509 path - * validation. - */ -typedef struct { - const br_x509_class *vtable; - -#ifndef BR_DOXYGEN_IGNORE - /* Structure for returning the EE public key. */ - br_x509_pkey pkey; - - /* CPU for the T0 virtual machine. */ - struct { - uint32_t *dp; - uint32_t *rp; - const unsigned char *ip; - } cpu; - uint32_t dp_stack[32]; - uint32_t rp_stack[32]; - int err; - - /* Server name to match with the SAN / CN of the EE certificate. */ - const char *server_name; - - /* Validated key usages. */ - unsigned char key_usages; - - /* Explicitly set date and time. */ - uint32_t days, seconds; - - /* Current certificate length (in bytes). Set to 0 when the - certificate has been fully processed. */ - uint32_t cert_length; - - /* Number of certificates processed so far in the current chain. - It is incremented at the end of the processing of a certificate, - so it is 0 for the EE. */ - uint32_t num_certs; - - /* Certificate data chunk. */ - const unsigned char *hbuf; - size_t hlen; - - /* The pad serves as destination for various operations. */ - unsigned char pad[256]; - - /* Buffer for EE public key data. */ - unsigned char ee_pkey_data[BR_X509_BUFSIZE_KEY]; - - /* Buffer for currently decoded public key. */ - unsigned char pkey_data[BR_X509_BUFSIZE_KEY]; - - /* Signature type: signer key type, offset to the hash - function OID (in the T0 data block) and hash function - output length (TBS hash length). */ - unsigned char cert_signer_key_type; - uint16_t cert_sig_hash_oid; - unsigned char cert_sig_hash_len; - - /* Current/last certificate signature. */ - unsigned char cert_sig[BR_X509_BUFSIZE_SIG]; - uint16_t cert_sig_len; - - /* Minimum RSA key length (difference in bytes from 128). */ - int16_t min_rsa_size; - - /* Configured trust anchors. */ - const br_x509_trust_anchor *trust_anchors; - size_t trust_anchors_num; - - /* - * Multi-hasher for the TBS. - */ - unsigned char do_mhash; - br_multihash_context mhash; - unsigned char tbs_hash[64]; - - /* - * Simple hasher for the subject/issuer DN. - */ - unsigned char do_dn_hash; - const br_hash_class *dn_hash_impl; - br_hash_compat_context dn_hash; - unsigned char current_dn_hash[64]; - unsigned char next_dn_hash[64]; - unsigned char saved_dn_hash[64]; - - /* - * Name elements to gather. - */ - br_name_element *name_elts; - size_t num_name_elts; - - /* - * Public key cryptography implementations (signature verification). - */ - br_rsa_pkcs1_vrfy irsa; - br_ecdsa_vrfy iecdsa; - const br_ec_impl *iec; -#endif - -} br_x509_minimal_context; - -/** - * \brief Class instance for the "minimal" X.509 engine. - */ -extern const br_x509_class br_x509_minimal_vtable; - -/** - * \brief Initialise a "minimal" X.509 engine. - * - * The `dn_hash_impl` parameter shall be a hash function internally used - * to match X.500 names (subject/issuer DN, and anchor names). Any standard - * hash function may be used, but a collision-resistant hash function is - * advised. - * - * After initialization, some implementations for signature verification - * (hash functions and signature algorithms) MUST be added. - * - * \param ctx context to initialise. - * \param dn_hash_impl hash function for DN comparisons. - * \param trust_anchors trust anchors. - * \param trust_anchors_num number of trust anchors. - */ -void br_x509_minimal_init(br_x509_minimal_context *ctx, - const br_hash_class *dn_hash_impl, - const br_x509_trust_anchor *trust_anchors, size_t trust_anchors_num); - -/** - * \brief Set a supported hash function in an X.509 "minimal" engine. - * - * Hash functions are used with signature verification algorithms. - * Once initialised (with `br_x509_minimal_init()`), the context must - * be configured with the hash functions it shall support for that - * purpose. The hash function identifier MUST be one of the standard - * hash function identifiers (1 to 6, for MD5, SHA-1, SHA-224, SHA-256, - * SHA-384 and SHA-512). - * - * If `impl` is `NULL`, this _removes_ support for the designated - * hash function. - * - * \param ctx validation context. - * \param id hash function identifier (from 1 to 6). - * \param impl hash function implementation (or `NULL`). - */ -static inline void -br_x509_minimal_set_hash(br_x509_minimal_context *ctx, - int id, const br_hash_class *impl) -{ - br_multihash_setimpl(&ctx->mhash, id, impl); -} - -/** - * \brief Set a RSA signature verification implementation in the X.509 - * "minimal" engine. - * - * Once initialised (with `br_x509_minimal_init()`), the context must - * be configured with the signature verification implementations that - * it is supposed to support. If `irsa` is `0`, then the RSA support - * is disabled. - * - * \param ctx validation context. - * \param irsa RSA signature verification implementation (or `0`). - */ -static inline void -br_x509_minimal_set_rsa(br_x509_minimal_context *ctx, - br_rsa_pkcs1_vrfy irsa) -{ - ctx->irsa = irsa; -} - -/** - * \brief Set a ECDSA signature verification implementation in the X.509 - * "minimal" engine. - * - * Once initialised (with `br_x509_minimal_init()`), the context must - * be configured with the signature verification implementations that - * it is supposed to support. - * - * If `iecdsa` is `0`, then this call disables ECDSA support; in that - * case, `iec` may be `NULL`. Otherwise, `iecdsa` MUST point to a function - * that verifies ECDSA signatures with format "asn1", and it will use - * `iec` as underlying elliptic curve support. - * - * \param ctx validation context. - * \param iec elliptic curve implementation (or `NULL`). - * \param iecdsa ECDSA implementation (or `0`). - */ -static inline void -br_x509_minimal_set_ecdsa(br_x509_minimal_context *ctx, - const br_ec_impl *iec, br_ecdsa_vrfy iecdsa) -{ - ctx->iecdsa = iecdsa; - ctx->iec = iec; -} - -/** - * \brief Initialise a "minimal" X.509 engine with default algorithms. - * - * This function performs the same job as `br_x509_minimal_init()`, but - * also sets implementations for RSA, ECDSA, and the standard hash - * functions. - * - * \param ctx context to initialise. - * \param trust_anchors trust anchors. - * \param trust_anchors_num number of trust anchors. - */ -void br_x509_minimal_init_full(br_x509_minimal_context *ctx, - const br_x509_trust_anchor *trust_anchors, size_t trust_anchors_num); - -/** - * \brief Set the validation time for the X.509 "minimal" engine. - * - * The validation time is set as two 32-bit integers, for days and - * seconds since a fixed epoch: - * - * - Days are counted in a proleptic Gregorian calendar since - * January 1st, 0 AD. Year "0 AD" is the one that preceded "1 AD"; - * it is also traditionally known as "1 BC". - * - * - Seconds are counted since midnight, from 0 to 86400 (a count of - * 86400 is possible only if a leap second happened). - * - * The validation date and time is understood in the UTC time zone. - * - * If the validation date and time are not explicitly set, but BearSSL - * was compiled with support for the system clock on the underlying - * platform, then the current time will automatically be used. Otherwise, - * not setting the validation date and time implies a validation - * failure (except in case of direct trust of the EE key). - * - * \param ctx validation context. - * \param days days since January 1st, 0 AD (Gregorian calendar). - * \param seconds seconds since midnight (0 to 86400). - */ -static inline void -br_x509_minimal_set_time(br_x509_minimal_context *ctx, - uint32_t days, uint32_t seconds) -{ - ctx->days = days; - ctx->seconds = seconds; -} - -/** - * \brief Set the minimal acceptable length for RSA keys (X.509 "minimal" - * engine). - * - * The RSA key length is expressed in bytes. The default minimum key - * length is 128 bytes, corresponding to 1017 bits. RSA keys shorter - * than the configured length will be rejected, implying validation - * failure. This setting applies to keys extracted from certificates - * (both end-entity, and intermediate CA) but not to "CA" trust anchors. - * - * \param ctx validation context. - * \param byte_length minimum RSA key length, **in bytes** (not bits). - */ -static inline void -br_x509_minimal_set_minrsa(br_x509_minimal_context *ctx, int byte_length) -{ - ctx->min_rsa_size = (int16_t)(byte_length - 128); -} - -/** - * \brief Set the name elements to gather. - * - * The provided array is linked in the context. The elements are - * gathered from the EE certificate. If the same element type is - * requested several times, then the relevant structures will be filled - * in the order the matching values are encountered in the certificate. - * - * \param ctx validation context. - * \param elts array of name element structures to fill. - * \param num_elts number of name element structures to fill. - */ -static inline void -br_x509_minimal_set_name_elements(br_x509_minimal_context *ctx, - br_name_element *elts, size_t num_elts) -{ - ctx->name_elts = elts; - ctx->num_name_elts = num_elts; -} - -/** - * \brief X.509 decoder context. - * - * This structure is _not_ for X.509 validation, but for extracting - * names and public keys from encoded certificates. Intended usage is - * to use (self-signed) certificates as trust anchors. - * - * Contents are opaque and shall not be accessed directly. - */ -typedef struct { - -#ifndef BR_DOXYGEN_IGNORE - /* Structure for returning the public key. */ - br_x509_pkey pkey; - - /* CPU for the T0 virtual machine. */ - struct { - uint32_t *dp; - uint32_t *rp; - const unsigned char *ip; - } cpu; - uint32_t dp_stack[32]; - uint32_t rp_stack[32]; - int err; - - /* The pad serves as destination for various operations. */ - unsigned char pad[256]; - - /* Flag set when decoding succeeds. */ - unsigned char decoded; - - /* Validity dates. */ - uint32_t notbefore_days, notbefore_seconds; - uint32_t notafter_days, notafter_seconds; - - /* The "CA" flag. This is set to true if the certificate contains - a Basic Constraints extension that asserts CA status. */ - unsigned char isCA; - - /* DN processing: the subject DN is extracted and pushed to the - provided callback. */ - unsigned char copy_dn; - void *append_dn_ctx; - void (*append_dn)(void *ctx, const void *buf, size_t len); - - /* Certificate data chunk. */ - const unsigned char *hbuf; - size_t hlen; - - /* Buffer for decoded public key. */ - unsigned char pkey_data[BR_X509_BUFSIZE_KEY]; - - /* Type of key and hash function used in the certificate signature. */ - unsigned char signer_key_type; - unsigned char signer_hash_id; -#endif - -} br_x509_decoder_context; - -/** - * \brief Initialise an X.509 decoder context for processing a new - * certificate. - * - * The `append_dn()` callback (with opaque context `append_dn_ctx`) - * will be invoked to receive, chunk by chunk, the certificate's - * subject DN. If `append_dn` is `0` then the subject DN will be - * ignored. - * - * \param ctx X.509 decoder context to initialise. - * \param append_dn DN receiver callback (or `0`). - * \param append_dn_ctx context for the DN receiver callback. - */ -void br_x509_decoder_init(br_x509_decoder_context *ctx, - void (*append_dn)(void *ctx, const void *buf, size_t len), - void *append_dn_ctx); - -/** - * \brief Push some certificate bytes into a decoder context. - * - * If `len` is non-zero, then that many bytes are pushed, from address - * `data`, into the provided decoder context. - * - * \param ctx X.509 decoder context. - * \param data certificate data chunk. - * \param len certificate data chunk length (in bytes). - */ -void br_x509_decoder_push(br_x509_decoder_context *ctx, - const void *data, size_t len); - -/** - * \brief Obtain the decoded public key. - * - * Returned value is a pointer to a structure internal to the decoder - * context; releasing or reusing the decoder context invalidates that - * structure. - * - * If decoding was not finished, or failed, then `NULL` is returned. - * - * \param ctx X.509 decoder context. - * \return the public key, or `NULL` on unfinished/error. - */ -static inline br_x509_pkey * -br_x509_decoder_get_pkey(br_x509_decoder_context *ctx) -{ - if (ctx->decoded && ctx->err == 0) { - return &ctx->pkey; - } else { - return NULL; - } -} - -/** - * \brief Get decoder error status. - * - * If no error was reported yet but the certificate decoding is not - * finished, then the error code is `BR_ERR_X509_TRUNCATED`. If decoding - * was successful, then 0 is returned. - * - * \param ctx X.509 decoder context. - * \return 0 on successful decoding, or a non-zero error code. - */ -static inline int -br_x509_decoder_last_error(br_x509_decoder_context *ctx) -{ - if (ctx->err != 0) { - return ctx->err; - } - if (!ctx->decoded) { - return BR_ERR_X509_TRUNCATED; - } - return 0; -} - -/** - * \brief Get the "isCA" flag from an X.509 decoder context. - * - * This flag is set if the decoded certificate claims to be a CA through - * a Basic Constraints extension. This flag should not be read before - * decoding completed successfully. - * - * \param ctx X.509 decoder context. - * \return the "isCA" flag. - */ -static inline int -br_x509_decoder_isCA(br_x509_decoder_context *ctx) -{ - return ctx->isCA; -} - -/** - * \brief Get the issuing CA key type (type of algorithm used to sign the - * decoded certificate). - * - * This is `BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC`. The value 0 is returned - * if the signature type was not recognised. - * - * \param ctx X.509 decoder context. - * \return the issuing CA key type. - */ -static inline int -br_x509_decoder_get_signer_key_type(br_x509_decoder_context *ctx) -{ - return ctx->signer_key_type; -} - -/** - * \brief Get the identifier for the hash function used to sign the decoded - * certificate. - * - * This is 0 if the hash function was not recognised. - * - * \param ctx X.509 decoder context. - * \return the signature hash function identifier. - */ -static inline int -br_x509_decoder_get_signer_hash_id(br_x509_decoder_context *ctx) -{ - return ctx->signer_hash_id; -} - -/** - * \brief Type for an X.509 certificate (DER-encoded). - */ -typedef struct { - /** \brief The DER-encoded certificate data. */ - unsigned char *data; - /** \brief The DER-encoded certificate length (in bytes). */ - size_t data_len; -} br_x509_certificate; - -/** - * \brief Private key decoder context. - * - * The private key decoder recognises RSA and EC private keys, either in - * their raw, DER-encoded format, or wrapped in an unencrypted PKCS#8 - * archive (again DER-encoded). - * - * Structure contents are opaque and shall not be accessed directly. - */ -typedef struct { -#ifndef BR_DOXYGEN_IGNORE - /* Structure for returning the private key. */ - union { - br_rsa_private_key rsa; - br_ec_private_key ec; - } key; - - /* CPU for the T0 virtual machine. */ - struct { - uint32_t *dp; - uint32_t *rp; - const unsigned char *ip; - } cpu; - uint32_t dp_stack[32]; - uint32_t rp_stack[32]; - int err; - - /* Private key data chunk. */ - const unsigned char *hbuf; - size_t hlen; - - /* The pad serves as destination for various operations. */ - unsigned char pad[256]; - - /* Decoded key type; 0 until decoding is complete. */ - unsigned char key_type; - - /* Buffer for the private key elements. It shall be large enough - to accommodate all elements for a RSA-4096 private key (roughly - five 2048-bit integers, possibly a bit more). */ - unsigned char key_data[3 * BR_X509_BUFSIZE_SIG]; -#endif -} br_skey_decoder_context; - -/** - * \brief Initialise a private key decoder context. - * - * \param ctx key decoder context to initialise. - */ -void br_skey_decoder_init(br_skey_decoder_context *ctx); - -/** - * \brief Push some data bytes into a private key decoder context. - * - * If `len` is non-zero, then that many data bytes, starting at address - * `data`, are pushed into the decoder. - * - * \param ctx key decoder context. - * \param data private key data chunk. - * \param len private key data chunk length (in bytes). - */ -void br_skey_decoder_push(br_skey_decoder_context *ctx, - const void *data, size_t len); - -/** - * \brief Get the decoding status for a private key. - * - * Decoding status is 0 on success, or a non-zero error code. If the - * decoding is unfinished when this function is called, then the - * status code `BR_ERR_X509_TRUNCATED` is returned. - * - * \param ctx key decoder context. - * \return 0 on successful decoding, or a non-zero error code. - */ -static inline int -br_skey_decoder_last_error(const br_skey_decoder_context *ctx) -{ - if (ctx->err != 0) { - return ctx->err; - } - if (ctx->key_type == 0) { - return BR_ERR_X509_TRUNCATED; - } - return 0; -} - -/** - * \brief Get the decoded private key type. - * - * Private key type is `BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC`. If decoding is - * not finished or failed, then 0 is returned. - * - * \param ctx key decoder context. - * \return decoded private key type, or 0. - */ -static inline int -br_skey_decoder_key_type(const br_skey_decoder_context *ctx) -{ - if (ctx->err == 0) { - return ctx->key_type; - } else { - return 0; - } -} - -/** - * \brief Get the decoded RSA private key. - * - * This function returns `NULL` if the decoding failed, or is not - * finished, or the key is not RSA. The returned pointer references - * structures within the context that can become invalid if the context - * is reused or released. - * - * \param ctx key decoder context. - * \return decoded RSA private key, or `NULL`. - */ -static inline const br_rsa_private_key * -br_skey_decoder_get_rsa(const br_skey_decoder_context *ctx) -{ - if (ctx->err == 0 && ctx->key_type == BR_KEYTYPE_RSA) { - return &ctx->key.rsa; - } else { - return NULL; - } -} - -/** - * \brief Get the decoded EC private key. - * - * This function returns `NULL` if the decoding failed, or is not - * finished, or the key is not EC. The returned pointer references - * structures within the context that can become invalid if the context - * is reused or released. - * - * \param ctx key decoder context. - * \return decoded EC private key, or `NULL`. - */ -static inline const br_ec_private_key * -br_skey_decoder_get_ec(const br_skey_decoder_context *ctx) -{ - if (ctx->err == 0 && ctx->key_type == BR_KEYTYPE_EC) { - return &ctx->key.ec; - } else { - return NULL; - } -} - -/** - * \brief Encode an RSA private key (raw DER format). - * - * This function encodes the provided key into the "raw" format specified - * in PKCS#1 (RFC 8017, Appendix C, type `RSAPrivateKey`), with DER - * encoding rules. - * - * The key elements are: - * - * - `sk`: the private key (`p`, `q`, `dp`, `dq` and `iq`) - * - * - `pk`: the public key (`n` and `e`) - * - * - `d` (size: `dlen` bytes): the private exponent - * - * The public key elements, and the private exponent `d`, can be - * recomputed from the private key (see `br_rsa_compute_modulus()`, - * `br_rsa_compute_pubexp()` and `br_rsa_compute_privexp()`). - * - * If `dest` is not `NULL`, then the encoded key is written at that - * address, and the encoded length (in bytes) is returned. If `dest` is - * `NULL`, then nothing is written, but the encoded length is still - * computed and returned. - * - * \param dest the destination buffer (or `NULL`). - * \param sk the RSA private key. - * \param pk the RSA public key. - * \param d the RSA private exponent. - * \param dlen the RSA private exponent length (in bytes). - * \return the encoded key length (in bytes). - */ -size_t br_encode_rsa_raw_der(void *dest, const br_rsa_private_key *sk, - const br_rsa_public_key *pk, const void *d, size_t dlen); - -/** - * \brief Encode an RSA private key (PKCS#8 DER format). - * - * This function encodes the provided key into the PKCS#8 format - * (RFC 5958, type `OneAsymmetricKey`). It wraps around the "raw DER" - * format for the RSA key, as implemented by `br_encode_rsa_raw_der()`. - * - * The key elements are: - * - * - `sk`: the private key (`p`, `q`, `dp`, `dq` and `iq`) - * - * - `pk`: the public key (`n` and `e`) - * - * - `d` (size: `dlen` bytes): the private exponent - * - * The public key elements, and the private exponent `d`, can be - * recomputed from the private key (see `br_rsa_compute_modulus()`, - * `br_rsa_compute_pubexp()` and `br_rsa_compute_privexp()`). - * - * If `dest` is not `NULL`, then the encoded key is written at that - * address, and the encoded length (in bytes) is returned. If `dest` is - * `NULL`, then nothing is written, but the encoded length is still - * computed and returned. - * - * \param dest the destination buffer (or `NULL`). - * \param sk the RSA private key. - * \param pk the RSA public key. - * \param d the RSA private exponent. - * \param dlen the RSA private exponent length (in bytes). - * \return the encoded key length (in bytes). - */ -size_t br_encode_rsa_pkcs8_der(void *dest, const br_rsa_private_key *sk, - const br_rsa_public_key *pk, const void *d, size_t dlen); - -/** - * \brief Encode an EC private key (raw DER format). - * - * This function encodes the provided key into the "raw" format specified - * in RFC 5915 (type `ECPrivateKey`), with DER encoding rules. - * - * The private key is provided in `sk`, the public key being `pk`. If - * `pk` is `NULL`, then the encoded key will not include the public key - * in its `publicKey` field (which is nominally optional). - * - * If `dest` is not `NULL`, then the encoded key is written at that - * address, and the encoded length (in bytes) is returned. If `dest` is - * `NULL`, then nothing is written, but the encoded length is still - * computed and returned. - * - * If the key cannot be encoded (e.g. because there is no known OBJECT - * IDENTIFIER for the used curve), then 0 is returned. - * - * \param dest the destination buffer (or `NULL`). - * \param sk the EC private key. - * \param pk the EC public key (or `NULL`). - * \return the encoded key length (in bytes), or 0. - */ -size_t br_encode_ec_raw_der(void *dest, - const br_ec_private_key *sk, const br_ec_public_key *pk); - -/** - * \brief Encode an EC private key (PKCS#8 DER format). - * - * This function encodes the provided key into the PKCS#8 format - * (RFC 5958, type `OneAsymmetricKey`). The curve is identified - * by an OID provided as parameters to the `privateKeyAlgorithm` - * field. The private key value (contents of the `privateKey` field) - * contains the DER encoding of the `ECPrivateKey` type defined in - * RFC 5915, without the `parameters` field (since they would be - * redundant with the information in `privateKeyAlgorithm`). - * - * The private key is provided in `sk`, the public key being `pk`. If - * `pk` is not `NULL`, then the encoded public key is included in the - * `publicKey` field of the private key value (but not in the `publicKey` - * field of the PKCS#8 `OneAsymmetricKey` wrapper). - * - * If `dest` is not `NULL`, then the encoded key is written at that - * address, and the encoded length (in bytes) is returned. If `dest` is - * `NULL`, then nothing is written, but the encoded length is still - * computed and returned. - * - * If the key cannot be encoded (e.g. because there is no known OBJECT - * IDENTIFIER for the used curve), then 0 is returned. - * - * \param dest the destination buffer (or `NULL`). - * \param sk the EC private key. - * \param pk the EC public key (or `NULL`). - * \return the encoded key length (in bytes), or 0. - */ -size_t br_encode_ec_pkcs8_der(void *dest, - const br_ec_private_key *sk, const br_ec_public_key *pk); - -/** - * \brief PEM banner for RSA private key (raw). - */ -#define BR_ENCODE_PEM_RSA_RAW "RSA PRIVATE KEY" - -/** - * \brief PEM banner for EC private key (raw). - */ -#define BR_ENCODE_PEM_EC_RAW "EC PRIVATE KEY" - -/** - * \brief PEM banner for an RSA or EC private key in PKCS#8 format. - */ -#define BR_ENCODE_PEM_PKCS8 "PRIVATE KEY" - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/tls/bearssl/ccm.c b/src/tls/bearssl/ccm.c deleted file mode 100644 index 7e5c863f0..000000000 --- a/src/tls/bearssl/ccm.c +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * Implementation Notes - * ==================== - * - * The combined CTR + CBC-MAC functions can only handle full blocks, - * so some buffering is necessary. - * - * - 'ptr' contains a value from 0 to 15, which is the number of bytes - * accumulated in buf[] that still needs to be processed with the - * current CBC-MAC computation. - * - * - When processing the message itself, CTR encryption/decryption is - * also done at the same time. The first 'ptr' bytes of buf[] then - * contains the plaintext bytes, while the last '16 - ptr' bytes of - * buf[] are the remnants of the stream block, to be used against - * the next input bytes, when available. When 'ptr' is 0, the - * contents of buf[] are to be ignored. - * - * - The current counter and running CBC-MAC values are kept in 'ctr' - * and 'cbcmac', respectively. - */ - -/* see bearssl_block.h */ -void -br_ccm_init(br_ccm_context *ctx, const br_block_ctrcbc_class **bctx) -{ - ctx->bctx = bctx; -} - -/* see bearssl_block.h */ -int -br_ccm_reset(br_ccm_context *ctx, const void *nonce, size_t nonce_len, - uint64_t aad_len, uint64_t data_len, size_t tag_len) -{ - unsigned char tmp[16]; - unsigned u, q; - - if (nonce_len < 7 || nonce_len > 13) { - return 0; - } - if (tag_len < 4 || tag_len > 16 || (tag_len & 1) != 0) { - return 0; - } - q = 15 - (unsigned)nonce_len; - ctx->tag_len = tag_len; - - /* - * Block B0, to start CBC-MAC. - */ - tmp[0] = (aad_len > 0 ? 0x40 : 0x00) - | (((unsigned)tag_len - 2) << 2) - | (q - 1); - memcpy(tmp + 1, nonce, nonce_len); - for (u = 0; u < q; u ++) { - tmp[15 - u] = (unsigned char)data_len; - data_len >>= 8; - } - if (data_len != 0) { - /* - * If the data length was not entirely consumed in the - * loop above, then it exceeds the maximum limit of - * q bytes (when encoded). - */ - return 0; - } - - /* - * Start CBC-MAC. - */ - memset(ctx->cbcmac, 0, sizeof ctx->cbcmac); - (*ctx->bctx)->mac(ctx->bctx, ctx->cbcmac, tmp, sizeof tmp); - - /* - * Assemble AAD length header. - */ - if ((aad_len >> 32) != 0) { - ctx->buf[0] = 0xFF; - ctx->buf[1] = 0xFF; - br_enc64be(ctx->buf + 2, aad_len); - ctx->ptr = 10; - } else if (aad_len >= 0xFF00) { - ctx->buf[0] = 0xFF; - ctx->buf[1] = 0xFE; - br_enc32be(ctx->buf + 2, (uint32_t)aad_len); - ctx->ptr = 6; - } else if (aad_len > 0) { - br_enc16be(ctx->buf, (unsigned)aad_len); - ctx->ptr = 2; - } else { - ctx->ptr = 0; - } - - /* - * Make initial counter value and compute tag mask. - */ - ctx->ctr[0] = q - 1; - memcpy(ctx->ctr + 1, nonce, nonce_len); - memset(ctx->ctr + 1 + nonce_len, 0, q); - memset(ctx->tagmask, 0, sizeof ctx->tagmask); - (*ctx->bctx)->ctr(ctx->bctx, ctx->ctr, - ctx->tagmask, sizeof ctx->tagmask); - - return 1; -} - -/* see bearssl_block.h */ -void -br_ccm_aad_inject(br_ccm_context *ctx, const void *data, size_t len) -{ - const unsigned char *dbuf; - size_t ptr; - - dbuf = data; - - /* - * Complete partial block, if needed. - */ - ptr = ctx->ptr; - if (ptr != 0) { - size_t clen; - - clen = (sizeof ctx->buf) - ptr; - if (clen > len) { - memcpy(ctx->buf + ptr, dbuf, len); - ctx->ptr = ptr + len; - return; - } - memcpy(ctx->buf + ptr, dbuf, clen); - dbuf += clen; - len -= clen; - (*ctx->bctx)->mac(ctx->bctx, ctx->cbcmac, - ctx->buf, sizeof ctx->buf); - } - - /* - * Process complete blocks. - */ - ptr = len & 15; - len -= ptr; - (*ctx->bctx)->mac(ctx->bctx, ctx->cbcmac, dbuf, len); - dbuf += len; - - /* - * Copy last partial block in the context buffer. - */ - memcpy(ctx->buf, dbuf, ptr); - ctx->ptr = ptr; -} - -/* see bearssl_block.h */ -void -br_ccm_flip(br_ccm_context *ctx) -{ - size_t ptr; - - /* - * Complete AAD partial block with zeros, if necessary. - */ - ptr = ctx->ptr; - if (ptr != 0) { - memset(ctx->buf + ptr, 0, (sizeof ctx->buf) - ptr); - (*ctx->bctx)->mac(ctx->bctx, ctx->cbcmac, - ctx->buf, sizeof ctx->buf); - ctx->ptr = 0; - } - - /* - * Counter was already set by br_ccm_reset(). - */ -} - -/* see bearssl_block.h */ -void -br_ccm_run(br_ccm_context *ctx, int encrypt, void *data, size_t len) -{ - unsigned char *dbuf; - size_t ptr; - - dbuf = data; - - /* - * Complete a partial block, if any: ctx->buf[] contains - * ctx->ptr plaintext bytes (already reported), and the other - * bytes are CTR stream output. - */ - ptr = ctx->ptr; - if (ptr != 0) { - size_t clen; - size_t u; - - clen = (sizeof ctx->buf) - ptr; - if (clen > len) { - clen = len; - } - if (encrypt) { - for (u = 0; u < clen; u ++) { - unsigned w, x; - - w = ctx->buf[ptr + u]; - x = dbuf[u]; - ctx->buf[ptr + u] = x; - dbuf[u] = w ^ x; - } - } else { - for (u = 0; u < clen; u ++) { - unsigned w; - - w = ctx->buf[ptr + u] ^ dbuf[u]; - dbuf[u] = w; - ctx->buf[ptr + u] = w; - } - } - dbuf += clen; - len -= clen; - ptr += clen; - if (ptr < sizeof ctx->buf) { - ctx->ptr = ptr; - return; - } - (*ctx->bctx)->mac(ctx->bctx, - ctx->cbcmac, ctx->buf, sizeof ctx->buf); - } - - /* - * Process all complete blocks. Note that the ctrcbc API is for - * encrypt-then-MAC (CBC-MAC is computed over the encrypted - * blocks) while CCM uses MAC-and-encrypt (CBC-MAC is computed - * over the plaintext blocks). Therefore, we need to use the - * _decryption_ function for encryption, and the encryption - * function for decryption (this works because CTR encryption - * and decryption are identical, so the choice really is about - * computing the CBC-MAC before or after XORing with the CTR - * stream). - */ - ptr = len & 15; - len -= ptr; - if (encrypt) { - (*ctx->bctx)->decrypt(ctx->bctx, ctx->ctr, ctx->cbcmac, - dbuf, len); - } else { - (*ctx->bctx)->encrypt(ctx->bctx, ctx->ctr, ctx->cbcmac, - dbuf, len); - } - dbuf += len; - - /* - * If there is some remaining data, then we need to compute an - * extra block of CTR stream. - */ - if (ptr != 0) { - size_t u; - - memset(ctx->buf, 0, sizeof ctx->buf); - (*ctx->bctx)->ctr(ctx->bctx, ctx->ctr, - ctx->buf, sizeof ctx->buf); - if (encrypt) { - for (u = 0; u < ptr; u ++) { - unsigned w, x; - - w = ctx->buf[u]; - x = dbuf[u]; - ctx->buf[u] = x; - dbuf[u] = w ^ x; - } - } else { - for (u = 0; u < ptr; u ++) { - unsigned w; - - w = ctx->buf[u] ^ dbuf[u]; - dbuf[u] = w; - ctx->buf[u] = w; - } - } - } - ctx->ptr = ptr; -} - -/* see bearssl_block.h */ -size_t -br_ccm_get_tag(br_ccm_context *ctx, void *tag) -{ - size_t ptr; - size_t u; - - /* - * If there is some buffered data, then we need to pad it with - * zeros and finish up CBC-MAC. - */ - ptr = ctx->ptr; - if (ptr != 0) { - memset(ctx->buf + ptr, 0, (sizeof ctx->buf) - ptr); - (*ctx->bctx)->mac(ctx->bctx, ctx->cbcmac, - ctx->buf, sizeof ctx->buf); - } - - /* - * XOR the tag mask into the CBC-MAC output. - */ - for (u = 0; u < ctx->tag_len; u ++) { - ctx->cbcmac[u] ^= ctx->tagmask[u]; - } - memcpy(tag, ctx->cbcmac, ctx->tag_len); - return ctx->tag_len; -} - -/* see bearssl_block.h */ -uint32_t -br_ccm_check_tag(br_ccm_context *ctx, const void *tag) -{ - unsigned char tmp[16]; - size_t u, tag_len; - uint32_t z; - - tag_len = br_ccm_get_tag(ctx, tmp); - z = 0; - for (u = 0; u < tag_len; u ++) { - z |= tmp[u] ^ ((const unsigned char *)tag)[u]; - } - return EQ0(z); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ccopy.c b/src/tls/bearssl/ccopy.c deleted file mode 100644 index 1c8d6e000..000000000 --- a/src/tls/bearssl/ccopy.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_ccopy(uint32_t ctl, void *dst, const void *src, size_t len) -{ - unsigned char *d; - const unsigned char *s; - - d = dst; - s = src; - while (len -- > 0) { - uint32_t x, y; - - x = *s ++; - y = *d; - *d = MUX(ctl, x, y); - d ++; - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/chacha20_ct.c b/src/tls/bearssl/chacha20_ct.c deleted file mode 100644 index 503015a13..000000000 --- a/src/tls/bearssl/chacha20_ct.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_block.h */ -uint32_t -br_chacha20_ct_run(const void *key, - const void *iv, uint32_t cc, void *data, size_t len) -{ - unsigned char *buf; - uint32_t kw[8], ivw[3]; - size_t u; - - static const uint32_t CW[] = { - 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574 - }; - - buf = data; - for (u = 0; u < 8; u ++) { - kw[u] = br_dec32le((const unsigned char *)key + (u << 2)); - } - for (u = 0; u < 3; u ++) { - ivw[u] = br_dec32le((const unsigned char *)iv + (u << 2)); - } - while (len > 0) { - uint32_t state[16]; - int i; - size_t clen; - unsigned char tmp[64]; - - memcpy(&state[0], CW, sizeof CW); - memcpy(&state[4], kw, sizeof kw); - state[12] = cc; - memcpy(&state[13], ivw, sizeof ivw); - for (i = 0; i < 10; i ++) { - -#define QROUND(a, b, c, d) do { \ - state[a] += state[b]; \ - state[d] ^= state[a]; \ - state[d] = (state[d] << 16) | (state[d] >> 16); \ - state[c] += state[d]; \ - state[b] ^= state[c]; \ - state[b] = (state[b] << 12) | (state[b] >> 20); \ - state[a] += state[b]; \ - state[d] ^= state[a]; \ - state[d] = (state[d] << 8) | (state[d] >> 24); \ - state[c] += state[d]; \ - state[b] ^= state[c]; \ - state[b] = (state[b] << 7) | (state[b] >> 25); \ - } while (0) - - QROUND( 0, 4, 8, 12); - QROUND( 1, 5, 9, 13); - QROUND( 2, 6, 10, 14); - QROUND( 3, 7, 11, 15); - QROUND( 0, 5, 10, 15); - QROUND( 1, 6, 11, 12); - QROUND( 2, 7, 8, 13); - QROUND( 3, 4, 9, 14); - -#undef QROUND - - } - for (u = 0; u < 4; u ++) { - br_enc32le(&tmp[u << 2], state[u] + CW[u]); - } - for (u = 4; u < 12; u ++) { - br_enc32le(&tmp[u << 2], state[u] + kw[u - 4]); - } - br_enc32le(&tmp[48], state[12] + cc); - for (u = 13; u < 16; u ++) { - br_enc32le(&tmp[u << 2], state[u] + ivw[u - 13]); - } - - clen = len < 64 ? len : 64; - for (u = 0; u < clen; u ++) { - buf[u] ^= tmp[u]; - } - buf += clen; - len -= clen; - cc ++; - } - return cc; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/chacha20_sse2.c b/src/tls/bearssl/chacha20_sse2.c deleted file mode 100644 index 6e717d028..000000000 --- a/src/tls/bearssl/chacha20_sse2.c +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#define BR_ENABLE_INTRINSICS 1 -#include "inner.h" - -#if BR_SSE2 - -/* - * This file contains a ChaCha20 implementation that leverages SSE2 - * opcodes for better performance. - */ - -/* see bearssl_block.h */ -br_chacha20_run -br_chacha20_sse2_get(void) -{ - /* - * If using 64-bit mode, then SSE2 opcodes should be automatically - * available, since they are part of the ABI. - * - * In 32-bit mode, we use CPUID to detect the SSE2 feature. - */ - -#if BR_amd64 - return &br_chacha20_sse2_run; -#else - - /* - * SSE2 support is indicated by bit 26 in EDX. - */ - if (br_cpuid(0, 0, 0, 0x04000000)) { - return &br_chacha20_sse2_run; - } else { - return 0; - } -#endif -} - -BR_TARGETS_X86_UP - -/* see bearssl_block.h */ -BR_TARGET("sse2") -uint32_t -br_chacha20_sse2_run(const void *key, - const void *iv, uint32_t cc, void *data, size_t len) -{ - unsigned char *buf; - uint32_t ivtmp[4]; - __m128i kw0, kw1; - __m128i iw, cw; - __m128i one; - - static const uint32_t CW[] = { - 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574 - }; - - buf = data; - kw0 = _mm_loadu_si128(key); - kw1 = _mm_loadu_si128((const void *)((const unsigned char *)key + 16)); - ivtmp[0] = cc; - memcpy(ivtmp + 1, iv, 12); - iw = _mm_loadu_si128((const void *)ivtmp); - cw = _mm_loadu_si128((const void *)CW); - one = _mm_set_epi32(0, 0, 0, 1); - - while (len > 0) { - /* - * sj contains state words 4*j to 4*j+3. - */ - __m128i s0, s1, s2, s3; - int i; - - s0 = cw; - s1 = kw0; - s2 = kw1; - s3 = iw; - for (i = 0; i < 10; i ++) { - /* - * Even round is straightforward application on - * the state words. - */ - s0 = _mm_add_epi32(s0, s1); - s3 = _mm_xor_si128(s3, s0); - s3 = _mm_or_si128( - _mm_slli_epi32(s3, 16), - _mm_srli_epi32(s3, 16)); - - s2 = _mm_add_epi32(s2, s3); - s1 = _mm_xor_si128(s1, s2); - s1 = _mm_or_si128( - _mm_slli_epi32(s1, 12), - _mm_srli_epi32(s1, 20)); - - s0 = _mm_add_epi32(s0, s1); - s3 = _mm_xor_si128(s3, s0); - s3 = _mm_or_si128( - _mm_slli_epi32(s3, 8), - _mm_srli_epi32(s3, 24)); - - s2 = _mm_add_epi32(s2, s3); - s1 = _mm_xor_si128(s1, s2); - s1 = _mm_or_si128( - _mm_slli_epi32(s1, 7), - _mm_srli_epi32(s1, 25)); - - /* - * For the odd round, we must rotate some state - * words so that the computations apply on the - * right combinations of words. - */ - s1 = _mm_shuffle_epi32(s1, 0x39); - s2 = _mm_shuffle_epi32(s2, 0x4E); - s3 = _mm_shuffle_epi32(s3, 0x93); - - s0 = _mm_add_epi32(s0, s1); - s3 = _mm_xor_si128(s3, s0); - s3 = _mm_or_si128( - _mm_slli_epi32(s3, 16), - _mm_srli_epi32(s3, 16)); - - s2 = _mm_add_epi32(s2, s3); - s1 = _mm_xor_si128(s1, s2); - s1 = _mm_or_si128( - _mm_slli_epi32(s1, 12), - _mm_srli_epi32(s1, 20)); - - s0 = _mm_add_epi32(s0, s1); - s3 = _mm_xor_si128(s3, s0); - s3 = _mm_or_si128( - _mm_slli_epi32(s3, 8), - _mm_srli_epi32(s3, 24)); - - s2 = _mm_add_epi32(s2, s3); - s1 = _mm_xor_si128(s1, s2); - s1 = _mm_or_si128( - _mm_slli_epi32(s1, 7), - _mm_srli_epi32(s1, 25)); - - /* - * After the odd round, we rotate back the values - * to undo the rotate at the start of the odd round. - */ - s1 = _mm_shuffle_epi32(s1, 0x93); - s2 = _mm_shuffle_epi32(s2, 0x4E); - s3 = _mm_shuffle_epi32(s3, 0x39); - } - - /* - * Addition with the initial state. - */ - s0 = _mm_add_epi32(s0, cw); - s1 = _mm_add_epi32(s1, kw0); - s2 = _mm_add_epi32(s2, kw1); - s3 = _mm_add_epi32(s3, iw); - - /* - * Increment block counter. - */ - iw = _mm_add_epi32(iw, one); - - /* - * XOR final state with the data. - */ - if (len < 64) { - unsigned char tmp[64]; - size_t u; - - _mm_storeu_si128((void *)(tmp + 0), s0); - _mm_storeu_si128((void *)(tmp + 16), s1); - _mm_storeu_si128((void *)(tmp + 32), s2); - _mm_storeu_si128((void *)(tmp + 48), s3); - for (u = 0; u < len; u ++) { - buf[u] ^= tmp[u]; - } - break; - } else { - __m128i b0, b1, b2, b3; - - b0 = _mm_loadu_si128((const void *)(buf + 0)); - b1 = _mm_loadu_si128((const void *)(buf + 16)); - b2 = _mm_loadu_si128((const void *)(buf + 32)); - b3 = _mm_loadu_si128((const void *)(buf + 48)); - b0 = _mm_xor_si128(b0, s0); - b1 = _mm_xor_si128(b1, s1); - b2 = _mm_xor_si128(b2, s2); - b3 = _mm_xor_si128(b3, s3); - _mm_storeu_si128((void *)(buf + 0), b0); - _mm_storeu_si128((void *)(buf + 16), b1); - _mm_storeu_si128((void *)(buf + 32), b2); - _mm_storeu_si128((void *)(buf + 48), b3); - buf += 64; - len -= 64; - } - } - - /* - * _mm_extract_epi32() requires SSE4.1. We prefer to stick to - * raw SSE2, thus we use _mm_extract_epi16(). - */ - return (uint32_t)_mm_extract_epi16(iw, 0) - | ((uint32_t)_mm_extract_epi16(iw, 1) << 16); -} - -BR_TARGETS_X86_DOWN - -#else - -/* see bearssl_block.h */ -br_chacha20_run -br_chacha20_sse2_get(void) -{ - return 0; -} - -#endif - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/config.h b/src/tls/bearssl/config.h deleted file mode 100644 index 158e6cbe2..000000000 --- a/src/tls/bearssl/config.h +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef CONFIG_H__ -#define CONFIG_H__ - -/* - * This file contains compile-time flags that can override the - * autodetection performed in relevant files. Each flag is a macro; it - * deactivates the feature if defined to 0, activates it if defined to a - * non-zero integer (normally 1). If the macro is not defined, then - * autodetection applies. - */ - -/* - * When BR_64 is enabled, 64-bit integer types are assumed to be - * efficient (i.e. the architecture has 64-bit registers and can - * do 64-bit operations as fast as 32-bit operations). - * -#define BR_64 1 - */ - -/* - * When BR_LOMUL is enabled, then multiplications of 32-bit values whose - * result are truncated to the low 32 bits are assumed to be - * substantially more efficient than 32-bit multiplications that yield - * 64-bit results. This is typically the case on low-end ARM Cortex M - * systems (M0, M0+, M1, and arguably M3 and M4 as well). - * -#define BR_LOMUL 1 - */ -#ifdef ARDUINO -#define BR_LOMUL 1 -#endif - -/* - * When BR_SLOW_MUL is enabled, multiplications are assumed to be - * substantially slow with regards to other integer operations, thus - * making it worth to make more operations for a given task if it allows - * using less multiplications. - * -#define BR_SLOW_MUL 1 - */ - -/* - * When BR_SLOW_MUL15 is enabled, short multplications (on 15-bit words) - * are assumed to be substantially slow with regards to other integer - * operations, thus making it worth to make more integer operations if - * it allows using less multiplications. - * -#define BR_SLOW_MUL15 1 - */ - -/* - * When BR_CT_MUL31 is enabled, multiplications of 31-bit values (used - * in the "i31" big integer implementation) use an alternate implementation - * which is slower and larger than the normal multiplication, but should - * ensure constant-time multiplications even on architectures where the - * multiplication opcode takes a variable number of cycles to complete. - * -#define BR_CT_MUL31 1 - */ - -/* - * When BR_CT_MUL15 is enabled, multiplications of 15-bit values (held - * in 32-bit words) use an alternate implementation which is slower and - * larger than the normal multiplication, but should ensure - * constant-time multiplications on most/all architectures where the - * basic multiplication is not constant-time. -#define BR_CT_MUL15 1 - */ - -/* - * When BR_NO_ARITH_SHIFT is enabled, arithmetic right shifts (with sign - * extension) are performed with a sequence of operations which is bigger - * and slower than a simple right shift on a signed value. This avoids - * relying on an implementation-defined behaviour. However, most if not - * all C compilers use sign extension for right shifts on signed values, - * so this alternate macro is disabled by default. -#define BR_NO_ARITH_SHIFT 1 - */ - -/* - * When BR_RDRAND is enabled, the SSL engine will use the RDRAND opcode - * to automatically obtain quality randomness for seeding its internal - * PRNG. Since that opcode is present only in recent x86 CPU, its - * support is dynamically tested; if the current CPU does not support - * it, then another random source will be used, such as /dev/urandom or - * CryptGenRandom(). - * -#define BR_RDRAND 1 - */ - -/* - * When BR_USE_URANDOM is enabled, the SSL engine will use /dev/urandom - * to automatically obtain quality randomness for seedings its internal - * PRNG. - * -#define BR_USE_URANDOM 1 - */ - -/* - * When BR_USE_WIN32_RAND is enabled, the SSL engine will use the Win32 - * (CryptoAPI) functions (CryptAcquireContext(), CryptGenRandom()...) to - * automatically obtain quality randomness for seedings its internal PRNG. - * - * Note: if both BR_USE_URANDOM and BR_USE_WIN32_RAND are defined, the - * former takes precedence. - * -#define BR_USE_WIN32_RAND 1 - */ - -/* - * When BR_USE_UNIX_TIME is enabled, the X.509 validation engine obtains - * the current time from the OS by calling time(), and assuming that the - * returned value (a 'time_t') is an integer that counts time in seconds - * since the Unix Epoch (Jan 1st, 1970, 00:00 UTC). - * -#define BR_USE_UNIX_TIME 1 - */ - -/* - * When BR_USE_WIN32_TIME is enabled, the X.509 validation engine obtains - * the current time from the OS by calling the Win32 function - * GetSystemTimeAsFileTime(). - * - * Note: if both BR_USE_UNIX_TIME and BR_USE_WIN32_TIME are defined, the - * former takes precedence. - * -#define BR_USE_WIN32_TIME 1 - */ - -/* - * When BR_ARMEL_CORTEXM_GCC is enabled, some operations are replaced with - * inline assembly which is shorter and/or faster. This should be used - * only when all of the following are true: - * - target architecture is ARM in Thumb mode - * - target endianness is little-endian - * - compiler is GCC (or GCC-compatible for inline assembly syntax) - * - * This is meant for the low-end cores (Cortex M0, M0+, M1, M3). - * Note: if BR_LOMUL is not explicitly enabled or disabled, then - * enabling BR_ARMEL_CORTEXM_GCC also enables BR_LOMUL. - * -#define BR_ARMEL_CORTEXM_GCC 1 - */ -#if defined(ARDUINO) && defined(__arm__) -#define BR_ARMEL_CORTEXM_GCC 1 -#endif - -/* - * When BR_AES_X86NI is enabled, the AES implementation using the x86 "NI" - * instructions (dedicated AES opcodes) will be compiled. If this is not - * enabled explicitly, then that AES implementation will be compiled only - * if a compatible compiler is detected. If set explicitly to 0, the - * implementation will not be compiled at all. - * -#define BR_AES_X86NI 1 - */ - -/* - * When BR_SSE2 is enabled, SSE2 intrinsics will be used for some - * algorithm implementations that use them (e.g. chacha20_sse2). If this - * is not enabled explicitly, then support for SSE2 intrinsics will be - * automatically detected. If set explicitly to 0, then SSE2 code will - * not be compiled at all. - * -#define BR_SSE2 1 - */ - -/* - * When BR_POWER8 is enabled, the AES implementation using the POWER ISA - * 2.07 opcodes (available on POWER8 processors and later) is compiled. - * If this is not enabled explicitly, then that implementation will be - * compiled only if a compatible compiler is detected, _and_ the target - * architecture is POWER8 or later. - * -#define BR_POWER8 1 - */ - -/* - * When BR_INT128 is enabled, then code using the 'unsigned __int64' - * and 'unsigned __int128' types will be used to leverage 64x64->128 - * unsigned multiplications. This should work with GCC and compatible - * compilers on 64-bit architectures. - * -#define BR_INT128 1 - */ - -/* - * When BR_UMUL128 is enabled, then code using the '_umul128()' and - * '_addcarry_u64()' intrinsics will be used to implement 64x64->128 - * unsigned multiplications. This should work on Visual C on x64 systems. - * -#define BR_UMUL128 1 - */ - -/* - * When BR_LE_UNALIGNED is enabled, then the current architecture is - * assumed to use little-endian encoding for integers, and to tolerate - * unaligned accesses with no or minimal time penalty. - * -#define BR_LE_UNALIGNED 1 - */ - -/* - * When BR_BE_UNALIGNED is enabled, then the current architecture is - * assumed to use big-endian encoding for integers, and to tolerate - * unaligned accesses with no or minimal time penalty. - * -#define BR_BE_UNALIGNED 1 - */ - -#endif diff --git a/src/tls/bearssl/dec16be.c b/src/tls/bearssl/dec16be.c deleted file mode 100644 index 4802ffedd..000000000 --- a/src/tls/bearssl/dec16be.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_range_dec16be(uint16_t *v, size_t num, const void *src) -{ - const unsigned char *buf; - - buf = src; - while (num -- > 0) { - *v ++ = br_dec16be(buf); - buf += 2; - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/dec16le.c b/src/tls/bearssl/dec16le.c deleted file mode 100644 index 377639a84..000000000 --- a/src/tls/bearssl/dec16le.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_range_dec16le(uint16_t *v, size_t num, const void *src) -{ - const unsigned char *buf; - - buf = src; - while (num -- > 0) { - *v ++ = br_dec16le(buf); - buf += 2; - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/dec32be.c b/src/tls/bearssl/dec32be.c deleted file mode 100644 index 733381229..000000000 --- a/src/tls/bearssl/dec32be.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#if defined(BOARD_HAS_ECCX08) || defined(BOARD_HAS_OFFLOADED_ECCX08) || \ - defined(BOARD_HAS_SE050) || defined(ARDUINO_ARCH_ESP32) || \ - defined(ARDUINO_UNOR4_WIFI) - -#include "inner.h" - -/* see inner.h */ -void -br_range_dec32be(uint32_t *v, size_t num, const void *src) -{ - const unsigned char *buf; - - buf = src; - while (num -- > 0) { - *v ++ = br_dec32be(buf); - buf += 4; - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/dec32le.c b/src/tls/bearssl/dec32le.c deleted file mode 100644 index 7fca69ac4..000000000 --- a/src/tls/bearssl/dec32le.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_range_dec32le(uint32_t *v, size_t num, const void *src) -{ - const unsigned char *buf; - - buf = src; - while (num -- > 0) { - *v ++ = br_dec32le(buf); - buf += 4; - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/dec64be.c b/src/tls/bearssl/dec64be.c deleted file mode 100644 index c0d26628e..000000000 --- a/src/tls/bearssl/dec64be.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_range_dec64be(uint64_t *v, size_t num, const void *src) -{ - const unsigned char *buf; - - buf = src; - while (num -- > 0) { - *v ++ = br_dec64be(buf); - buf += 8; - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/dec64le.c b/src/tls/bearssl/dec64le.c deleted file mode 100644 index 293fd2d99..000000000 --- a/src/tls/bearssl/dec64le.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_range_dec64le(uint64_t *v, size_t num, const void *src) -{ - const unsigned char *buf; - - buf = src; - while (num -- > 0) { - *v ++ = br_dec64le(buf); - buf += 8; - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/des_ct.c b/src/tls/bearssl/des_ct.c deleted file mode 100644 index 5b13c97ff..000000000 --- a/src/tls/bearssl/des_ct.c +++ /dev/null @@ -1,416 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * During key schedule, we need to apply bit extraction PC-2 then permute - * things into our bitslice representation. PC-2 extracts 48 bits out - * of two 28-bit words (kl and kr), and we store these bits into two - * 32-bit words sk0 and sk1. - * - * -- bit 16+x of sk0 comes from bit QL0[x] of kl - * -- bit x of sk0 comes from bit QR0[x] of kr - * -- bit 16+x of sk1 comes from bit QL1[x] of kl - * -- bit x of sk1 comes from bit QR1[x] of kr - */ - -static const unsigned char QL0[] = { - 17, 4, 27, 23, 13, 22, 7, 18, - 16, 24, 2, 20, 1, 8, 15, 26 -}; - -static const unsigned char QR0[] = { - 25, 19, 9, 1, 5, 11, 23, 8, - 17, 0, 22, 3, 6, 20, 27, 24 -}; - -static const unsigned char QL1[] = { - 28, 28, 14, 11, 28, 28, 25, 0, - 28, 28, 5, 9, 28, 28, 12, 21 -}; - -static const unsigned char QR1[] = { - 28, 28, 15, 4, 28, 28, 26, 16, - 28, 28, 12, 7, 28, 28, 10, 14 -}; - -/* - * 32-bit rotation. The C compiler is supposed to recognize it as a - * rotation and use the local architecture rotation opcode (if available). - */ -static inline uint32_t -rotl(uint32_t x, int n) -{ - return (x << n) | (x >> (32 - n)); -} - -/* - * Compute key schedule for 8 key bytes (produces 32 subkey words). - */ -static void -keysched_unit(uint32_t *skey, const void *key) -{ - int i; - - br_des_keysched_unit(skey, key); - - /* - * Apply PC-2 + bitslicing. - */ - for (i = 0; i < 16; i ++) { - uint32_t kl, kr, sk0, sk1; - int j; - - kl = skey[(i << 1) + 0]; - kr = skey[(i << 1) + 1]; - sk0 = 0; - sk1 = 0; - for (j = 0; j < 16; j ++) { - sk0 <<= 1; - sk1 <<= 1; - sk0 |= ((kl >> QL0[j]) & (uint32_t)1) << 16; - sk0 |= (kr >> QR0[j]) & (uint32_t)1; - sk1 |= ((kl >> QL1[j]) & (uint32_t)1) << 16; - sk1 |= (kr >> QR1[j]) & (uint32_t)1; - } - - skey[(i << 1) + 0] = sk0; - skey[(i << 1) + 1] = sk1; - } - -#if 0 - /* - * Speed-optimized version for PC-2 + bitslicing. - * (Unused. Kept for reference only.) - */ - sk0 = kl & (uint32_t)0x00100000; - sk0 |= (kl & (uint32_t)0x08008000) << 2; - sk0 |= (kl & (uint32_t)0x00400000) << 4; - sk0 |= (kl & (uint32_t)0x00800000) << 5; - sk0 |= (kl & (uint32_t)0x00040000) << 6; - sk0 |= (kl & (uint32_t)0x00010000) << 7; - sk0 |= (kl & (uint32_t)0x00000100) << 10; - sk0 |= (kl & (uint32_t)0x00022000) << 14; - sk0 |= (kl & (uint32_t)0x00000082) << 18; - sk0 |= (kl & (uint32_t)0x00000004) << 19; - sk0 |= (kl & (uint32_t)0x04000000) >> 10; - sk0 |= (kl & (uint32_t)0x00000010) << 26; - sk0 |= (kl & (uint32_t)0x01000000) >> 2; - - sk0 |= kr & (uint32_t)0x00000100; - sk0 |= (kr & (uint32_t)0x00000008) << 1; - sk0 |= (kr & (uint32_t)0x00000200) << 4; - sk0 |= rotl(kr & (uint32_t)0x08000021, 6); - sk0 |= (kr & (uint32_t)0x01000000) >> 24; - sk0 |= (kr & (uint32_t)0x00000002) << 11; - sk0 |= (kr & (uint32_t)0x00100000) >> 18; - sk0 |= (kr & (uint32_t)0x00400000) >> 17; - sk0 |= (kr & (uint32_t)0x00800000) >> 14; - sk0 |= (kr & (uint32_t)0x02020000) >> 10; - sk0 |= (kr & (uint32_t)0x00080000) >> 5; - sk0 |= (kr & (uint32_t)0x00000040) >> 3; - sk0 |= (kr & (uint32_t)0x00000800) >> 1; - - sk1 = kl & (uint32_t)0x02000000; - sk1 |= (kl & (uint32_t)0x00001000) << 5; - sk1 |= (kl & (uint32_t)0x00000200) << 11; - sk1 |= (kl & (uint32_t)0x00004000) << 15; - sk1 |= (kl & (uint32_t)0x00000020) << 16; - sk1 |= (kl & (uint32_t)0x00000800) << 17; - sk1 |= (kl & (uint32_t)0x00000001) << 24; - sk1 |= (kl & (uint32_t)0x00200000) >> 5; - - sk1 |= (kr & (uint32_t)0x00000010) << 8; - sk1 |= (kr & (uint32_t)0x04000000) >> 17; - sk1 |= (kr & (uint32_t)0x00004000) >> 14; - sk1 |= (kr & (uint32_t)0x00000400) >> 9; - sk1 |= (kr & (uint32_t)0x00010000) >> 8; - sk1 |= (kr & (uint32_t)0x00001000) >> 7; - sk1 |= (kr & (uint32_t)0x00000080) >> 3; - sk1 |= (kr & (uint32_t)0x00008000) >> 2; -#endif -} - -/* see inner.h */ -unsigned -br_des_ct_keysched(uint32_t *skey, const void *key, size_t key_len) -{ - switch (key_len) { - case 8: - keysched_unit(skey, key); - return 1; - case 16: - keysched_unit(skey, key); - keysched_unit(skey + 32, (const unsigned char *)key + 8); - br_des_rev_skey(skey + 32); - memcpy(skey + 64, skey, 32 * sizeof *skey); - return 3; - default: - keysched_unit(skey, key); - keysched_unit(skey + 32, (const unsigned char *)key + 8); - br_des_rev_skey(skey + 32); - keysched_unit(skey + 64, (const unsigned char *)key + 16); - return 3; - } -} - -/* - * DES confusion function. This function performs expansion E (32 to - * 48 bits), XOR with subkey, S-boxes, and permutation P. - */ -static inline uint32_t -Fconf(uint32_t r0, const uint32_t *sk) -{ - /* - * Each 6->4 S-box is virtually turned into four 6->1 boxes; we - * thus end up with 32 boxes that we call "T-boxes" here. We will - * evaluate them with bitslice code. - * - * Each T-box is a circuit of multiplexers (sort of) and thus - * takes 70 inputs: the 6 actual T-box inputs, and 64 constants - * that describe the T-box output for all combinations of the - * 6 inputs. With this model, all T-boxes are identical (with - * distinct inputs) and thus can be executed in parallel with - * bitslice code. - * - * T-boxes are numbered from 0 to 31, in least-to-most - * significant order. Thus, S-box S1 corresponds to T-boxes 31, - * 30, 29 and 28, in that order. T-box 'n' is computed with the - * bits at rank 'n' in the 32-bit words. - * - * Words x0 to x5 contain the T-box inputs 0 to 5. - */ - uint32_t x0, x1, x2, x3, x4, x5, z0; - uint32_t y0, y1, y2, y3, y4, y5, y6, y7, y8, y9; - uint32_t y10, y11, y12, y13, y14, y15, y16, y17, y18, y19; - uint32_t y20, y21, y22, y23, y24, y25, y26, y27, y28, y29; - uint32_t y30; - - /* - * Spread input bits over the 6 input words x*. - */ - x1 = r0 & (uint32_t)0x11111111; - x2 = (r0 >> 1) & (uint32_t)0x11111111; - x3 = (r0 >> 2) & (uint32_t)0x11111111; - x4 = (r0 >> 3) & (uint32_t)0x11111111; - x1 = (x1 << 4) - x1; - x2 = (x2 << 4) - x2; - x3 = (x3 << 4) - x3; - x4 = (x4 << 4) - x4; - x0 = (x4 << 4) | (x4 >> 28); - x5 = (x1 >> 4) | (x1 << 28); - - /* - * XOR with the subkey for this round. - */ - x0 ^= sk[0]; - x1 ^= sk[1]; - x2 ^= sk[2]; - x3 ^= sk[3]; - x4 ^= sk[4]; - x5 ^= sk[5]; - - /* - * The T-boxes are done in parallel, since they all use a - * "tree of multiplexer". We use "fake multiplexers": - * - * y = a ^ (x & b) - * - * computes y as either 'a' (if x == 0) or 'a ^ b' (if x == 1). - */ - y0 = (uint32_t)0xEFA72C4D ^ (x0 & (uint32_t)0xEC7AC69C); - y1 = (uint32_t)0xAEAAEDFF ^ (x0 & (uint32_t)0x500FB821); - y2 = (uint32_t)0x37396665 ^ (x0 & (uint32_t)0x40EFA809); - y3 = (uint32_t)0x68D7B833 ^ (x0 & (uint32_t)0xA5EC0B28); - y4 = (uint32_t)0xC9C755BB ^ (x0 & (uint32_t)0x252CF820); - y5 = (uint32_t)0x73FC3606 ^ (x0 & (uint32_t)0x40205801); - y6 = (uint32_t)0xA2A0A918 ^ (x0 & (uint32_t)0xE220F929); - y7 = (uint32_t)0x8222BD90 ^ (x0 & (uint32_t)0x44A3F9E1); - y8 = (uint32_t)0xD6B6AC77 ^ (x0 & (uint32_t)0x794F104A); - y9 = (uint32_t)0x3069300C ^ (x0 & (uint32_t)0x026F320B); - y10 = (uint32_t)0x6CE0D5CC ^ (x0 & (uint32_t)0x7640B01A); - y11 = (uint32_t)0x59A9A22D ^ (x0 & (uint32_t)0x238F1572); - y12 = (uint32_t)0xAC6D0BD4 ^ (x0 & (uint32_t)0x7A63C083); - y13 = (uint32_t)0x21C83200 ^ (x0 & (uint32_t)0x11CCA000); - y14 = (uint32_t)0xA0E62188 ^ (x0 & (uint32_t)0x202F69AA); - /* y15 = (uint32_t)0x00000000 ^ (x0 & (uint32_t)0x00000000); */ - y16 = (uint32_t)0xAF7D655A ^ (x0 & (uint32_t)0x51B33BE9); - y17 = (uint32_t)0xF0168AA3 ^ (x0 & (uint32_t)0x3B0FE8AE); - y18 = (uint32_t)0x90AA30C6 ^ (x0 & (uint32_t)0x90BF8816); - y19 = (uint32_t)0x5AB2750A ^ (x0 & (uint32_t)0x09E34F9B); - y20 = (uint32_t)0x5391BE65 ^ (x0 & (uint32_t)0x0103BE88); - y21 = (uint32_t)0x93372BAF ^ (x0 & (uint32_t)0x49AC8E25); - y22 = (uint32_t)0xF288210C ^ (x0 & (uint32_t)0x922C313D); - y23 = (uint32_t)0x920AF5C0 ^ (x0 & (uint32_t)0x70EF31B0); - y24 = (uint32_t)0x63D312C0 ^ (x0 & (uint32_t)0x6A707100); - y25 = (uint32_t)0x537B3006 ^ (x0 & (uint32_t)0xB97C9011); - y26 = (uint32_t)0xA2EFB0A5 ^ (x0 & (uint32_t)0xA320C959); - y27 = (uint32_t)0xBC8F96A5 ^ (x0 & (uint32_t)0x6EA0AB4A); - y28 = (uint32_t)0xFAD176A5 ^ (x0 & (uint32_t)0x6953DDF8); - y29 = (uint32_t)0x665A14A3 ^ (x0 & (uint32_t)0xF74F3E2B); - y30 = (uint32_t)0xF2EFF0CC ^ (x0 & (uint32_t)0xF0306CAD); - /* y31 = (uint32_t)0x00000000 ^ (x0 & (uint32_t)0x00000000); */ - - y0 = y0 ^ (x1 & y1); - y1 = y2 ^ (x1 & y3); - y2 = y4 ^ (x1 & y5); - y3 = y6 ^ (x1 & y7); - y4 = y8 ^ (x1 & y9); - y5 = y10 ^ (x1 & y11); - y6 = y12 ^ (x1 & y13); - y7 = y14; /* was: y14 ^ (x1 & y15) */ - y8 = y16 ^ (x1 & y17); - y9 = y18 ^ (x1 & y19); - y10 = y20 ^ (x1 & y21); - y11 = y22 ^ (x1 & y23); - y12 = y24 ^ (x1 & y25); - y13 = y26 ^ (x1 & y27); - y14 = y28 ^ (x1 & y29); - y15 = y30; /* was: y30 ^ (x1 & y31) */ - - y0 = y0 ^ (x2 & y1); - y1 = y2 ^ (x2 & y3); - y2 = y4 ^ (x2 & y5); - y3 = y6 ^ (x2 & y7); - y4 = y8 ^ (x2 & y9); - y5 = y10 ^ (x2 & y11); - y6 = y12 ^ (x2 & y13); - y7 = y14 ^ (x2 & y15); - - y0 = y0 ^ (x3 & y1); - y1 = y2 ^ (x3 & y3); - y2 = y4 ^ (x3 & y5); - y3 = y6 ^ (x3 & y7); - - y0 = y0 ^ (x4 & y1); - y1 = y2 ^ (x4 & y3); - - y0 = y0 ^ (x5 & y1); - - /* - * The P permutation: - * -- Each bit move is converted into a mask + left rotation. - * -- Rotations that use the same movement are coalesced together. - * -- Left and right shifts are used as alternatives to a rotation - * where appropriate (this will help architectures that do not have - * a rotation opcode). - */ - z0 = (y0 & (uint32_t)0x00000004) << 3; - z0 |= (y0 & (uint32_t)0x00004000) << 4; - z0 |= rotl(y0 & 0x12020120, 5); - z0 |= (y0 & (uint32_t)0x00100000) << 6; - z0 |= (y0 & (uint32_t)0x00008000) << 9; - z0 |= (y0 & (uint32_t)0x04000000) >> 22; - z0 |= (y0 & (uint32_t)0x00000001) << 11; - z0 |= rotl(y0 & 0x20000200, 12); - z0 |= (y0 & (uint32_t)0x00200000) >> 19; - z0 |= (y0 & (uint32_t)0x00000040) << 14; - z0 |= (y0 & (uint32_t)0x00010000) << 15; - z0 |= (y0 & (uint32_t)0x00000002) << 16; - z0 |= rotl(y0 & 0x40801800, 17); - z0 |= (y0 & (uint32_t)0x00080000) >> 13; - z0 |= (y0 & (uint32_t)0x00000010) << 21; - z0 |= (y0 & (uint32_t)0x01000000) >> 10; - z0 |= rotl(y0 & 0x88000008, 24); - z0 |= (y0 & (uint32_t)0x00000480) >> 7; - z0 |= (y0 & (uint32_t)0x00442000) >> 6; - return z0; -} - -/* - * Process one block through 16 successive rounds, omitting the swap - * in the final round. - */ -static void -process_block_unit(uint32_t *pl, uint32_t *pr, const uint32_t *sk_exp) -{ - int i; - uint32_t l, r; - - l = *pl; - r = *pr; - for (i = 0; i < 16; i ++) { - uint32_t t; - - t = l ^ Fconf(r, sk_exp); - l = r; - r = t; - sk_exp += 6; - } - *pl = r; - *pr = l; -} - -/* see inner.h */ -void -br_des_ct_process_block(unsigned num_rounds, - const uint32_t *sk_exp, void *block) -{ - unsigned char *buf; - uint32_t l, r; - - buf = block; - l = br_dec32be(buf); - r = br_dec32be(buf + 4); - br_des_do_IP(&l, &r); - while (num_rounds -- > 0) { - process_block_unit(&l, &r, sk_exp); - sk_exp += 96; - } - br_des_do_invIP(&l, &r); - br_enc32be(buf, l); - br_enc32be(buf + 4, r); -} - -/* see inner.h */ -void -br_des_ct_skey_expand(uint32_t *sk_exp, - unsigned num_rounds, const uint32_t *skey) -{ - num_rounds <<= 4; - while (num_rounds -- > 0) { - uint32_t v, w0, w1, w2, w3; - - v = *skey ++; - w0 = v & 0x11111111; - w1 = (v >> 1) & 0x11111111; - w2 = (v >> 2) & 0x11111111; - w3 = (v >> 3) & 0x11111111; - *sk_exp ++ = (w0 << 4) - w0; - *sk_exp ++ = (w1 << 4) - w1; - *sk_exp ++ = (w2 << 4) - w2; - *sk_exp ++ = (w3 << 4) - w3; - v = *skey ++; - w0 = v & 0x11111111; - w1 = (v >> 1) & 0x11111111; - *sk_exp ++ = (w0 << 4) - w0; - *sk_exp ++ = (w1 << 4) - w1; - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/des_ct_cbcdec.c b/src/tls/bearssl/des_ct_cbcdec.c deleted file mode 100644 index b0742ae84..000000000 --- a/src/tls/bearssl/des_ct_cbcdec.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_block.h */ -void -br_des_ct_cbcdec_init(br_des_ct_cbcdec_keys *ctx, - const void *key, size_t len) -{ - ctx->vtable = &br_des_ct_cbcdec_vtable; - ctx->num_rounds = br_des_ct_keysched(ctx->skey, key, len); - if (len == 8) { - br_des_rev_skey(ctx->skey); - } else { - int i; - - for (i = 0; i < 48; i += 2) { - uint32_t t; - - t = ctx->skey[i]; - ctx->skey[i] = ctx->skey[94 - i]; - ctx->skey[94 - i] = t; - t = ctx->skey[i + 1]; - ctx->skey[i + 1] = ctx->skey[95 - i]; - ctx->skey[95 - i] = t; - } - } -} - -/* see bearssl_block.h */ -void -br_des_ct_cbcdec_run(const br_des_ct_cbcdec_keys *ctx, - void *iv, void *data, size_t len) -{ - unsigned char *buf, *ivbuf; - uint32_t sk_exp[288]; - - br_des_ct_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); - ivbuf = iv; - buf = data; - while (len > 0) { - unsigned char tmp[8]; - int i; - - memcpy(tmp, buf, 8); - br_des_ct_process_block(ctx->num_rounds, sk_exp, buf); - for (i = 0; i < 8; i ++) { - buf[i] ^= ivbuf[i]; - } - memcpy(ivbuf, tmp, 8); - buf += 8; - len -= 8; - } -} - -/* see bearssl_block.h */ -const br_block_cbcdec_class br_des_ct_cbcdec_vtable = { - sizeof(br_des_ct_cbcdec_keys), - 8, - 3, - (void (*)(const br_block_cbcdec_class **, const void *, size_t)) - &br_des_ct_cbcdec_init, - (void (*)(const br_block_cbcdec_class *const *, void *, void *, size_t)) - &br_des_ct_cbcdec_run -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/des_ct_cbcenc.c b/src/tls/bearssl/des_ct_cbcenc.c deleted file mode 100644 index aa60b4ff5..000000000 --- a/src/tls/bearssl/des_ct_cbcenc.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_block.h */ -void -br_des_ct_cbcenc_init(br_des_ct_cbcenc_keys *ctx, - const void *key, size_t len) -{ - ctx->vtable = &br_des_ct_cbcenc_vtable; - ctx->num_rounds = br_des_ct_keysched(ctx->skey, key, len); -} - -/* see bearssl_block.h */ -void -br_des_ct_cbcenc_run(const br_des_ct_cbcenc_keys *ctx, - void *iv, void *data, size_t len) -{ - unsigned char *buf, *ivbuf; - uint32_t sk_exp[288]; - - br_des_ct_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); - ivbuf = iv; - buf = data; - while (len > 0) { - int i; - - for (i = 0; i < 8; i ++) { - buf[i] ^= ivbuf[i]; - } - br_des_ct_process_block(ctx->num_rounds, sk_exp, buf); - memcpy(ivbuf, buf, 8); - buf += 8; - len -= 8; - } -} - -/* see bearssl_block.h */ -const br_block_cbcenc_class br_des_ct_cbcenc_vtable = { - sizeof(br_des_ct_cbcenc_keys), - 8, - 3, - (void (*)(const br_block_cbcenc_class **, const void *, size_t)) - &br_des_ct_cbcenc_init, - (void (*)(const br_block_cbcenc_class *const *, void *, void *, size_t)) - &br_des_ct_cbcenc_run -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/des_support.c b/src/tls/bearssl/des_support.c deleted file mode 100644 index 4db9bd87e..000000000 --- a/src/tls/bearssl/des_support.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_des_do_IP(uint32_t *xl, uint32_t *xr) -{ - /* - * Permutation algorithm is initially from Richard Outerbridge; - * implementation here is adapted from Crypto++ "des.cpp" file - * (which is in public domain). - */ - uint32_t l, r, t; - - l = *xl; - r = *xr; - t = ((l >> 4) ^ r) & (uint32_t)0x0F0F0F0F; - r ^= t; - l ^= t << 4; - t = ((l >> 16) ^ r) & (uint32_t)0x0000FFFF; - r ^= t; - l ^= t << 16; - t = ((r >> 2) ^ l) & (uint32_t)0x33333333; - l ^= t; - r ^= t << 2; - t = ((r >> 8) ^ l) & (uint32_t)0x00FF00FF; - l ^= t; - r ^= t << 8; - t = ((l >> 1) ^ r) & (uint32_t)0x55555555; - r ^= t; - l ^= t << 1; - *xl = l; - *xr = r; -} - -/* see inner.h */ -void -br_des_do_invIP(uint32_t *xl, uint32_t *xr) -{ - /* - * See br_des_do_IP(). - */ - uint32_t l, r, t; - - l = *xl; - r = *xr; - t = ((l >> 1) ^ r) & 0x55555555; - r ^= t; - l ^= t << 1; - t = ((r >> 8) ^ l) & 0x00FF00FF; - l ^= t; - r ^= t << 8; - t = ((r >> 2) ^ l) & 0x33333333; - l ^= t; - r ^= t << 2; - t = ((l >> 16) ^ r) & 0x0000FFFF; - r ^= t; - l ^= t << 16; - t = ((l >> 4) ^ r) & 0x0F0F0F0F; - r ^= t; - l ^= t << 4; - *xl = l; - *xr = r; -} - -/* see inner.h */ -void -br_des_keysched_unit(uint32_t *skey, const void *key) -{ - uint32_t xl, xr, kl, kr; - int i; - - xl = br_dec32be(key); - xr = br_dec32be((const unsigned char *)key + 4); - - /* - * Permutation PC-1 is quite similar to the IP permutation. - * Definition of IP (in FIPS 46-3 notations) is: - * 58 50 42 34 26 18 10 2 - * 60 52 44 36 28 20 12 4 - * 62 54 46 38 30 22 14 6 - * 64 56 48 40 32 24 16 8 - * 57 49 41 33 25 17 9 1 - * 59 51 43 35 27 19 11 3 - * 61 53 45 37 29 21 13 5 - * 63 55 47 39 31 23 15 7 - * - * Definition of PC-1 is: - * 57 49 41 33 25 17 9 1 - * 58 50 42 34 26 18 10 2 - * 59 51 43 35 27 19 11 3 - * 60 52 44 36 - * 63 55 47 39 31 23 15 7 - * 62 54 46 38 30 22 14 6 - * 61 53 45 37 29 21 13 5 - * 28 20 12 4 - */ - br_des_do_IP(&xl, &xr); - kl = ((xr & (uint32_t)0xFF000000) >> 4) - | ((xl & (uint32_t)0xFF000000) >> 12) - | ((xr & (uint32_t)0x00FF0000) >> 12) - | ((xl & (uint32_t)0x00FF0000) >> 20); - kr = ((xr & (uint32_t)0x000000FF) << 20) - | ((xl & (uint32_t)0x0000FF00) << 4) - | ((xr & (uint32_t)0x0000FF00) >> 4) - | ((xl & (uint32_t)0x000F0000) >> 16); - - /* - * For each round, rotate the two 28-bit words kl and kr. - * The extraction of the 48-bit subkey (PC-2) is not done yet. - */ - for (i = 0; i < 16; i ++) { - if ((1 << i) & 0x8103) { - kl = (kl << 1) | (kl >> 27); - kr = (kr << 1) | (kr >> 27); - } else { - kl = (kl << 2) | (kl >> 26); - kr = (kr << 2) | (kr >> 26); - } - kl &= (uint32_t)0x0FFFFFFF; - kr &= (uint32_t)0x0FFFFFFF; - skey[(i << 1) + 0] = kl; - skey[(i << 1) + 1] = kr; - } -} - -/* see inner.h */ -void -br_des_rev_skey(uint32_t *skey) -{ - int i; - - for (i = 0; i < 16; i += 2) { - uint32_t t; - - t = skey[i + 0]; - skey[i + 0] = skey[30 - i]; - skey[30 - i] = t; - t = skey[i + 1]; - skey[i + 1] = skey[31 - i]; - skey[31 - i] = t; - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/des_tab.c b/src/tls/bearssl/des_tab.c deleted file mode 100644 index dd6063ece..000000000 --- a/src/tls/bearssl/des_tab.c +++ /dev/null @@ -1,315 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * PC2left[x] tells where bit x goes when applying PC-2. 'x' is a bit - * position in the left rotated key word. Both position are in normal - * order (rightmost bit is 0). - */ -static const unsigned char PC2left[] = { - 16, 3, 7, 24, 20, 11, 24, - 13, 2, 10, 24, 22, 5, 15, - 23, 1, 9, 21, 12, 24, 6, - 4, 14, 18, 8, 17, 0, 19 -}; - -/* - * Similar to PC2left[x], for the right rotated key word. - */ -static const unsigned char PC2right[] = { - 8, 18, 24, 6, 22, 15, 3, - 10, 12, 19, 5, 14, 11, 24, - 4, 23, 16, 9, 24, 20, 2, - 24, 7, 13, 0, 21, 17, 1 -}; - -/* - * S-boxes and PC-1 merged. - */ -static const uint32_t S1[] = { - 0x00808200, 0x00000000, 0x00008000, 0x00808202, - 0x00808002, 0x00008202, 0x00000002, 0x00008000, - 0x00000200, 0x00808200, 0x00808202, 0x00000200, - 0x00800202, 0x00808002, 0x00800000, 0x00000002, - 0x00000202, 0x00800200, 0x00800200, 0x00008200, - 0x00008200, 0x00808000, 0x00808000, 0x00800202, - 0x00008002, 0x00800002, 0x00800002, 0x00008002, - 0x00000000, 0x00000202, 0x00008202, 0x00800000, - 0x00008000, 0x00808202, 0x00000002, 0x00808000, - 0x00808200, 0x00800000, 0x00800000, 0x00000200, - 0x00808002, 0x00008000, 0x00008200, 0x00800002, - 0x00000200, 0x00000002, 0x00800202, 0x00008202, - 0x00808202, 0x00008002, 0x00808000, 0x00800202, - 0x00800002, 0x00000202, 0x00008202, 0x00808200, - 0x00000202, 0x00800200, 0x00800200, 0x00000000, - 0x00008002, 0x00008200, 0x00000000, 0x00808002 -}; - -static const uint32_t S2[] = { - 0x40084010, 0x40004000, 0x00004000, 0x00084010, - 0x00080000, 0x00000010, 0x40080010, 0x40004010, - 0x40000010, 0x40084010, 0x40084000, 0x40000000, - 0x40004000, 0x00080000, 0x00000010, 0x40080010, - 0x00084000, 0x00080010, 0x40004010, 0x00000000, - 0x40000000, 0x00004000, 0x00084010, 0x40080000, - 0x00080010, 0x40000010, 0x00000000, 0x00084000, - 0x00004010, 0x40084000, 0x40080000, 0x00004010, - 0x00000000, 0x00084010, 0x40080010, 0x00080000, - 0x40004010, 0x40080000, 0x40084000, 0x00004000, - 0x40080000, 0x40004000, 0x00000010, 0x40084010, - 0x00084010, 0x00000010, 0x00004000, 0x40000000, - 0x00004010, 0x40084000, 0x00080000, 0x40000010, - 0x00080010, 0x40004010, 0x40000010, 0x00080010, - 0x00084000, 0x00000000, 0x40004000, 0x00004010, - 0x40000000, 0x40080010, 0x40084010, 0x00084000 -}; - -static const uint32_t S3[] = { - 0x00000104, 0x04010100, 0x00000000, 0x04010004, - 0x04000100, 0x00000000, 0x00010104, 0x04000100, - 0x00010004, 0x04000004, 0x04000004, 0x00010000, - 0x04010104, 0x00010004, 0x04010000, 0x00000104, - 0x04000000, 0x00000004, 0x04010100, 0x00000100, - 0x00010100, 0x04010000, 0x04010004, 0x00010104, - 0x04000104, 0x00010100, 0x00010000, 0x04000104, - 0x00000004, 0x04010104, 0x00000100, 0x04000000, - 0x04010100, 0x04000000, 0x00010004, 0x00000104, - 0x00010000, 0x04010100, 0x04000100, 0x00000000, - 0x00000100, 0x00010004, 0x04010104, 0x04000100, - 0x04000004, 0x00000100, 0x00000000, 0x04010004, - 0x04000104, 0x00010000, 0x04000000, 0x04010104, - 0x00000004, 0x00010104, 0x00010100, 0x04000004, - 0x04010000, 0x04000104, 0x00000104, 0x04010000, - 0x00010104, 0x00000004, 0x04010004, 0x00010100 -}; - -static const uint32_t S4[] = { - 0x80401000, 0x80001040, 0x80001040, 0x00000040, - 0x00401040, 0x80400040, 0x80400000, 0x80001000, - 0x00000000, 0x00401000, 0x00401000, 0x80401040, - 0x80000040, 0x00000000, 0x00400040, 0x80400000, - 0x80000000, 0x00001000, 0x00400000, 0x80401000, - 0x00000040, 0x00400000, 0x80001000, 0x00001040, - 0x80400040, 0x80000000, 0x00001040, 0x00400040, - 0x00001000, 0x00401040, 0x80401040, 0x80000040, - 0x00400040, 0x80400000, 0x00401000, 0x80401040, - 0x80000040, 0x00000000, 0x00000000, 0x00401000, - 0x00001040, 0x00400040, 0x80400040, 0x80000000, - 0x80401000, 0x80001040, 0x80001040, 0x00000040, - 0x80401040, 0x80000040, 0x80000000, 0x00001000, - 0x80400000, 0x80001000, 0x00401040, 0x80400040, - 0x80001000, 0x00001040, 0x00400000, 0x80401000, - 0x00000040, 0x00400000, 0x00001000, 0x00401040 -}; - -static const uint32_t S5[] = { - 0x00000080, 0x01040080, 0x01040000, 0x21000080, - 0x00040000, 0x00000080, 0x20000000, 0x01040000, - 0x20040080, 0x00040000, 0x01000080, 0x20040080, - 0x21000080, 0x21040000, 0x00040080, 0x20000000, - 0x01000000, 0x20040000, 0x20040000, 0x00000000, - 0x20000080, 0x21040080, 0x21040080, 0x01000080, - 0x21040000, 0x20000080, 0x00000000, 0x21000000, - 0x01040080, 0x01000000, 0x21000000, 0x00040080, - 0x00040000, 0x21000080, 0x00000080, 0x01000000, - 0x20000000, 0x01040000, 0x21000080, 0x20040080, - 0x01000080, 0x20000000, 0x21040000, 0x01040080, - 0x20040080, 0x00000080, 0x01000000, 0x21040000, - 0x21040080, 0x00040080, 0x21000000, 0x21040080, - 0x01040000, 0x00000000, 0x20040000, 0x21000000, - 0x00040080, 0x01000080, 0x20000080, 0x00040000, - 0x00000000, 0x20040000, 0x01040080, 0x20000080 -}; - -static const uint32_t S6[] = { - 0x10000008, 0x10200000, 0x00002000, 0x10202008, - 0x10200000, 0x00000008, 0x10202008, 0x00200000, - 0x10002000, 0x00202008, 0x00200000, 0x10000008, - 0x00200008, 0x10002000, 0x10000000, 0x00002008, - 0x00000000, 0x00200008, 0x10002008, 0x00002000, - 0x00202000, 0x10002008, 0x00000008, 0x10200008, - 0x10200008, 0x00000000, 0x00202008, 0x10202000, - 0x00002008, 0x00202000, 0x10202000, 0x10000000, - 0x10002000, 0x00000008, 0x10200008, 0x00202000, - 0x10202008, 0x00200000, 0x00002008, 0x10000008, - 0x00200000, 0x10002000, 0x10000000, 0x00002008, - 0x10000008, 0x10202008, 0x00202000, 0x10200000, - 0x00202008, 0x10202000, 0x00000000, 0x10200008, - 0x00000008, 0x00002000, 0x10200000, 0x00202008, - 0x00002000, 0x00200008, 0x10002008, 0x00000000, - 0x10202000, 0x10000000, 0x00200008, 0x10002008 -}; - -static const uint32_t S7[] = { - 0x00100000, 0x02100001, 0x02000401, 0x00000000, - 0x00000400, 0x02000401, 0x00100401, 0x02100400, - 0x02100401, 0x00100000, 0x00000000, 0x02000001, - 0x00000001, 0x02000000, 0x02100001, 0x00000401, - 0x02000400, 0x00100401, 0x00100001, 0x02000400, - 0x02000001, 0x02100000, 0x02100400, 0x00100001, - 0x02100000, 0x00000400, 0x00000401, 0x02100401, - 0x00100400, 0x00000001, 0x02000000, 0x00100400, - 0x02000000, 0x00100400, 0x00100000, 0x02000401, - 0x02000401, 0x02100001, 0x02100001, 0x00000001, - 0x00100001, 0x02000000, 0x02000400, 0x00100000, - 0x02100400, 0x00000401, 0x00100401, 0x02100400, - 0x00000401, 0x02000001, 0x02100401, 0x02100000, - 0x00100400, 0x00000000, 0x00000001, 0x02100401, - 0x00000000, 0x00100401, 0x02100000, 0x00000400, - 0x02000001, 0x02000400, 0x00000400, 0x00100001 -}; - -static const uint32_t S8[] = { - 0x08000820, 0x00000800, 0x00020000, 0x08020820, - 0x08000000, 0x08000820, 0x00000020, 0x08000000, - 0x00020020, 0x08020000, 0x08020820, 0x00020800, - 0x08020800, 0x00020820, 0x00000800, 0x00000020, - 0x08020000, 0x08000020, 0x08000800, 0x00000820, - 0x00020800, 0x00020020, 0x08020020, 0x08020800, - 0x00000820, 0x00000000, 0x00000000, 0x08020020, - 0x08000020, 0x08000800, 0x00020820, 0x00020000, - 0x00020820, 0x00020000, 0x08020800, 0x00000800, - 0x00000020, 0x08020020, 0x00000800, 0x00020820, - 0x08000800, 0x00000020, 0x08000020, 0x08020000, - 0x08020020, 0x08000000, 0x00020000, 0x08000820, - 0x00000000, 0x08020820, 0x00020020, 0x08000020, - 0x08020000, 0x08000800, 0x08000820, 0x00000000, - 0x08020820, 0x00020800, 0x00020800, 0x00000820, - 0x00000820, 0x00020020, 0x08000000, 0x08020800 -}; - -static inline uint32_t -Fconf(uint32_t r0, uint32_t skl, uint32_t skr) -{ - uint32_t r1; - - r1 = (r0 << 16) | (r0 >> 16); - return - S1[((r1 >> 11) ^ (skl >> 18)) & 0x3F] - | S2[((r0 >> 23) ^ (skl >> 12)) & 0x3F] - | S3[((r0 >> 19) ^ (skl >> 6)) & 0x3F] - | S4[((r0 >> 15) ^ (skl )) & 0x3F] - | S5[((r0 >> 11) ^ (skr >> 18)) & 0x3F] - | S6[((r0 >> 7) ^ (skr >> 12)) & 0x3F] - | S7[((r0 >> 3) ^ (skr >> 6)) & 0x3F] - | S8[((r1 >> 15) ^ (skr )) & 0x3F]; -} - -static void -process_block_unit(uint32_t *pl, uint32_t *pr, const uint32_t *skey) -{ - int i; - uint32_t l, r; - - l = *pl; - r = *pr; - for (i = 0; i < 16; i ++) { - uint32_t t; - - t = l ^ Fconf(r, skey[(i << 1) + 0], skey[(i << 1) + 1]); - l = r; - r = t; - } - *pl = r; - *pr = l; -} - -/* see inner.h */ -void -br_des_tab_process_block(unsigned num_rounds, const uint32_t *skey, void *block) -{ - unsigned char *buf; - uint32_t l, r; - - buf = block; - l = br_dec32be(buf); - r = br_dec32be(buf + 4); - br_des_do_IP(&l, &r); - while (num_rounds -- > 0) { - process_block_unit(&l, &r, skey); - skey += 32; - } - br_des_do_invIP(&l, &r); - br_enc32be(buf, l); - br_enc32be(buf + 4, r); -} - -static void -keysched_unit(uint32_t *skey, const void *key) -{ - int i; - - br_des_keysched_unit(skey, key); - - /* - * Apply PC-2 to get the 48-bit subkeys. - */ - for (i = 0; i < 16; i ++) { - uint32_t xl, xr, ul, ur; - int j; - - xl = skey[(i << 1) + 0]; - xr = skey[(i << 1) + 1]; - ul = 0; - ur = 0; - for (j = 0; j < 28; j ++) { - ul |= (xl & 1) << PC2left[j]; - ur |= (xr & 1) << PC2right[j]; - xl >>= 1; - xr >>= 1; - } - skey[(i << 1) + 0] = ul; - skey[(i << 1) + 1] = ur; - } -} - -/* see inner.h */ -unsigned -br_des_tab_keysched(uint32_t *skey, const void *key, size_t key_len) -{ - switch (key_len) { - case 8: - keysched_unit(skey, key); - return 1; - case 16: - keysched_unit(skey, key); - keysched_unit(skey + 32, (const unsigned char *)key + 8); - br_des_rev_skey(skey + 32); - memcpy(skey + 64, skey, 32 * sizeof *skey); - return 3; - default: - keysched_unit(skey, key); - keysched_unit(skey + 32, (const unsigned char *)key + 8); - br_des_rev_skey(skey + 32); - keysched_unit(skey + 64, (const unsigned char *)key + 16); - return 3; - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/des_tab_cbcdec.c b/src/tls/bearssl/des_tab_cbcdec.c deleted file mode 100644 index f7d3e3064..000000000 --- a/src/tls/bearssl/des_tab_cbcdec.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_block.h */ -void -br_des_tab_cbcdec_init(br_des_tab_cbcdec_keys *ctx, - const void *key, size_t len) -{ - ctx->vtable = &br_des_tab_cbcdec_vtable; - ctx->num_rounds = br_des_tab_keysched(ctx->skey, key, len); - if (len == 8) { - br_des_rev_skey(ctx->skey); - } else { - int i; - - for (i = 0; i < 48; i += 2) { - uint32_t t; - - t = ctx->skey[i]; - ctx->skey[i] = ctx->skey[94 - i]; - ctx->skey[94 - i] = t; - t = ctx->skey[i + 1]; - ctx->skey[i + 1] = ctx->skey[95 - i]; - ctx->skey[95 - i] = t; - } - } -} - -/* see bearssl_block.h */ -void -br_des_tab_cbcdec_run(const br_des_tab_cbcdec_keys *ctx, - void *iv, void *data, size_t len) -{ - unsigned char *buf, *ivbuf; - - ivbuf = iv; - buf = data; - while (len > 0) { - unsigned char tmp[8]; - int i; - - memcpy(tmp, buf, 8); - br_des_tab_process_block(ctx->num_rounds, ctx->skey, buf); - for (i = 0; i < 8; i ++) { - buf[i] ^= ivbuf[i]; - } - memcpy(ivbuf, tmp, 8); - buf += 8; - len -= 8; - } -} - -/* see bearssl_block.h */ -const br_block_cbcdec_class br_des_tab_cbcdec_vtable = { - sizeof(br_des_tab_cbcdec_keys), - 8, - 3, - (void (*)(const br_block_cbcdec_class **, const void *, size_t)) - &br_des_tab_cbcdec_init, - (void (*)(const br_block_cbcdec_class *const *, void *, void *, size_t)) - &br_des_tab_cbcdec_run -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/des_tab_cbcenc.c b/src/tls/bearssl/des_tab_cbcenc.c deleted file mode 100644 index e1a3359c2..000000000 --- a/src/tls/bearssl/des_tab_cbcenc.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_block.h */ -void -br_des_tab_cbcenc_init(br_des_tab_cbcenc_keys *ctx, - const void *key, size_t len) -{ - ctx->vtable = &br_des_tab_cbcenc_vtable; - ctx->num_rounds = br_des_tab_keysched(ctx->skey, key, len); -} - -/* see bearssl_block.h */ -void -br_des_tab_cbcenc_run(const br_des_tab_cbcenc_keys *ctx, - void *iv, void *data, size_t len) -{ - unsigned char *buf, *ivbuf; - - ivbuf = iv; - buf = data; - while (len > 0) { - int i; - - for (i = 0; i < 8; i ++) { - buf[i] ^= ivbuf[i]; - } - br_des_tab_process_block(ctx->num_rounds, ctx->skey, buf); - memcpy(ivbuf, buf, 8); - buf += 8; - len -= 8; - } -} - -/* see bearssl_block.h */ -const br_block_cbcenc_class br_des_tab_cbcenc_vtable = { - sizeof(br_des_tab_cbcenc_keys), - 8, - 3, - (void (*)(const br_block_cbcenc_class **, const void *, size_t)) - &br_des_tab_cbcenc_init, - (void (*)(const br_block_cbcenc_class *const *, void *, void *, size_t)) - &br_des_tab_cbcenc_run -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/dig_oid.c b/src/tls/bearssl/dig_oid.c deleted file mode 100644 index 85be00106..000000000 --- a/src/tls/bearssl/dig_oid.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * This file contains the encoded OID for the standard hash functions. - * Such OID appear in, for instance, the PKCS#1 v1.5 padding for RSA - * signatures. - */ - -static const unsigned char md5_OID[] = { - 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05 -}; - -static const unsigned char sha1_OID[] = { - 0x2B, 0x0E, 0x03, 0x02, 0x1A -}; - -static const unsigned char sha224_OID[] = { - 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04 -}; - -static const unsigned char sha256_OID[] = { - 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01 -}; - -static const unsigned char sha384_OID[] = { - 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02 -}; - -static const unsigned char sha512_OID[] = { - 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03 -}; - -/* see inner.h */ -const unsigned char * -br_digest_OID(int digest_id, size_t *len) -{ - switch (digest_id) { - case br_md5_ID: - *len = sizeof md5_OID; - return md5_OID; - case br_sha1_ID: - *len = sizeof sha1_OID; - return sha1_OID; - case br_sha224_ID: - *len = sizeof sha224_OID; - return sha224_OID; - case br_sha256_ID: - *len = sizeof sha256_OID; - return sha256_OID; - case br_sha384_ID: - *len = sizeof sha384_OID; - return sha384_OID; - case br_sha512_ID: - *len = sizeof sha512_OID; - return sha512_OID; - default: - *len = 0; - return NULL; - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/dig_size.c b/src/tls/bearssl/dig_size.c deleted file mode 100644 index 40de304a2..000000000 --- a/src/tls/bearssl/dig_size.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -size_t -br_digest_size_by_ID(int digest_id) -{ - switch (digest_id) { - case br_md5sha1_ID: - return br_md5_SIZE + br_sha1_SIZE; - case br_md5_ID: - return br_md5_SIZE; - case br_sha1_ID: - return br_sha1_SIZE; - case br_sha224_ID: - return br_sha224_SIZE; - case br_sha256_ID: - return br_sha256_SIZE; - case br_sha384_ID: - return br_sha384_SIZE; - case br_sha512_ID: - return br_sha512_SIZE; - default: - /* abort(); */ - return 0; - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/eax.c b/src/tls/bearssl/eax.c deleted file mode 100644 index fcd20012d..000000000 --- a/src/tls/bearssl/eax.c +++ /dev/null @@ -1,530 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * Implementation Notes - * ==================== - * - * The combined CTR + CBC-MAC functions can only handle full blocks, - * so some buffering is necessary. Moreover, EAX has a special padding - * rule for CBC-MAC, which implies that we cannot compute the MAC over - * the last received full block until we know whether we are at the - * end of the data or not. - * - * - 'ptr' contains a value from 1 to 16, which is the number of bytes - * accumulated in buf[] that still needs to be processed with the - * current OMAC computation. Beware that this can go to 16: a - * complete block cannot be processed until it is known whether it - * is the last block or not. However, it can never be 0, because - * OMAC^t works on an input that is at least one-block long. - * - * - When processing the message itself, CTR encryption/decryption is - * also done at the same time. The first 'ptr' bytes of buf[] then - * contains the encrypted bytes, while the last '16 - ptr' bytes of - * buf[] are the remnants of the stream block, to be used against - * the next input bytes, when available. - * - * - The current counter and running CBC-MAC values are kept in 'ctr' - * and 'cbcmac', respectively. - * - * - The derived keys for padding are kept in L2 and L4 (double and - * quadruple of Enc_K(0^n), in GF(2^128), respectively). - */ - -/* - * Start an OMAC computation; the first block is the big-endian - * representation of the provided value ('val' must fit on one byte). - * We make it a delayed block because it may also be the last one, - */ -static void -omac_start(br_eax_context *ctx, unsigned val) -{ - memset(ctx->cbcmac, 0, sizeof ctx->cbcmac); - memset(ctx->buf, 0, sizeof ctx->buf); - ctx->buf[15] = val; - ctx->ptr = 16; -} - -/* - * Double a value in finite field GF(2^128), defined with modulus - * X^128+X^7+X^2+X+1. - */ -static void -double_gf128(unsigned char *dst, const unsigned char *src) -{ - unsigned cc; - int i; - - cc = 0x87 & -((unsigned)src[0] >> 7); - for (i = 15; i >= 0; i --) { - unsigned z; - - z = (src[i] << 1) ^ cc; - cc = z >> 8; - dst[i] = (unsigned char)z; - } -} - -/* - * Apply padding to the last block, currently in ctx->buf (with - * ctx->ptr bytes), and finalize OMAC computation. - */ -static void -do_pad(br_eax_context *ctx) -{ - unsigned char *pad; - size_t ptr, u; - - ptr = ctx->ptr; - if (ptr == 16) { - pad = ctx->L2; - } else { - ctx->buf[ptr ++] = 0x80; - memset(ctx->buf + ptr, 0x00, 16 - ptr); - pad = ctx->L4; - } - for (u = 0; u < sizeof ctx->buf; u ++) { - ctx->buf[u] ^= pad[u]; - } - (*ctx->bctx)->mac(ctx->bctx, ctx->cbcmac, ctx->buf, sizeof ctx->buf); -} - -/* - * Apply CBC-MAC on the provided data, with buffering management. - * - * Upon entry, two situations are acceptable: - * - * ctx->ptr == 0: there is no data to process in ctx->buf - * ctx->ptr == 16: there is a full block of unprocessed data in ctx->buf - * - * Upon exit, ctx->ptr may be zero only if it was already zero on entry, - * and len == 0. In all other situations, ctx->ptr will be non-zero on - * exit (and may have value 16). - */ -static void -do_cbcmac_chunk(br_eax_context *ctx, const void *data, size_t len) -{ - size_t ptr; - - if (len == 0) { - return; - } - ptr = len & (size_t)15; - if (ptr == 0) { - len -= 16; - ptr = 16; - } else { - len -= ptr; - } - if (ctx->ptr == 16) { - (*ctx->bctx)->mac(ctx->bctx, ctx->cbcmac, - ctx->buf, sizeof ctx->buf); - } - (*ctx->bctx)->mac(ctx->bctx, ctx->cbcmac, data, len); - memcpy(ctx->buf, (const unsigned char *)data + len, ptr); - ctx->ptr = ptr; -} - -/* see bearssl_aead.h */ -void -br_eax_init(br_eax_context *ctx, const br_block_ctrcbc_class **bctx) -{ - unsigned char tmp[16], iv[16]; - - ctx->vtable = &br_eax_vtable; - ctx->bctx = bctx; - - /* - * Encrypt a whole-zero block to compute L2 and L4. - */ - memset(tmp, 0, sizeof tmp); - memset(iv, 0, sizeof iv); - (*bctx)->ctr(bctx, iv, tmp, sizeof tmp); - double_gf128(ctx->L2, tmp); - double_gf128(ctx->L4, ctx->L2); -} - -/* see bearssl_aead.h */ -void -br_eax_capture(const br_eax_context *ctx, br_eax_state *st) -{ - /* - * We capture the three OMAC* states _after_ processing the - * initial block (assuming that nonce, message and AAD are - * all non-empty). - */ - int i; - - memset(st->st, 0, sizeof st->st); - for (i = 0; i < 3; i ++) { - unsigned char tmp[16]; - - memset(tmp, 0, sizeof tmp); - tmp[15] = (unsigned char)i; - (*ctx->bctx)->mac(ctx->bctx, st->st[i], tmp, sizeof tmp); - } -} - -/* see bearssl_aead.h */ -void -br_eax_reset(br_eax_context *ctx, const void *nonce, size_t len) -{ - /* - * Process nonce with OMAC^0. - */ - omac_start(ctx, 0); - do_cbcmac_chunk(ctx, nonce, len); - do_pad(ctx); - memcpy(ctx->nonce, ctx->cbcmac, sizeof ctx->cbcmac); - - /* - * Start OMAC^1 for the AAD ("header" in the EAX specification). - */ - omac_start(ctx, 1); - - /* - * We use ctx->head[0] as temporary flag to mark that we are - * using a "normal" reset(). - */ - ctx->head[0] = 0; -} - -/* see bearssl_aead.h */ -void -br_eax_reset_pre_aad(br_eax_context *ctx, const br_eax_state *st, - const void *nonce, size_t len) -{ - if (len == 0) { - omac_start(ctx, 0); - } else { - memcpy(ctx->cbcmac, st->st[0], sizeof ctx->cbcmac); - ctx->ptr = 0; - do_cbcmac_chunk(ctx, nonce, len); - } - do_pad(ctx); - memcpy(ctx->nonce, ctx->cbcmac, sizeof ctx->cbcmac); - - memcpy(ctx->cbcmac, st->st[1], sizeof ctx->cbcmac); - ctx->ptr = 0; - - memcpy(ctx->ctr, st->st[2], sizeof ctx->ctr); - - /* - * We use ctx->head[0] as a flag to indicate that we use a - * a recorded state, with ctx->ctr containing the preprocessed - * first block for OMAC^2. - */ - ctx->head[0] = 1; -} - -/* see bearssl_aead.h */ -void -br_eax_reset_post_aad(br_eax_context *ctx, const br_eax_state *st, - const void *nonce, size_t len) -{ - if (len == 0) { - omac_start(ctx, 0); - } else { - memcpy(ctx->cbcmac, st->st[0], sizeof ctx->cbcmac); - ctx->ptr = 0; - do_cbcmac_chunk(ctx, nonce, len); - } - do_pad(ctx); - memcpy(ctx->nonce, ctx->cbcmac, sizeof ctx->cbcmac); - memcpy(ctx->ctr, ctx->nonce, sizeof ctx->nonce); - - memcpy(ctx->head, st->st[1], sizeof ctx->head); - - memcpy(ctx->cbcmac, st->st[2], sizeof ctx->cbcmac); - ctx->ptr = 0; -} - -/* see bearssl_aead.h */ -void -br_eax_aad_inject(br_eax_context *ctx, const void *data, size_t len) -{ - size_t ptr; - - ptr = ctx->ptr; - - /* - * If there is a partial block, first complete it. - */ - if (ptr < 16) { - size_t clen; - - clen = 16 - ptr; - if (len <= clen) { - memcpy(ctx->buf + ptr, data, len); - ctx->ptr = ptr + len; - return; - } - memcpy(ctx->buf + ptr, data, clen); - data = (const unsigned char *)data + clen; - len -= clen; - } - - /* - * We now have a full block in buf[], and this is not the last - * block. - */ - do_cbcmac_chunk(ctx, data, len); -} - -/* see bearssl_aead.h */ -void -br_eax_flip(br_eax_context *ctx) -{ - int from_capture; - - /* - * ctx->head[0] may be non-zero if the context was reset with - * a pre-AAD captured state. In that case, ctx->ctr[] contains - * the state for OMAC^2 _after_ processing the first block. - */ - from_capture = ctx->head[0]; - - /* - * Complete the OMAC computation on the AAD. - */ - do_pad(ctx); - memcpy(ctx->head, ctx->cbcmac, sizeof ctx->cbcmac); - - /* - * Start OMAC^2 for the encrypted data. - * If the context was initialized from a captured state, then - * the OMAC^2 value is in the ctr[] array. - */ - if (from_capture) { - memcpy(ctx->cbcmac, ctx->ctr, sizeof ctx->cbcmac); - ctx->ptr = 0; - } else { - omac_start(ctx, 2); - } - - /* - * Initial counter value for CTR is the processed nonce. - */ - memcpy(ctx->ctr, ctx->nonce, sizeof ctx->nonce); -} - -/* see bearssl_aead.h */ -void -br_eax_run(br_eax_context *ctx, int encrypt, void *data, size_t len) -{ - unsigned char *dbuf; - size_t ptr; - - /* - * Ensure that there is actual data to process. - */ - if (len == 0) { - return; - } - - dbuf = data; - ptr = ctx->ptr; - - /* - * We may have ptr == 0 here if we initialized from a captured - * state. In that case, there is no partially consumed block - * or unprocessed data. - */ - if (ptr != 0 && ptr != 16) { - /* - * We have a partially consumed block. - */ - size_t u, clen; - - clen = 16 - ptr; - if (len <= clen) { - clen = len; - } - if (encrypt) { - for (u = 0; u < clen; u ++) { - ctx->buf[ptr + u] ^= dbuf[u]; - } - memcpy(dbuf, ctx->buf + ptr, clen); - } else { - for (u = 0; u < clen; u ++) { - unsigned dx, sx; - - sx = ctx->buf[ptr + u]; - dx = dbuf[u]; - ctx->buf[ptr + u] = dx; - dbuf[u] = sx ^ dx; - } - } - - if (len <= clen) { - ctx->ptr = ptr + clen; - return; - } - dbuf += clen; - len -= clen; - } - - /* - * We now have a complete encrypted block in buf[] that must still - * be processed with OMAC, and this is not the final buf. - * Exception: when ptr == 0, no block has been produced yet. - */ - if (ptr != 0) { - (*ctx->bctx)->mac(ctx->bctx, ctx->cbcmac, - ctx->buf, sizeof ctx->buf); - } - - /* - * Do CTR encryption or decryption and CBC-MAC for all full blocks - * except the last. - */ - ptr = len & (size_t)15; - if (ptr == 0) { - len -= 16; - ptr = 16; - } else { - len -= ptr; - } - if (encrypt) { - (*ctx->bctx)->encrypt(ctx->bctx, ctx->ctr, ctx->cbcmac, - dbuf, len); - } else { - (*ctx->bctx)->decrypt(ctx->bctx, ctx->ctr, ctx->cbcmac, - dbuf, len); - } - dbuf += len; - - /* - * Compute next block of CTR stream, and use it to finish - * encrypting or decrypting the data. - */ - memset(ctx->buf, 0, sizeof ctx->buf); - (*ctx->bctx)->ctr(ctx->bctx, ctx->ctr, ctx->buf, sizeof ctx->buf); - if (encrypt) { - size_t u; - - for (u = 0; u < ptr; u ++) { - ctx->buf[u] ^= dbuf[u]; - } - memcpy(dbuf, ctx->buf, ptr); - } else { - size_t u; - - for (u = 0; u < ptr; u ++) { - unsigned dx, sx; - - sx = ctx->buf[u]; - dx = dbuf[u]; - ctx->buf[u] = dx; - dbuf[u] = sx ^ dx; - } - } - ctx->ptr = ptr; -} - -/* - * Complete tag computation. The final tag is written in ctx->cbcmac. - */ -static void -do_final(br_eax_context *ctx) -{ - size_t u; - - do_pad(ctx); - - /* - * Authentication tag is the XOR of the three OMAC outputs for - * the nonce, AAD and encrypted data. - */ - for (u = 0; u < 16; u ++) { - ctx->cbcmac[u] ^= ctx->nonce[u] ^ ctx->head[u]; - } -} - -/* see bearssl_aead.h */ -void -br_eax_get_tag(br_eax_context *ctx, void *tag) -{ - do_final(ctx); - memcpy(tag, ctx->cbcmac, sizeof ctx->cbcmac); -} - -/* see bearssl_aead.h */ -void -br_eax_get_tag_trunc(br_eax_context *ctx, void *tag, size_t len) -{ - do_final(ctx); - memcpy(tag, ctx->cbcmac, len); -} - -/* see bearssl_aead.h */ -uint32_t -br_eax_check_tag_trunc(br_eax_context *ctx, const void *tag, size_t len) -{ - unsigned char tmp[16]; - size_t u; - int x; - - br_eax_get_tag(ctx, tmp); - x = 0; - for (u = 0; u < len; u ++) { - x |= tmp[u] ^ ((const unsigned char *)tag)[u]; - } - return EQ0(x); -} - -/* see bearssl_aead.h */ -uint32_t -br_eax_check_tag(br_eax_context *ctx, const void *tag) -{ - return br_eax_check_tag_trunc(ctx, tag, 16); -} - -/* see bearssl_aead.h */ -const br_aead_class br_eax_vtable = { - 16, - (void (*)(const br_aead_class **, const void *, size_t)) - &br_eax_reset, - (void (*)(const br_aead_class **, const void *, size_t)) - &br_eax_aad_inject, - (void (*)(const br_aead_class **)) - &br_eax_flip, - (void (*)(const br_aead_class **, int, void *, size_t)) - &br_eax_run, - (void (*)(const br_aead_class **, void *)) - &br_eax_get_tag, - (uint32_t (*)(const br_aead_class **, const void *)) - &br_eax_check_tag, - (void (*)(const br_aead_class **, void *, size_t)) - &br_eax_get_tag_trunc, - (uint32_t (*)(const br_aead_class **, const void *, size_t)) - &br_eax_check_tag_trunc -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ec_all_m15.c b/src/tls/bearssl/ec_all_m15.c deleted file mode 100644 index dea4e6b0d..000000000 --- a/src/tls/bearssl/ec_all_m15.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -static const unsigned char * -api_generator(int curve, size_t *len) -{ - switch (curve) { - case BR_EC_secp256r1: - return br_ec_p256_m15.generator(curve, len); - case BR_EC_curve25519: - return br_ec_c25519_m15.generator(curve, len); - default: - return br_ec_prime_i15.generator(curve, len); - } -} - -static const unsigned char * -api_order(int curve, size_t *len) -{ - switch (curve) { - case BR_EC_secp256r1: - return br_ec_p256_m15.order(curve, len); - case BR_EC_curve25519: - return br_ec_c25519_m15.order(curve, len); - default: - return br_ec_prime_i15.order(curve, len); - } -} - -static size_t -api_xoff(int curve, size_t *len) -{ - switch (curve) { - case BR_EC_secp256r1: - return br_ec_p256_m15.xoff(curve, len); - case BR_EC_curve25519: - return br_ec_c25519_m15.xoff(curve, len); - default: - return br_ec_prime_i15.xoff(curve, len); - } -} - -static uint32_t -api_mul(unsigned char *G, size_t Glen, - const unsigned char *kb, size_t kblen, int curve) -{ - switch (curve) { - case BR_EC_secp256r1: - return br_ec_p256_m15.mul(G, Glen, kb, kblen, curve); - case BR_EC_curve25519: - return br_ec_c25519_m15.mul(G, Glen, kb, kblen, curve); - default: - return br_ec_prime_i15.mul(G, Glen, kb, kblen, curve); - } -} - -static size_t -api_mulgen(unsigned char *R, - const unsigned char *x, size_t xlen, int curve) -{ - switch (curve) { - case BR_EC_secp256r1: - return br_ec_p256_m15.mulgen(R, x, xlen, curve); - case BR_EC_curve25519: - return br_ec_c25519_m15.mulgen(R, x, xlen, curve); - default: - return br_ec_prime_i15.mulgen(R, x, xlen, curve); - } -} - -static uint32_t -api_muladd(unsigned char *A, const unsigned char *B, size_t len, - const unsigned char *x, size_t xlen, - const unsigned char *y, size_t ylen, int curve) -{ - switch (curve) { - case BR_EC_secp256r1: - return br_ec_p256_m15.muladd(A, B, len, - x, xlen, y, ylen, curve); - case BR_EC_curve25519: - return br_ec_c25519_m15.muladd(A, B, len, - x, xlen, y, ylen, curve); - default: - return br_ec_prime_i15.muladd(A, B, len, - x, xlen, y, ylen, curve); - } -} - -/* see bearssl_ec.h */ -const br_ec_impl br_ec_all_m15 = { - (uint32_t)0x23800000, - &api_generator, - &api_order, - &api_xoff, - &api_mul, - &api_mulgen, - &api_muladd -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ec_all_m31.c b/src/tls/bearssl/ec_all_m31.c deleted file mode 100644 index 66168c27d..000000000 --- a/src/tls/bearssl/ec_all_m31.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -static const unsigned char * -api_generator(int curve, size_t *len) -{ - switch (curve) { - case BR_EC_secp256r1: - return br_ec_p256_m31.generator(curve, len); - case BR_EC_curve25519: - return br_ec_c25519_m31.generator(curve, len); - default: - return br_ec_prime_i31.generator(curve, len); - } -} - -static const unsigned char * -api_order(int curve, size_t *len) -{ - switch (curve) { - case BR_EC_secp256r1: - return br_ec_p256_m31.order(curve, len); - case BR_EC_curve25519: - return br_ec_c25519_m31.order(curve, len); - default: - return br_ec_prime_i31.order(curve, len); - } -} - -static size_t -api_xoff(int curve, size_t *len) -{ - switch (curve) { - case BR_EC_secp256r1: - return br_ec_p256_m31.xoff(curve, len); - case BR_EC_curve25519: - return br_ec_c25519_m31.xoff(curve, len); - default: - return br_ec_prime_i31.xoff(curve, len); - } -} - -static uint32_t -api_mul(unsigned char *G, size_t Glen, - const unsigned char *kb, size_t kblen, int curve) -{ - switch (curve) { - case BR_EC_secp256r1: - return br_ec_p256_m31.mul(G, Glen, kb, kblen, curve); - case BR_EC_curve25519: - return br_ec_c25519_m31.mul(G, Glen, kb, kblen, curve); - default: - return br_ec_prime_i31.mul(G, Glen, kb, kblen, curve); - } -} - -static size_t -api_mulgen(unsigned char *R, - const unsigned char *x, size_t xlen, int curve) -{ - switch (curve) { - case BR_EC_secp256r1: - return br_ec_p256_m31.mulgen(R, x, xlen, curve); - case BR_EC_curve25519: - return br_ec_c25519_m31.mulgen(R, x, xlen, curve); - default: - return br_ec_prime_i31.mulgen(R, x, xlen, curve); - } -} - -static uint32_t -api_muladd(unsigned char *A, const unsigned char *B, size_t len, - const unsigned char *x, size_t xlen, - const unsigned char *y, size_t ylen, int curve) -{ - switch (curve) { - case BR_EC_secp256r1: - return br_ec_p256_m31.muladd(A, B, len, - x, xlen, y, ylen, curve); - case BR_EC_curve25519: - return br_ec_c25519_m31.muladd(A, B, len, - x, xlen, y, ylen, curve); - default: - return br_ec_prime_i31.muladd(A, B, len, - x, xlen, y, ylen, curve); - } -} - -/* see bearssl_ec.h */ -const br_ec_impl br_ec_all_m31 = { - (uint32_t)0x23800000, - &api_generator, - &api_order, - &api_xoff, - &api_mul, - &api_mulgen, - &api_muladd -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ec_c25519_i15.c b/src/tls/bearssl/ec_c25519_i15.c deleted file mode 100644 index 68ca1fda6..000000000 --- a/src/tls/bearssl/ec_c25519_i15.c +++ /dev/null @@ -1,403 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * Parameters for the field: - * - field modulus p = 2^255-19 - * - R^2 mod p (R = 2^(15k) for the smallest k such that R >= p) - */ - -static const uint16_t C255_P[] = { - 0x0110, - 0x7FED, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, - 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, - 0x7FFF -}; - -#define P0I 0x4A1B - -static const uint16_t C255_R2[] = { - 0x0110, - 0x0169, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000 -}; - -/* obsolete -#include -#include -static void -print_int_mont(const char *name, const uint16_t *x) -{ - uint16_t y[18]; - unsigned char tmp[32]; - size_t u; - - printf("%s = ", name); - memcpy(y, x, sizeof y); - br_i15_from_monty(y, C255_P, P0I); - br_i15_encode(tmp, sizeof tmp, y); - for (u = 0; u < sizeof tmp; u ++) { - printf("%02X", tmp[u]); - } - printf("\n"); -} -*/ - -static const uint16_t C255_A24[] = { - 0x0110, - 0x45D3, 0x0046, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000 -}; - -static const unsigned char GEN[] = { - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -static const unsigned char ORDER[] = { - 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF -}; - -static const unsigned char * -api_generator(int curve, size_t *len) -{ - (void)curve; - *len = 32; - return GEN; -} - -static const unsigned char * -api_order(int curve, size_t *len) -{ - (void)curve; - *len = 32; - return ORDER; -} - -static size_t -api_xoff(int curve, size_t *len) -{ - (void)curve; - *len = 32; - return 0; -} - -static void -cswap(uint16_t *a, uint16_t *b, uint32_t ctl) -{ - int i; - - ctl = -ctl; - for (i = 0; i < 18; i ++) { - uint32_t aw, bw, tw; - - aw = a[i]; - bw = b[i]; - tw = ctl & (aw ^ bw); - a[i] = aw ^ tw; - b[i] = bw ^ tw; - } -} - -static void -c255_add(uint16_t *d, const uint16_t *a, const uint16_t *b) -{ - uint32_t ctl; - uint16_t t[18]; - - memcpy(t, a, sizeof t); - ctl = br_i15_add(t, b, 1); - ctl |= NOT(br_i15_sub(t, C255_P, 0)); - br_i15_sub(t, C255_P, ctl); - memcpy(d, t, sizeof t); -} - -static void -c255_sub(uint16_t *d, const uint16_t *a, const uint16_t *b) -{ - uint16_t t[18]; - - memcpy(t, a, sizeof t); - br_i15_add(t, C255_P, br_i15_sub(t, b, 1)); - memcpy(d, t, sizeof t); -} - -static void -c255_mul(uint16_t *d, const uint16_t *a, const uint16_t *b) -{ - uint16_t t[18]; - - br_i15_montymul(t, a, b, C255_P, P0I); - memcpy(d, t, sizeof t); -} - -static void -byteswap(unsigned char *G) -{ - int i; - - for (i = 0; i < 16; i ++) { - unsigned char t; - - t = G[i]; - G[i] = G[31 - i]; - G[31 - i] = t; - } -} - -static uint32_t -api_mul(unsigned char *G, size_t Glen, - const unsigned char *kb, size_t kblen, int curve) -{ -#define ILEN (18 * sizeof(uint16_t)) - - /* - * The a[] and b[] arrays have an extra word to allow for - * decoding without using br_i15_decode_reduce(). - */ - uint16_t x1[18], x2[18], x3[18], z2[18], z3[18]; - uint16_t a[19], aa[18], b[19], bb[18]; - uint16_t c[18], d[18], e[18], da[18], cb[18]; - unsigned char k[32]; - uint32_t swap; - int i; - - (void)curve; - - /* - * Points are encoded over exactly 32 bytes. Multipliers must fit - * in 32 bytes as well. - * RFC 7748 mandates that the high bit of the last point byte must - * be ignored/cleared. - */ - if (Glen != 32 || kblen > 32) { - return 0; - } - G[31] &= 0x7F; - - /* - * Byteswap the point encoding, because it uses little-endian, and - * the generic decoding routine uses big-endian. - */ - byteswap(G); - - /* - * Decode the point ('u' coordinate). This should be reduced - * modulo p, but we prefer to avoid the dependency on - * br_i15_decode_reduce(). Instead, we use br_i15_decode_mod() - * with a synthetic modulus of value 2^255 (this must work - * since G was truncated to 255 bits), then use a conditional - * subtraction. We use br_i15_decode_mod() and not - * br_i15_decode(), because the ec_prime_i15 implementation uses - * the former but not the latter. - * br_i15_decode_reduce(a, G, 32, C255_P); - */ - br_i15_zero(b, 0x111); - b[18] = 1; - br_i15_decode_mod(a, G, 32, b); - a[0] = 0x110; - br_i15_sub(a, C255_P, NOT(br_i15_sub(a, C255_P, 0))); - - /* - * Initialise variables x1, x2, z2, x3 and z3. We set all of them - * into Montgomery representation. - */ - br_i15_montymul(x1, a, C255_R2, C255_P, P0I); - memcpy(x3, x1, ILEN); - br_i15_zero(z2, C255_P[0]); - memcpy(x2, z2, ILEN); - x2[1] = 19; - memcpy(z3, x2, ILEN); - - memcpy(k, kb, kblen); - memset(k + kblen, 0, (sizeof k) - kblen); - k[0] &= 0xF8; - k[31] &= 0x7F; - k[31] |= 0x40; - - /* obsolete - print_int_mont("x1", x1); - */ - - swap = 0; - for (i = 254; i >= 0; i --) { - uint32_t kt; - - kt = (k[i >> 3] >> (i & 7)) & 1; - swap ^= kt; - cswap(x2, x3, swap); - cswap(z2, z3, swap); - swap = kt; - - /* obsolete - print_int_mont("x2", x2); - print_int_mont("z2", z2); - print_int_mont("x3", x3); - print_int_mont("z3", z3); - */ - - c255_add(a, x2, z2); - c255_mul(aa, a, a); - c255_sub(b, x2, z2); - c255_mul(bb, b, b); - c255_sub(e, aa, bb); - c255_add(c, x3, z3); - c255_sub(d, x3, z3); - c255_mul(da, d, a); - c255_mul(cb, c, b); - - /* obsolete - print_int_mont("a ", a); - print_int_mont("aa", aa); - print_int_mont("b ", b); - print_int_mont("bb", bb); - print_int_mont("e ", e); - print_int_mont("c ", c); - print_int_mont("d ", d); - print_int_mont("da", da); - print_int_mont("cb", cb); - */ - - c255_add(x3, da, cb); - c255_mul(x3, x3, x3); - c255_sub(z3, da, cb); - c255_mul(z3, z3, z3); - c255_mul(z3, z3, x1); - c255_mul(x2, aa, bb); - c255_mul(z2, C255_A24, e); - c255_add(z2, z2, aa); - c255_mul(z2, e, z2); - - /* obsolete - print_int_mont("x2", x2); - print_int_mont("z2", z2); - print_int_mont("x3", x3); - print_int_mont("z3", z3); - */ - } - cswap(x2, x3, swap); - cswap(z2, z3, swap); - - /* - * Inverse z2 with a modular exponentiation. This is a simple - * square-and-multiply algorithm; we mutualise most non-squarings - * since the exponent contains almost only ones. - */ - memcpy(a, z2, ILEN); - for (i = 0; i < 15; i ++) { - c255_mul(a, a, a); - c255_mul(a, a, z2); - } - memcpy(b, a, ILEN); - for (i = 0; i < 14; i ++) { - int j; - - for (j = 0; j < 16; j ++) { - c255_mul(b, b, b); - } - c255_mul(b, b, a); - } - for (i = 14; i >= 0; i --) { - c255_mul(b, b, b); - if ((0xFFEB >> i) & 1) { - c255_mul(b, z2, b); - } - } - c255_mul(b, x2, b); - - /* - * To avoid a dependency on br_i15_from_monty(), we use a - * Montgomery multiplication with 1. - * memcpy(x2, b, ILEN); - * br_i15_from_monty(x2, C255_P, P0I); - */ - br_i15_zero(a, C255_P[0]); - a[1] = 1; - br_i15_montymul(x2, a, b, C255_P, P0I); - - br_i15_encode(G, 32, x2); - byteswap(G); - return 1; - -#undef ILEN -} - -static size_t -api_mulgen(unsigned char *R, - const unsigned char *x, size_t xlen, int curve) -{ - const unsigned char *G; - size_t Glen; - - G = api_generator(curve, &Glen); - memcpy(R, G, Glen); - api_mul(R, Glen, x, xlen, curve); - return Glen; -} - -static uint32_t -api_muladd(unsigned char *A, const unsigned char *B, size_t len, - const unsigned char *x, size_t xlen, - const unsigned char *y, size_t ylen, int curve) -{ - /* - * We don't implement this method, since it is used for ECDSA - * only, and there is no ECDSA over Curve25519 (which instead - * uses EdDSA). - */ - (void)A; - (void)B; - (void)len; - (void)x; - (void)xlen; - (void)y; - (void)ylen; - (void)curve; - return 0; -} - -/* see bearssl_ec.h */ -const br_ec_impl br_ec_c25519_i15 = { - (uint32_t)0x20000000, - &api_generator, - &api_order, - &api_xoff, - &api_mul, - &api_mulgen, - &api_muladd -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ec_c25519_i31.c b/src/tls/bearssl/ec_c25519_i31.c deleted file mode 100644 index 47451d38a..000000000 --- a/src/tls/bearssl/ec_c25519_i31.c +++ /dev/null @@ -1,392 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * Parameters for the field: - * - field modulus p = 2^255-19 - * - R^2 mod p (R = 2^(31k) for the smallest k such that R >= p) - */ - -static const uint32_t C255_P[] = { - 0x00000107, - 0x7FFFFFED, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, - 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x0000007F -}; - -#define P0I 0x286BCA1B - -static const uint32_t C255_R2[] = { - 0x00000107, - 0x00000000, 0x02D20000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000 -}; - -static const uint32_t C255_A24[] = { - 0x00000107, - 0x53000000, 0x0000468B, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000 -}; - -/* obsolete -#include -#include -static void -print_int_mont(const char *name, const uint32_t *x) -{ - uint32_t y[10]; - unsigned char tmp[32]; - size_t u; - - printf("%s = ", name); - memcpy(y, x, sizeof y); - br_i31_from_monty(y, C255_P, P0I); - br_i31_encode(tmp, sizeof tmp, y); - for (u = 0; u < sizeof tmp; u ++) { - printf("%02X", tmp[u]); - } - printf("\n"); -} -*/ - -static const unsigned char GEN[] = { - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -static const unsigned char ORDER[] = { - 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF -}; - -static const unsigned char * -api_generator(int curve, size_t *len) -{ - (void)curve; - *len = 32; - return GEN; -} - -static const unsigned char * -api_order(int curve, size_t *len) -{ - (void)curve; - *len = 32; - return ORDER; -} - -static size_t -api_xoff(int curve, size_t *len) -{ - (void)curve; - *len = 32; - return 0; -} - -static void -cswap(uint32_t *a, uint32_t *b, uint32_t ctl) -{ - int i; - - ctl = -ctl; - for (i = 0; i < 10; i ++) { - uint32_t aw, bw, tw; - - aw = a[i]; - bw = b[i]; - tw = ctl & (aw ^ bw); - a[i] = aw ^ tw; - b[i] = bw ^ tw; - } -} - -static void -c255_add(uint32_t *d, const uint32_t *a, const uint32_t *b) -{ - uint32_t ctl; - uint32_t t[10]; - - memcpy(t, a, sizeof t); - ctl = br_i31_add(t, b, 1); - ctl |= NOT(br_i31_sub(t, C255_P, 0)); - br_i31_sub(t, C255_P, ctl); - memcpy(d, t, sizeof t); -} - -static void -c255_sub(uint32_t *d, const uint32_t *a, const uint32_t *b) -{ - uint32_t t[10]; - - memcpy(t, a, sizeof t); - br_i31_add(t, C255_P, br_i31_sub(t, b, 1)); - memcpy(d, t, sizeof t); -} - -static void -c255_mul(uint32_t *d, const uint32_t *a, const uint32_t *b) -{ - uint32_t t[10]; - - br_i31_montymul(t, a, b, C255_P, P0I); - memcpy(d, t, sizeof t); -} - -static void -byteswap(unsigned char *G) -{ - int i; - - for (i = 0; i < 16; i ++) { - unsigned char t; - - t = G[i]; - G[i] = G[31 - i]; - G[31 - i] = t; - } -} - -static uint32_t -api_mul(unsigned char *G, size_t Glen, - const unsigned char *kb, size_t kblen, int curve) -{ - uint32_t x1[10], x2[10], x3[10], z2[10], z3[10]; - uint32_t a[10], aa[10], b[10], bb[10]; - uint32_t c[10], d[10], e[10], da[10], cb[10]; - unsigned char k[32]; - uint32_t swap; - int i; - - (void)curve; - - /* - * Points are encoded over exactly 32 bytes. Multipliers must fit - * in 32 bytes as well. - * RFC 7748 mandates that the high bit of the last point byte must - * be ignored/cleared. - */ - if (Glen != 32 || kblen > 32) { - return 0; - } - G[31] &= 0x7F; - - /* - * Byteswap the point encoding, because it uses little-endian, and - * the generic decoding routine uses big-endian. - */ - byteswap(G); - - /* - * Decode the point ('u' coordinate). This should be reduced - * modulo p, but we prefer to avoid the dependency on - * br_i31_decode_reduce(). Instead, we use br_i31_decode_mod() - * with a synthetic modulus of value 2^255 (this must work - * since G was truncated to 255 bits), then use a conditional - * subtraction. We use br_i31_decode_mod() and not - * br_i31_decode(), because the ec_prime_i31 implementation uses - * the former but not the latter. - * br_i31_decode_reduce(a, G, 32, C255_P); - */ - br_i31_zero(b, 0x108); - b[9] = 0x0100; - br_i31_decode_mod(a, G, 32, b); - a[0] = 0x107; - br_i31_sub(a, C255_P, NOT(br_i31_sub(a, C255_P, 0))); - - /* - * Initialise variables x1, x2, z2, x3 and z3. We set all of them - * into Montgomery representation. - */ - br_i31_montymul(x1, a, C255_R2, C255_P, P0I); - memcpy(x3, x1, sizeof x1); - br_i31_zero(z2, C255_P[0]); - memcpy(x2, z2, sizeof z2); - x2[1] = 0x13000000; - memcpy(z3, x2, sizeof x2); - - memcpy(k, kb, kblen); - memset(k + kblen, 0, (sizeof k) - kblen); - k[0] &= 0xF8; - k[31] &= 0x7F; - k[31] |= 0x40; - - /* obsolete - print_int_mont("x1", x1); - */ - - swap = 0; - for (i = 254; i >= 0; i --) { - uint32_t kt; - - kt = (k[i >> 3] >> (i & 7)) & 1; - swap ^= kt; - cswap(x2, x3, swap); - cswap(z2, z3, swap); - swap = kt; - - /* obsolete - print_int_mont("x2", x2); - print_int_mont("z2", z2); - print_int_mont("x3", x3); - print_int_mont("z3", z3); - */ - - c255_add(a, x2, z2); - c255_mul(aa, a, a); - c255_sub(b, x2, z2); - c255_mul(bb, b, b); - c255_sub(e, aa, bb); - c255_add(c, x3, z3); - c255_sub(d, x3, z3); - c255_mul(da, d, a); - c255_mul(cb, c, b); - - /* obsolete - print_int_mont("a ", a); - print_int_mont("aa", aa); - print_int_mont("b ", b); - print_int_mont("bb", bb); - print_int_mont("e ", e); - print_int_mont("c ", c); - print_int_mont("d ", d); - print_int_mont("da", da); - print_int_mont("cb", cb); - */ - - c255_add(x3, da, cb); - c255_mul(x3, x3, x3); - c255_sub(z3, da, cb); - c255_mul(z3, z3, z3); - c255_mul(z3, z3, x1); - c255_mul(x2, aa, bb); - c255_mul(z2, C255_A24, e); - c255_add(z2, z2, aa); - c255_mul(z2, e, z2); - - /* obsolete - print_int_mont("x2", x2); - print_int_mont("z2", z2); - print_int_mont("x3", x3); - print_int_mont("z3", z3); - */ - } - cswap(x2, x3, swap); - cswap(z2, z3, swap); - - /* - * Inverse z2 with a modular exponentiation. This is a simple - * square-and-multiply algorithm; we mutualise most non-squarings - * since the exponent contains almost only ones. - */ - memcpy(a, z2, sizeof z2); - for (i = 0; i < 15; i ++) { - c255_mul(a, a, a); - c255_mul(a, a, z2); - } - memcpy(b, a, sizeof a); - for (i = 0; i < 14; i ++) { - int j; - - for (j = 0; j < 16; j ++) { - c255_mul(b, b, b); - } - c255_mul(b, b, a); - } - for (i = 14; i >= 0; i --) { - c255_mul(b, b, b); - if ((0xFFEB >> i) & 1) { - c255_mul(b, z2, b); - } - } - c255_mul(b, x2, b); - - /* - * To avoid a dependency on br_i31_from_monty(), we use - * a Montgomery multiplication with 1. - * memcpy(x2, b, sizeof b); - * br_i31_from_monty(x2, C255_P, P0I); - */ - br_i31_zero(a, C255_P[0]); - a[1] = 1; - br_i31_montymul(x2, a, b, C255_P, P0I); - - br_i31_encode(G, 32, x2); - byteswap(G); - return 1; -} - -static size_t -api_mulgen(unsigned char *R, - const unsigned char *x, size_t xlen, int curve) -{ - const unsigned char *G; - size_t Glen; - - G = api_generator(curve, &Glen); - memcpy(R, G, Glen); - api_mul(R, Glen, x, xlen, curve); - return Glen; -} - -static uint32_t -api_muladd(unsigned char *A, const unsigned char *B, size_t len, - const unsigned char *x, size_t xlen, - const unsigned char *y, size_t ylen, int curve) -{ - /* - * We don't implement this method, since it is used for ECDSA - * only, and there is no ECDSA over Curve25519 (which instead - * uses EdDSA). - */ - (void)A; - (void)B; - (void)len; - (void)x; - (void)xlen; - (void)y; - (void)ylen; - (void)curve; - return 0; -} - -/* see bearssl_ec.h */ -const br_ec_impl br_ec_c25519_i31 = { - (uint32_t)0x20000000, - &api_generator, - &api_order, - &api_xoff, - &api_mul, - &api_mulgen, - &api_muladd -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ec_c25519_m15.c b/src/tls/bearssl/ec_c25519_m15.c deleted file mode 100644 index 3b0deff44..000000000 --- a/src/tls/bearssl/ec_c25519_m15.c +++ /dev/null @@ -1,1483 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* obsolete -#include -#include -static void -print_int(const char *name, const uint32_t *x) -{ - size_t u; - unsigned char tmp[36]; - - printf("%s = ", name); - for (u = 0; u < 20; u ++) { - if (x[u] > 0x1FFF) { - printf("INVALID:"); - for (u = 0; u < 20; u ++) { - printf(" %04X", x[u]); - } - printf("\n"); - return; - } - } - memset(tmp, 0, sizeof tmp); - for (u = 0; u < 20; u ++) { - uint32_t w; - int j, k; - - w = x[u]; - j = 13 * (int)u; - k = j & 7; - if (k != 0) { - w <<= k; - j -= k; - } - k = j >> 3; - tmp[35 - k] |= (unsigned char)w; - tmp[34 - k] |= (unsigned char)(w >> 8); - tmp[33 - k] |= (unsigned char)(w >> 16); - tmp[32 - k] |= (unsigned char)(w >> 24); - } - for (u = 4; u < 36; u ++) { - printf("%02X", tmp[u]); - } - printf("\n"); -} -*/ - -/* - * If BR_NO_ARITH_SHIFT is undefined, or defined to 0, then we _assume_ - * that right-shifting a signed negative integer copies the sign bit - * (arithmetic right-shift). This is "implementation-defined behaviour", - * i.e. it is not undefined, but it may differ between compilers. Each - * compiler is supposed to document its behaviour in that respect. GCC - * explicitly defines that an arithmetic right shift is used. We expect - * all other compilers to do the same, because underlying CPU offer an - * arithmetic right shift opcode that could not be used otherwise. - */ -#if BR_NO_ARITH_SHIFT -#define ARSH(x, n) (((uint32_t)(x) >> (n)) \ - | ((-((uint32_t)(x) >> 31)) << (32 - (n)))) -#else -#define ARSH(x, n) ((*(int32_t *)&(x)) >> (n)) -#endif - -/* - * Convert an integer from unsigned little-endian encoding to a sequence of - * 13-bit words in little-endian order. The final "partial" word is - * returned. - */ -static uint32_t -le8_to_le13(uint32_t *dst, const unsigned char *src, size_t len) -{ - uint32_t acc; - int acc_len; - - acc = 0; - acc_len = 0; - while (len -- > 0) { - acc |= (uint32_t)(*src ++) << acc_len; - acc_len += 8; - if (acc_len >= 13) { - *dst ++ = acc & 0x1FFF; - acc >>= 13; - acc_len -= 13; - } - } - return acc; -} - -/* - * Convert an integer (13-bit words, little-endian) to unsigned - * little-endian encoding. The total encoding length is provided; all - * the destination bytes will be filled. - */ -static void -le13_to_le8(unsigned char *dst, size_t len, const uint32_t *src) -{ - uint32_t acc; - int acc_len; - - acc = 0; - acc_len = 0; - while (len -- > 0) { - if (acc_len < 8) { - acc |= (*src ++) << acc_len; - acc_len += 13; - } - *dst ++ = (unsigned char)acc; - acc >>= 8; - acc_len -= 8; - } -} - -/* - * Normalise an array of words to a strict 13 bits per word. Returned - * value is the resulting carry. The source (w) and destination (d) - * arrays may be identical, but shall not overlap partially. - */ -static inline uint32_t -norm13(uint32_t *d, const uint32_t *w, size_t len) -{ - size_t u; - uint32_t cc; - - cc = 0; - for (u = 0; u < len; u ++) { - int32_t z; - - z = w[u] + cc; - d[u] = z & 0x1FFF; - cc = ARSH(z, 13); - } - return cc; -} - -/* - * mul20() multiplies two 260-bit integers together. Each word must fit - * on 13 bits; source operands use 20 words, destination operand - * receives 40 words. All overlaps allowed. - * - * square20() computes the square of a 260-bit integer. Each word must - * fit on 13 bits; source operand uses 20 words, destination operand - * receives 40 words. All overlaps allowed. - */ - -#if BR_SLOW_MUL15 - -static void -mul20(uint32_t *d, const uint32_t *a, const uint32_t *b) -{ - /* - * Two-level Karatsuba: turns a 20x20 multiplication into - * nine 5x5 multiplications. We use 13-bit words but do not - * propagate carries immediately, so words may expand: - * - * - First Karatsuba decomposition turns the 20x20 mul on - * 13-bit words into three 10x10 muls, two on 13-bit words - * and one on 14-bit words. - * - * - Second Karatsuba decomposition further splits these into: - * - * * four 5x5 muls on 13-bit words - * * four 5x5 muls on 14-bit words - * * one 5x5 mul on 15-bit words - * - * Highest word value is 8191, 16382 or 32764, for 13-bit, 14-bit - * or 15-bit words, respectively. - */ - uint32_t u[45], v[45], w[90]; - uint32_t cc; - int i; - -#define ZADD(dw, d_off, s1w, s1_off, s2w, s2_off) do { \ - (dw)[5 * (d_off) + 0] = (s1w)[5 * (s1_off) + 0] \ - + (s2w)[5 * (s2_off) + 0]; \ - (dw)[5 * (d_off) + 1] = (s1w)[5 * (s1_off) + 1] \ - + (s2w)[5 * (s2_off) + 1]; \ - (dw)[5 * (d_off) + 2] = (s1w)[5 * (s1_off) + 2] \ - + (s2w)[5 * (s2_off) + 2]; \ - (dw)[5 * (d_off) + 3] = (s1w)[5 * (s1_off) + 3] \ - + (s2w)[5 * (s2_off) + 3]; \ - (dw)[5 * (d_off) + 4] = (s1w)[5 * (s1_off) + 4] \ - + (s2w)[5 * (s2_off) + 4]; \ - } while (0) - -#define ZADDT(dw, d_off, sw, s_off) do { \ - (dw)[5 * (d_off) + 0] += (sw)[5 * (s_off) + 0]; \ - (dw)[5 * (d_off) + 1] += (sw)[5 * (s_off) + 1]; \ - (dw)[5 * (d_off) + 2] += (sw)[5 * (s_off) + 2]; \ - (dw)[5 * (d_off) + 3] += (sw)[5 * (s_off) + 3]; \ - (dw)[5 * (d_off) + 4] += (sw)[5 * (s_off) + 4]; \ - } while (0) - -#define ZSUB2F(dw, d_off, s1w, s1_off, s2w, s2_off) do { \ - (dw)[5 * (d_off) + 0] -= (s1w)[5 * (s1_off) + 0] \ - + (s2w)[5 * (s2_off) + 0]; \ - (dw)[5 * (d_off) + 1] -= (s1w)[5 * (s1_off) + 1] \ - + (s2w)[5 * (s2_off) + 1]; \ - (dw)[5 * (d_off) + 2] -= (s1w)[5 * (s1_off) + 2] \ - + (s2w)[5 * (s2_off) + 2]; \ - (dw)[5 * (d_off) + 3] -= (s1w)[5 * (s1_off) + 3] \ - + (s2w)[5 * (s2_off) + 3]; \ - (dw)[5 * (d_off) + 4] -= (s1w)[5 * (s1_off) + 4] \ - + (s2w)[5 * (s2_off) + 4]; \ - } while (0) - -#define CPR1(w, cprcc) do { \ - uint32_t cprz = (w) + cprcc; \ - (w) = cprz & 0x1FFF; \ - cprcc = cprz >> 13; \ - } while (0) - -#define CPR(dw, d_off) do { \ - uint32_t cprcc; \ - cprcc = 0; \ - CPR1((dw)[(d_off) + 0], cprcc); \ - CPR1((dw)[(d_off) + 1], cprcc); \ - CPR1((dw)[(d_off) + 2], cprcc); \ - CPR1((dw)[(d_off) + 3], cprcc); \ - CPR1((dw)[(d_off) + 4], cprcc); \ - CPR1((dw)[(d_off) + 5], cprcc); \ - CPR1((dw)[(d_off) + 6], cprcc); \ - CPR1((dw)[(d_off) + 7], cprcc); \ - CPR1((dw)[(d_off) + 8], cprcc); \ - (dw)[(d_off) + 9] = cprcc; \ - } while (0) - - memcpy(u, a, 20 * sizeof *a); - ZADD(u, 4, a, 0, a, 1); - ZADD(u, 5, a, 2, a, 3); - ZADD(u, 6, a, 0, a, 2); - ZADD(u, 7, a, 1, a, 3); - ZADD(u, 8, u, 6, u, 7); - - memcpy(v, b, 20 * sizeof *b); - ZADD(v, 4, b, 0, b, 1); - ZADD(v, 5, b, 2, b, 3); - ZADD(v, 6, b, 0, b, 2); - ZADD(v, 7, b, 1, b, 3); - ZADD(v, 8, v, 6, v, 7); - - /* - * Do the eight first 8x8 muls. Source words are at most 16382 - * each, so we can add product results together "as is" in 32-bit - * words. - */ - for (i = 0; i < 40; i += 5) { - w[(i << 1) + 0] = MUL15(u[i + 0], v[i + 0]); - w[(i << 1) + 1] = MUL15(u[i + 0], v[i + 1]) - + MUL15(u[i + 1], v[i + 0]); - w[(i << 1) + 2] = MUL15(u[i + 0], v[i + 2]) - + MUL15(u[i + 1], v[i + 1]) - + MUL15(u[i + 2], v[i + 0]); - w[(i << 1) + 3] = MUL15(u[i + 0], v[i + 3]) - + MUL15(u[i + 1], v[i + 2]) - + MUL15(u[i + 2], v[i + 1]) - + MUL15(u[i + 3], v[i + 0]); - w[(i << 1) + 4] = MUL15(u[i + 0], v[i + 4]) - + MUL15(u[i + 1], v[i + 3]) - + MUL15(u[i + 2], v[i + 2]) - + MUL15(u[i + 3], v[i + 1]) - + MUL15(u[i + 4], v[i + 0]); - w[(i << 1) + 5] = MUL15(u[i + 1], v[i + 4]) - + MUL15(u[i + 2], v[i + 3]) - + MUL15(u[i + 3], v[i + 2]) - + MUL15(u[i + 4], v[i + 1]); - w[(i << 1) + 6] = MUL15(u[i + 2], v[i + 4]) - + MUL15(u[i + 3], v[i + 3]) - + MUL15(u[i + 4], v[i + 2]); - w[(i << 1) + 7] = MUL15(u[i + 3], v[i + 4]) - + MUL15(u[i + 4], v[i + 3]); - w[(i << 1) + 8] = MUL15(u[i + 4], v[i + 4]); - w[(i << 1) + 9] = 0; - } - - /* - * For the 9th multiplication, source words are up to 32764, - * so we must do some carry propagation. If we add up to - * 4 products and the carry is no more than 524224, then the - * result fits in 32 bits, and the next carry will be no more - * than 524224 (because 4*(32764^2)+524224 < 8192*524225). - * - * We thus just skip one of the products in the middle word, - * then do a carry propagation (this reduces words to 13 bits - * each, except possibly the last, which may use up to 17 bits - * or so), then add the missing product. - */ - w[80 + 0] = MUL15(u[40 + 0], v[40 + 0]); - w[80 + 1] = MUL15(u[40 + 0], v[40 + 1]) - + MUL15(u[40 + 1], v[40 + 0]); - w[80 + 2] = MUL15(u[40 + 0], v[40 + 2]) - + MUL15(u[40 + 1], v[40 + 1]) - + MUL15(u[40 + 2], v[40 + 0]); - w[80 + 3] = MUL15(u[40 + 0], v[40 + 3]) - + MUL15(u[40 + 1], v[40 + 2]) - + MUL15(u[40 + 2], v[40 + 1]) - + MUL15(u[40 + 3], v[40 + 0]); - w[80 + 4] = MUL15(u[40 + 0], v[40 + 4]) - + MUL15(u[40 + 1], v[40 + 3]) - + MUL15(u[40 + 2], v[40 + 2]) - + MUL15(u[40 + 3], v[40 + 1]); - /* + MUL15(u[40 + 4], v[40 + 0]) */ - w[80 + 5] = MUL15(u[40 + 1], v[40 + 4]) - + MUL15(u[40 + 2], v[40 + 3]) - + MUL15(u[40 + 3], v[40 + 2]) - + MUL15(u[40 + 4], v[40 + 1]); - w[80 + 6] = MUL15(u[40 + 2], v[40 + 4]) - + MUL15(u[40 + 3], v[40 + 3]) - + MUL15(u[40 + 4], v[40 + 2]); - w[80 + 7] = MUL15(u[40 + 3], v[40 + 4]) - + MUL15(u[40 + 4], v[40 + 3]); - w[80 + 8] = MUL15(u[40 + 4], v[40 + 4]); - - CPR(w, 80); - - w[80 + 4] += MUL15(u[40 + 4], v[40 + 0]); - - /* - * The products on 14-bit words in slots 6 and 7 yield values - * up to 5*(16382^2) each, and we need to subtract two such - * values from the higher word. We need the subtraction to fit - * in a _signed_ 32-bit integer, i.e. 31 bits + a sign bit. - * However, 10*(16382^2) does not fit. So we must perform a - * bit of reduction here. - */ - CPR(w, 60); - CPR(w, 70); - - /* - * Recompose results. - */ - - /* 0..1*0..1 into 0..3 */ - ZSUB2F(w, 8, w, 0, w, 2); - ZSUB2F(w, 9, w, 1, w, 3); - ZADDT(w, 1, w, 8); - ZADDT(w, 2, w, 9); - - /* 2..3*2..3 into 4..7 */ - ZSUB2F(w, 10, w, 4, w, 6); - ZSUB2F(w, 11, w, 5, w, 7); - ZADDT(w, 5, w, 10); - ZADDT(w, 6, w, 11); - - /* (0..1+2..3)*(0..1+2..3) into 12..15 */ - ZSUB2F(w, 16, w, 12, w, 14); - ZSUB2F(w, 17, w, 13, w, 15); - ZADDT(w, 13, w, 16); - ZADDT(w, 14, w, 17); - - /* first-level recomposition */ - ZSUB2F(w, 12, w, 0, w, 4); - ZSUB2F(w, 13, w, 1, w, 5); - ZSUB2F(w, 14, w, 2, w, 6); - ZSUB2F(w, 15, w, 3, w, 7); - ZADDT(w, 2, w, 12); - ZADDT(w, 3, w, 13); - ZADDT(w, 4, w, 14); - ZADDT(w, 5, w, 15); - - /* - * Perform carry propagation to bring all words down to 13 bits. - */ - cc = norm13(d, w, 40); - d[39] += (cc << 13); - -#undef ZADD -#undef ZADDT -#undef ZSUB2F -#undef CPR1 -#undef CPR -} - -static inline void -square20(uint32_t *d, const uint32_t *a) -{ - mul20(d, a, a); -} - -#else - -static void -mul20(uint32_t *d, const uint32_t *a, const uint32_t *b) -{ - uint32_t t[39]; - - t[ 0] = MUL15(a[ 0], b[ 0]); - t[ 1] = MUL15(a[ 0], b[ 1]) - + MUL15(a[ 1], b[ 0]); - t[ 2] = MUL15(a[ 0], b[ 2]) - + MUL15(a[ 1], b[ 1]) - + MUL15(a[ 2], b[ 0]); - t[ 3] = MUL15(a[ 0], b[ 3]) - + MUL15(a[ 1], b[ 2]) - + MUL15(a[ 2], b[ 1]) - + MUL15(a[ 3], b[ 0]); - t[ 4] = MUL15(a[ 0], b[ 4]) - + MUL15(a[ 1], b[ 3]) - + MUL15(a[ 2], b[ 2]) - + MUL15(a[ 3], b[ 1]) - + MUL15(a[ 4], b[ 0]); - t[ 5] = MUL15(a[ 0], b[ 5]) - + MUL15(a[ 1], b[ 4]) - + MUL15(a[ 2], b[ 3]) - + MUL15(a[ 3], b[ 2]) - + MUL15(a[ 4], b[ 1]) - + MUL15(a[ 5], b[ 0]); - t[ 6] = MUL15(a[ 0], b[ 6]) - + MUL15(a[ 1], b[ 5]) - + MUL15(a[ 2], b[ 4]) - + MUL15(a[ 3], b[ 3]) - + MUL15(a[ 4], b[ 2]) - + MUL15(a[ 5], b[ 1]) - + MUL15(a[ 6], b[ 0]); - t[ 7] = MUL15(a[ 0], b[ 7]) - + MUL15(a[ 1], b[ 6]) - + MUL15(a[ 2], b[ 5]) - + MUL15(a[ 3], b[ 4]) - + MUL15(a[ 4], b[ 3]) - + MUL15(a[ 5], b[ 2]) - + MUL15(a[ 6], b[ 1]) - + MUL15(a[ 7], b[ 0]); - t[ 8] = MUL15(a[ 0], b[ 8]) - + MUL15(a[ 1], b[ 7]) - + MUL15(a[ 2], b[ 6]) - + MUL15(a[ 3], b[ 5]) - + MUL15(a[ 4], b[ 4]) - + MUL15(a[ 5], b[ 3]) - + MUL15(a[ 6], b[ 2]) - + MUL15(a[ 7], b[ 1]) - + MUL15(a[ 8], b[ 0]); - t[ 9] = MUL15(a[ 0], b[ 9]) - + MUL15(a[ 1], b[ 8]) - + MUL15(a[ 2], b[ 7]) - + MUL15(a[ 3], b[ 6]) - + MUL15(a[ 4], b[ 5]) - + MUL15(a[ 5], b[ 4]) - + MUL15(a[ 6], b[ 3]) - + MUL15(a[ 7], b[ 2]) - + MUL15(a[ 8], b[ 1]) - + MUL15(a[ 9], b[ 0]); - t[10] = MUL15(a[ 0], b[10]) - + MUL15(a[ 1], b[ 9]) - + MUL15(a[ 2], b[ 8]) - + MUL15(a[ 3], b[ 7]) - + MUL15(a[ 4], b[ 6]) - + MUL15(a[ 5], b[ 5]) - + MUL15(a[ 6], b[ 4]) - + MUL15(a[ 7], b[ 3]) - + MUL15(a[ 8], b[ 2]) - + MUL15(a[ 9], b[ 1]) - + MUL15(a[10], b[ 0]); - t[11] = MUL15(a[ 0], b[11]) - + MUL15(a[ 1], b[10]) - + MUL15(a[ 2], b[ 9]) - + MUL15(a[ 3], b[ 8]) - + MUL15(a[ 4], b[ 7]) - + MUL15(a[ 5], b[ 6]) - + MUL15(a[ 6], b[ 5]) - + MUL15(a[ 7], b[ 4]) - + MUL15(a[ 8], b[ 3]) - + MUL15(a[ 9], b[ 2]) - + MUL15(a[10], b[ 1]) - + MUL15(a[11], b[ 0]); - t[12] = MUL15(a[ 0], b[12]) - + MUL15(a[ 1], b[11]) - + MUL15(a[ 2], b[10]) - + MUL15(a[ 3], b[ 9]) - + MUL15(a[ 4], b[ 8]) - + MUL15(a[ 5], b[ 7]) - + MUL15(a[ 6], b[ 6]) - + MUL15(a[ 7], b[ 5]) - + MUL15(a[ 8], b[ 4]) - + MUL15(a[ 9], b[ 3]) - + MUL15(a[10], b[ 2]) - + MUL15(a[11], b[ 1]) - + MUL15(a[12], b[ 0]); - t[13] = MUL15(a[ 0], b[13]) - + MUL15(a[ 1], b[12]) - + MUL15(a[ 2], b[11]) - + MUL15(a[ 3], b[10]) - + MUL15(a[ 4], b[ 9]) - + MUL15(a[ 5], b[ 8]) - + MUL15(a[ 6], b[ 7]) - + MUL15(a[ 7], b[ 6]) - + MUL15(a[ 8], b[ 5]) - + MUL15(a[ 9], b[ 4]) - + MUL15(a[10], b[ 3]) - + MUL15(a[11], b[ 2]) - + MUL15(a[12], b[ 1]) - + MUL15(a[13], b[ 0]); - t[14] = MUL15(a[ 0], b[14]) - + MUL15(a[ 1], b[13]) - + MUL15(a[ 2], b[12]) - + MUL15(a[ 3], b[11]) - + MUL15(a[ 4], b[10]) - + MUL15(a[ 5], b[ 9]) - + MUL15(a[ 6], b[ 8]) - + MUL15(a[ 7], b[ 7]) - + MUL15(a[ 8], b[ 6]) - + MUL15(a[ 9], b[ 5]) - + MUL15(a[10], b[ 4]) - + MUL15(a[11], b[ 3]) - + MUL15(a[12], b[ 2]) - + MUL15(a[13], b[ 1]) - + MUL15(a[14], b[ 0]); - t[15] = MUL15(a[ 0], b[15]) - + MUL15(a[ 1], b[14]) - + MUL15(a[ 2], b[13]) - + MUL15(a[ 3], b[12]) - + MUL15(a[ 4], b[11]) - + MUL15(a[ 5], b[10]) - + MUL15(a[ 6], b[ 9]) - + MUL15(a[ 7], b[ 8]) - + MUL15(a[ 8], b[ 7]) - + MUL15(a[ 9], b[ 6]) - + MUL15(a[10], b[ 5]) - + MUL15(a[11], b[ 4]) - + MUL15(a[12], b[ 3]) - + MUL15(a[13], b[ 2]) - + MUL15(a[14], b[ 1]) - + MUL15(a[15], b[ 0]); - t[16] = MUL15(a[ 0], b[16]) - + MUL15(a[ 1], b[15]) - + MUL15(a[ 2], b[14]) - + MUL15(a[ 3], b[13]) - + MUL15(a[ 4], b[12]) - + MUL15(a[ 5], b[11]) - + MUL15(a[ 6], b[10]) - + MUL15(a[ 7], b[ 9]) - + MUL15(a[ 8], b[ 8]) - + MUL15(a[ 9], b[ 7]) - + MUL15(a[10], b[ 6]) - + MUL15(a[11], b[ 5]) - + MUL15(a[12], b[ 4]) - + MUL15(a[13], b[ 3]) - + MUL15(a[14], b[ 2]) - + MUL15(a[15], b[ 1]) - + MUL15(a[16], b[ 0]); - t[17] = MUL15(a[ 0], b[17]) - + MUL15(a[ 1], b[16]) - + MUL15(a[ 2], b[15]) - + MUL15(a[ 3], b[14]) - + MUL15(a[ 4], b[13]) - + MUL15(a[ 5], b[12]) - + MUL15(a[ 6], b[11]) - + MUL15(a[ 7], b[10]) - + MUL15(a[ 8], b[ 9]) - + MUL15(a[ 9], b[ 8]) - + MUL15(a[10], b[ 7]) - + MUL15(a[11], b[ 6]) - + MUL15(a[12], b[ 5]) - + MUL15(a[13], b[ 4]) - + MUL15(a[14], b[ 3]) - + MUL15(a[15], b[ 2]) - + MUL15(a[16], b[ 1]) - + MUL15(a[17], b[ 0]); - t[18] = MUL15(a[ 0], b[18]) - + MUL15(a[ 1], b[17]) - + MUL15(a[ 2], b[16]) - + MUL15(a[ 3], b[15]) - + MUL15(a[ 4], b[14]) - + MUL15(a[ 5], b[13]) - + MUL15(a[ 6], b[12]) - + MUL15(a[ 7], b[11]) - + MUL15(a[ 8], b[10]) - + MUL15(a[ 9], b[ 9]) - + MUL15(a[10], b[ 8]) - + MUL15(a[11], b[ 7]) - + MUL15(a[12], b[ 6]) - + MUL15(a[13], b[ 5]) - + MUL15(a[14], b[ 4]) - + MUL15(a[15], b[ 3]) - + MUL15(a[16], b[ 2]) - + MUL15(a[17], b[ 1]) - + MUL15(a[18], b[ 0]); - t[19] = MUL15(a[ 0], b[19]) - + MUL15(a[ 1], b[18]) - + MUL15(a[ 2], b[17]) - + MUL15(a[ 3], b[16]) - + MUL15(a[ 4], b[15]) - + MUL15(a[ 5], b[14]) - + MUL15(a[ 6], b[13]) - + MUL15(a[ 7], b[12]) - + MUL15(a[ 8], b[11]) - + MUL15(a[ 9], b[10]) - + MUL15(a[10], b[ 9]) - + MUL15(a[11], b[ 8]) - + MUL15(a[12], b[ 7]) - + MUL15(a[13], b[ 6]) - + MUL15(a[14], b[ 5]) - + MUL15(a[15], b[ 4]) - + MUL15(a[16], b[ 3]) - + MUL15(a[17], b[ 2]) - + MUL15(a[18], b[ 1]) - + MUL15(a[19], b[ 0]); - t[20] = MUL15(a[ 1], b[19]) - + MUL15(a[ 2], b[18]) - + MUL15(a[ 3], b[17]) - + MUL15(a[ 4], b[16]) - + MUL15(a[ 5], b[15]) - + MUL15(a[ 6], b[14]) - + MUL15(a[ 7], b[13]) - + MUL15(a[ 8], b[12]) - + MUL15(a[ 9], b[11]) - + MUL15(a[10], b[10]) - + MUL15(a[11], b[ 9]) - + MUL15(a[12], b[ 8]) - + MUL15(a[13], b[ 7]) - + MUL15(a[14], b[ 6]) - + MUL15(a[15], b[ 5]) - + MUL15(a[16], b[ 4]) - + MUL15(a[17], b[ 3]) - + MUL15(a[18], b[ 2]) - + MUL15(a[19], b[ 1]); - t[21] = MUL15(a[ 2], b[19]) - + MUL15(a[ 3], b[18]) - + MUL15(a[ 4], b[17]) - + MUL15(a[ 5], b[16]) - + MUL15(a[ 6], b[15]) - + MUL15(a[ 7], b[14]) - + MUL15(a[ 8], b[13]) - + MUL15(a[ 9], b[12]) - + MUL15(a[10], b[11]) - + MUL15(a[11], b[10]) - + MUL15(a[12], b[ 9]) - + MUL15(a[13], b[ 8]) - + MUL15(a[14], b[ 7]) - + MUL15(a[15], b[ 6]) - + MUL15(a[16], b[ 5]) - + MUL15(a[17], b[ 4]) - + MUL15(a[18], b[ 3]) - + MUL15(a[19], b[ 2]); - t[22] = MUL15(a[ 3], b[19]) - + MUL15(a[ 4], b[18]) - + MUL15(a[ 5], b[17]) - + MUL15(a[ 6], b[16]) - + MUL15(a[ 7], b[15]) - + MUL15(a[ 8], b[14]) - + MUL15(a[ 9], b[13]) - + MUL15(a[10], b[12]) - + MUL15(a[11], b[11]) - + MUL15(a[12], b[10]) - + MUL15(a[13], b[ 9]) - + MUL15(a[14], b[ 8]) - + MUL15(a[15], b[ 7]) - + MUL15(a[16], b[ 6]) - + MUL15(a[17], b[ 5]) - + MUL15(a[18], b[ 4]) - + MUL15(a[19], b[ 3]); - t[23] = MUL15(a[ 4], b[19]) - + MUL15(a[ 5], b[18]) - + MUL15(a[ 6], b[17]) - + MUL15(a[ 7], b[16]) - + MUL15(a[ 8], b[15]) - + MUL15(a[ 9], b[14]) - + MUL15(a[10], b[13]) - + MUL15(a[11], b[12]) - + MUL15(a[12], b[11]) - + MUL15(a[13], b[10]) - + MUL15(a[14], b[ 9]) - + MUL15(a[15], b[ 8]) - + MUL15(a[16], b[ 7]) - + MUL15(a[17], b[ 6]) - + MUL15(a[18], b[ 5]) - + MUL15(a[19], b[ 4]); - t[24] = MUL15(a[ 5], b[19]) - + MUL15(a[ 6], b[18]) - + MUL15(a[ 7], b[17]) - + MUL15(a[ 8], b[16]) - + MUL15(a[ 9], b[15]) - + MUL15(a[10], b[14]) - + MUL15(a[11], b[13]) - + MUL15(a[12], b[12]) - + MUL15(a[13], b[11]) - + MUL15(a[14], b[10]) - + MUL15(a[15], b[ 9]) - + MUL15(a[16], b[ 8]) - + MUL15(a[17], b[ 7]) - + MUL15(a[18], b[ 6]) - + MUL15(a[19], b[ 5]); - t[25] = MUL15(a[ 6], b[19]) - + MUL15(a[ 7], b[18]) - + MUL15(a[ 8], b[17]) - + MUL15(a[ 9], b[16]) - + MUL15(a[10], b[15]) - + MUL15(a[11], b[14]) - + MUL15(a[12], b[13]) - + MUL15(a[13], b[12]) - + MUL15(a[14], b[11]) - + MUL15(a[15], b[10]) - + MUL15(a[16], b[ 9]) - + MUL15(a[17], b[ 8]) - + MUL15(a[18], b[ 7]) - + MUL15(a[19], b[ 6]); - t[26] = MUL15(a[ 7], b[19]) - + MUL15(a[ 8], b[18]) - + MUL15(a[ 9], b[17]) - + MUL15(a[10], b[16]) - + MUL15(a[11], b[15]) - + MUL15(a[12], b[14]) - + MUL15(a[13], b[13]) - + MUL15(a[14], b[12]) - + MUL15(a[15], b[11]) - + MUL15(a[16], b[10]) - + MUL15(a[17], b[ 9]) - + MUL15(a[18], b[ 8]) - + MUL15(a[19], b[ 7]); - t[27] = MUL15(a[ 8], b[19]) - + MUL15(a[ 9], b[18]) - + MUL15(a[10], b[17]) - + MUL15(a[11], b[16]) - + MUL15(a[12], b[15]) - + MUL15(a[13], b[14]) - + MUL15(a[14], b[13]) - + MUL15(a[15], b[12]) - + MUL15(a[16], b[11]) - + MUL15(a[17], b[10]) - + MUL15(a[18], b[ 9]) - + MUL15(a[19], b[ 8]); - t[28] = MUL15(a[ 9], b[19]) - + MUL15(a[10], b[18]) - + MUL15(a[11], b[17]) - + MUL15(a[12], b[16]) - + MUL15(a[13], b[15]) - + MUL15(a[14], b[14]) - + MUL15(a[15], b[13]) - + MUL15(a[16], b[12]) - + MUL15(a[17], b[11]) - + MUL15(a[18], b[10]) - + MUL15(a[19], b[ 9]); - t[29] = MUL15(a[10], b[19]) - + MUL15(a[11], b[18]) - + MUL15(a[12], b[17]) - + MUL15(a[13], b[16]) - + MUL15(a[14], b[15]) - + MUL15(a[15], b[14]) - + MUL15(a[16], b[13]) - + MUL15(a[17], b[12]) - + MUL15(a[18], b[11]) - + MUL15(a[19], b[10]); - t[30] = MUL15(a[11], b[19]) - + MUL15(a[12], b[18]) - + MUL15(a[13], b[17]) - + MUL15(a[14], b[16]) - + MUL15(a[15], b[15]) - + MUL15(a[16], b[14]) - + MUL15(a[17], b[13]) - + MUL15(a[18], b[12]) - + MUL15(a[19], b[11]); - t[31] = MUL15(a[12], b[19]) - + MUL15(a[13], b[18]) - + MUL15(a[14], b[17]) - + MUL15(a[15], b[16]) - + MUL15(a[16], b[15]) - + MUL15(a[17], b[14]) - + MUL15(a[18], b[13]) - + MUL15(a[19], b[12]); - t[32] = MUL15(a[13], b[19]) - + MUL15(a[14], b[18]) - + MUL15(a[15], b[17]) - + MUL15(a[16], b[16]) - + MUL15(a[17], b[15]) - + MUL15(a[18], b[14]) - + MUL15(a[19], b[13]); - t[33] = MUL15(a[14], b[19]) - + MUL15(a[15], b[18]) - + MUL15(a[16], b[17]) - + MUL15(a[17], b[16]) - + MUL15(a[18], b[15]) - + MUL15(a[19], b[14]); - t[34] = MUL15(a[15], b[19]) - + MUL15(a[16], b[18]) - + MUL15(a[17], b[17]) - + MUL15(a[18], b[16]) - + MUL15(a[19], b[15]); - t[35] = MUL15(a[16], b[19]) - + MUL15(a[17], b[18]) - + MUL15(a[18], b[17]) - + MUL15(a[19], b[16]); - t[36] = MUL15(a[17], b[19]) - + MUL15(a[18], b[18]) - + MUL15(a[19], b[17]); - t[37] = MUL15(a[18], b[19]) - + MUL15(a[19], b[18]); - t[38] = MUL15(a[19], b[19]); - - d[39] = norm13(d, t, 39); -} - -static void -square20(uint32_t *d, const uint32_t *a) -{ - uint32_t t[39]; - - t[ 0] = MUL15(a[ 0], a[ 0]); - t[ 1] = ((MUL15(a[ 0], a[ 1])) << 1); - t[ 2] = MUL15(a[ 1], a[ 1]) - + ((MUL15(a[ 0], a[ 2])) << 1); - t[ 3] = ((MUL15(a[ 0], a[ 3]) - + MUL15(a[ 1], a[ 2])) << 1); - t[ 4] = MUL15(a[ 2], a[ 2]) - + ((MUL15(a[ 0], a[ 4]) - + MUL15(a[ 1], a[ 3])) << 1); - t[ 5] = ((MUL15(a[ 0], a[ 5]) - + MUL15(a[ 1], a[ 4]) - + MUL15(a[ 2], a[ 3])) << 1); - t[ 6] = MUL15(a[ 3], a[ 3]) - + ((MUL15(a[ 0], a[ 6]) - + MUL15(a[ 1], a[ 5]) - + MUL15(a[ 2], a[ 4])) << 1); - t[ 7] = ((MUL15(a[ 0], a[ 7]) - + MUL15(a[ 1], a[ 6]) - + MUL15(a[ 2], a[ 5]) - + MUL15(a[ 3], a[ 4])) << 1); - t[ 8] = MUL15(a[ 4], a[ 4]) - + ((MUL15(a[ 0], a[ 8]) - + MUL15(a[ 1], a[ 7]) - + MUL15(a[ 2], a[ 6]) - + MUL15(a[ 3], a[ 5])) << 1); - t[ 9] = ((MUL15(a[ 0], a[ 9]) - + MUL15(a[ 1], a[ 8]) - + MUL15(a[ 2], a[ 7]) - + MUL15(a[ 3], a[ 6]) - + MUL15(a[ 4], a[ 5])) << 1); - t[10] = MUL15(a[ 5], a[ 5]) - + ((MUL15(a[ 0], a[10]) - + MUL15(a[ 1], a[ 9]) - + MUL15(a[ 2], a[ 8]) - + MUL15(a[ 3], a[ 7]) - + MUL15(a[ 4], a[ 6])) << 1); - t[11] = ((MUL15(a[ 0], a[11]) - + MUL15(a[ 1], a[10]) - + MUL15(a[ 2], a[ 9]) - + MUL15(a[ 3], a[ 8]) - + MUL15(a[ 4], a[ 7]) - + MUL15(a[ 5], a[ 6])) << 1); - t[12] = MUL15(a[ 6], a[ 6]) - + ((MUL15(a[ 0], a[12]) - + MUL15(a[ 1], a[11]) - + MUL15(a[ 2], a[10]) - + MUL15(a[ 3], a[ 9]) - + MUL15(a[ 4], a[ 8]) - + MUL15(a[ 5], a[ 7])) << 1); - t[13] = ((MUL15(a[ 0], a[13]) - + MUL15(a[ 1], a[12]) - + MUL15(a[ 2], a[11]) - + MUL15(a[ 3], a[10]) - + MUL15(a[ 4], a[ 9]) - + MUL15(a[ 5], a[ 8]) - + MUL15(a[ 6], a[ 7])) << 1); - t[14] = MUL15(a[ 7], a[ 7]) - + ((MUL15(a[ 0], a[14]) - + MUL15(a[ 1], a[13]) - + MUL15(a[ 2], a[12]) - + MUL15(a[ 3], a[11]) - + MUL15(a[ 4], a[10]) - + MUL15(a[ 5], a[ 9]) - + MUL15(a[ 6], a[ 8])) << 1); - t[15] = ((MUL15(a[ 0], a[15]) - + MUL15(a[ 1], a[14]) - + MUL15(a[ 2], a[13]) - + MUL15(a[ 3], a[12]) - + MUL15(a[ 4], a[11]) - + MUL15(a[ 5], a[10]) - + MUL15(a[ 6], a[ 9]) - + MUL15(a[ 7], a[ 8])) << 1); - t[16] = MUL15(a[ 8], a[ 8]) - + ((MUL15(a[ 0], a[16]) - + MUL15(a[ 1], a[15]) - + MUL15(a[ 2], a[14]) - + MUL15(a[ 3], a[13]) - + MUL15(a[ 4], a[12]) - + MUL15(a[ 5], a[11]) - + MUL15(a[ 6], a[10]) - + MUL15(a[ 7], a[ 9])) << 1); - t[17] = ((MUL15(a[ 0], a[17]) - + MUL15(a[ 1], a[16]) - + MUL15(a[ 2], a[15]) - + MUL15(a[ 3], a[14]) - + MUL15(a[ 4], a[13]) - + MUL15(a[ 5], a[12]) - + MUL15(a[ 6], a[11]) - + MUL15(a[ 7], a[10]) - + MUL15(a[ 8], a[ 9])) << 1); - t[18] = MUL15(a[ 9], a[ 9]) - + ((MUL15(a[ 0], a[18]) - + MUL15(a[ 1], a[17]) - + MUL15(a[ 2], a[16]) - + MUL15(a[ 3], a[15]) - + MUL15(a[ 4], a[14]) - + MUL15(a[ 5], a[13]) - + MUL15(a[ 6], a[12]) - + MUL15(a[ 7], a[11]) - + MUL15(a[ 8], a[10])) << 1); - t[19] = ((MUL15(a[ 0], a[19]) - + MUL15(a[ 1], a[18]) - + MUL15(a[ 2], a[17]) - + MUL15(a[ 3], a[16]) - + MUL15(a[ 4], a[15]) - + MUL15(a[ 5], a[14]) - + MUL15(a[ 6], a[13]) - + MUL15(a[ 7], a[12]) - + MUL15(a[ 8], a[11]) - + MUL15(a[ 9], a[10])) << 1); - t[20] = MUL15(a[10], a[10]) - + ((MUL15(a[ 1], a[19]) - + MUL15(a[ 2], a[18]) - + MUL15(a[ 3], a[17]) - + MUL15(a[ 4], a[16]) - + MUL15(a[ 5], a[15]) - + MUL15(a[ 6], a[14]) - + MUL15(a[ 7], a[13]) - + MUL15(a[ 8], a[12]) - + MUL15(a[ 9], a[11])) << 1); - t[21] = ((MUL15(a[ 2], a[19]) - + MUL15(a[ 3], a[18]) - + MUL15(a[ 4], a[17]) - + MUL15(a[ 5], a[16]) - + MUL15(a[ 6], a[15]) - + MUL15(a[ 7], a[14]) - + MUL15(a[ 8], a[13]) - + MUL15(a[ 9], a[12]) - + MUL15(a[10], a[11])) << 1); - t[22] = MUL15(a[11], a[11]) - + ((MUL15(a[ 3], a[19]) - + MUL15(a[ 4], a[18]) - + MUL15(a[ 5], a[17]) - + MUL15(a[ 6], a[16]) - + MUL15(a[ 7], a[15]) - + MUL15(a[ 8], a[14]) - + MUL15(a[ 9], a[13]) - + MUL15(a[10], a[12])) << 1); - t[23] = ((MUL15(a[ 4], a[19]) - + MUL15(a[ 5], a[18]) - + MUL15(a[ 6], a[17]) - + MUL15(a[ 7], a[16]) - + MUL15(a[ 8], a[15]) - + MUL15(a[ 9], a[14]) - + MUL15(a[10], a[13]) - + MUL15(a[11], a[12])) << 1); - t[24] = MUL15(a[12], a[12]) - + ((MUL15(a[ 5], a[19]) - + MUL15(a[ 6], a[18]) - + MUL15(a[ 7], a[17]) - + MUL15(a[ 8], a[16]) - + MUL15(a[ 9], a[15]) - + MUL15(a[10], a[14]) - + MUL15(a[11], a[13])) << 1); - t[25] = ((MUL15(a[ 6], a[19]) - + MUL15(a[ 7], a[18]) - + MUL15(a[ 8], a[17]) - + MUL15(a[ 9], a[16]) - + MUL15(a[10], a[15]) - + MUL15(a[11], a[14]) - + MUL15(a[12], a[13])) << 1); - t[26] = MUL15(a[13], a[13]) - + ((MUL15(a[ 7], a[19]) - + MUL15(a[ 8], a[18]) - + MUL15(a[ 9], a[17]) - + MUL15(a[10], a[16]) - + MUL15(a[11], a[15]) - + MUL15(a[12], a[14])) << 1); - t[27] = ((MUL15(a[ 8], a[19]) - + MUL15(a[ 9], a[18]) - + MUL15(a[10], a[17]) - + MUL15(a[11], a[16]) - + MUL15(a[12], a[15]) - + MUL15(a[13], a[14])) << 1); - t[28] = MUL15(a[14], a[14]) - + ((MUL15(a[ 9], a[19]) - + MUL15(a[10], a[18]) - + MUL15(a[11], a[17]) - + MUL15(a[12], a[16]) - + MUL15(a[13], a[15])) << 1); - t[29] = ((MUL15(a[10], a[19]) - + MUL15(a[11], a[18]) - + MUL15(a[12], a[17]) - + MUL15(a[13], a[16]) - + MUL15(a[14], a[15])) << 1); - t[30] = MUL15(a[15], a[15]) - + ((MUL15(a[11], a[19]) - + MUL15(a[12], a[18]) - + MUL15(a[13], a[17]) - + MUL15(a[14], a[16])) << 1); - t[31] = ((MUL15(a[12], a[19]) - + MUL15(a[13], a[18]) - + MUL15(a[14], a[17]) - + MUL15(a[15], a[16])) << 1); - t[32] = MUL15(a[16], a[16]) - + ((MUL15(a[13], a[19]) - + MUL15(a[14], a[18]) - + MUL15(a[15], a[17])) << 1); - t[33] = ((MUL15(a[14], a[19]) - + MUL15(a[15], a[18]) - + MUL15(a[16], a[17])) << 1); - t[34] = MUL15(a[17], a[17]) - + ((MUL15(a[15], a[19]) - + MUL15(a[16], a[18])) << 1); - t[35] = ((MUL15(a[16], a[19]) - + MUL15(a[17], a[18])) << 1); - t[36] = MUL15(a[18], a[18]) - + ((MUL15(a[17], a[19])) << 1); - t[37] = ((MUL15(a[18], a[19])) << 1); - t[38] = MUL15(a[19], a[19]); - - d[39] = norm13(d, t, 39); -} - -#endif - -/* - * Perform a "final reduction" in field F255 (field for Curve25519) - * The source value must be less than twice the modulus. If the value - * is not lower than the modulus, then the modulus is subtracted and - * this function returns 1; otherwise, it leaves it untouched and it - * returns 0. - */ -static uint32_t -reduce_final_f255(uint32_t *d) -{ - uint32_t t[20]; - uint32_t cc; - int i; - - memcpy(t, d, sizeof t); - cc = 19; - for (i = 0; i < 20; i ++) { - uint32_t w; - - w = t[i] + cc; - cc = w >> 13; - t[i] = w & 0x1FFF; - } - cc = t[19] >> 8; - t[19] &= 0xFF; - CCOPY(cc, d, t, sizeof t); - return cc; -} - -static void -f255_mulgen(uint32_t *d, const uint32_t *a, const uint32_t *b, int square) -{ - uint32_t t[40], cc, w; - - /* - * Compute raw multiplication. All result words fit in 13 bits - * each; upper word (t[39]) must fit on 5 bits, since the product - * of two 256-bit integers must fit on 512 bits. - */ - if (square) { - square20(t, a); - } else { - mul20(t, a, b); - } - - /* - * Modular reduction: each high word is added where necessary. - * Since the modulus is 2^255-19 and word 20 corresponds to - * offset 20*13 = 260, word 20+k must be added to word k with - * a factor of 19*2^5 = 608. The extra bits in word 19 are also - * added that way. - */ - cc = MUL15(t[19] >> 8, 19); - t[19] &= 0xFF; - -#define MM1(x) do { \ - w = t[x] + cc + MUL15(t[(x) + 20], 608); \ - t[x] = w & 0x1FFF; \ - cc = w >> 13; \ - } while (0) - - MM1( 0); - MM1( 1); - MM1( 2); - MM1( 3); - MM1( 4); - MM1( 5); - MM1( 6); - MM1( 7); - MM1( 8); - MM1( 9); - MM1(10); - MM1(11); - MM1(12); - MM1(13); - MM1(14); - MM1(15); - MM1(16); - MM1(17); - MM1(18); - MM1(19); - -#undef MM1 - - cc = MUL15(w >> 8, 19); - t[19] &= 0xFF; - -#define MM2(x) do { \ - w = t[x] + cc; \ - d[x] = w & 0x1FFF; \ - cc = w >> 13; \ - } while (0) - - MM2( 0); - MM2( 1); - MM2( 2); - MM2( 3); - MM2( 4); - MM2( 5); - MM2( 6); - MM2( 7); - MM2( 8); - MM2( 9); - MM2(10); - MM2(11); - MM2(12); - MM2(13); - MM2(14); - MM2(15); - MM2(16); - MM2(17); - MM2(18); - MM2(19); - -#undef MM2 -} - -/* - * Perform a multiplication of two integers modulo 2^255-19. - * Operands are arrays of 20 words, each containing 13 bits of data, in - * little-endian order. Input value may be up to 2^256-1; on output, value - * fits on 256 bits and is lower than twice the modulus. - * - * f255_mul() is the general multiplication, f255_square() is specialised - * for squarings. - */ -#define f255_mul(d, a, b) f255_mulgen(d, a, b, 0) -#define f255_square(d, a) f255_mulgen(d, a, a, 1) - -/* - * Add two values in F255. Partial reduction is performed (down to less - * than twice the modulus). - */ -static void -f255_add(uint32_t *d, const uint32_t *a, const uint32_t *b) -{ - int i; - uint32_t cc, w; - - cc = 0; - for (i = 0; i < 20; i ++) { - w = a[i] + b[i] + cc; - d[i] = w & 0x1FFF; - cc = w >> 13; - } - cc = MUL15(w >> 8, 19); - d[19] &= 0xFF; - for (i = 0; i < 20; i ++) { - w = d[i] + cc; - d[i] = w & 0x1FFF; - cc = w >> 13; - } -} - -/* - * Subtract one value from another in F255. Partial reduction is - * performed (down to less than twice the modulus). - */ -static void -f255_sub(uint32_t *d, const uint32_t *a, const uint32_t *b) -{ - /* - * We actually compute a - b + 2*p, so that the final value is - * necessarily positive. - */ - int i; - uint32_t cc, w; - - cc = (uint32_t)-38; - for (i = 0; i < 20; i ++) { - w = a[i] - b[i] + cc; - d[i] = w & 0x1FFF; - cc = ARSH(w, 13); - } - cc = MUL15((w + 0x200) >> 8, 19); - d[19] &= 0xFF; - for (i = 0; i < 20; i ++) { - w = d[i] + cc; - d[i] = w & 0x1FFF; - cc = w >> 13; - } -} - -/* - * Multiply an integer by the 'A24' constant (121665). Partial reduction - * is performed (down to less than twice the modulus). - */ -static void -f255_mul_a24(uint32_t *d, const uint32_t *a) -{ - int i; - uint32_t cc, w; - - cc = 0; - for (i = 0; i < 20; i ++) { - w = MUL15(a[i], 121665) + cc; - d[i] = w & 0x1FFF; - cc = w >> 13; - } - cc = MUL15(w >> 8, 19); - d[19] &= 0xFF; - for (i = 0; i < 20; i ++) { - w = d[i] + cc; - d[i] = w & 0x1FFF; - cc = w >> 13; - } -} - -static const unsigned char GEN[] = { - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -static const unsigned char ORDER[] = { - 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF -}; - -static const unsigned char * -api_generator(int curve, size_t *len) -{ - (void)curve; - *len = 32; - return GEN; -} - -static const unsigned char * -api_order(int curve, size_t *len) -{ - (void)curve; - *len = 32; - return ORDER; -} - -static size_t -api_xoff(int curve, size_t *len) -{ - (void)curve; - *len = 32; - return 0; -} - -static void -cswap(uint32_t *a, uint32_t *b, uint32_t ctl) -{ - int i; - - ctl = -ctl; - for (i = 0; i < 20; i ++) { - uint32_t aw, bw, tw; - - aw = a[i]; - bw = b[i]; - tw = ctl & (aw ^ bw); - a[i] = aw ^ tw; - b[i] = bw ^ tw; - } -} - -static uint32_t -api_mul(unsigned char *G, size_t Glen, - const unsigned char *kb, size_t kblen, int curve) -{ - uint32_t x1[20], x2[20], x3[20], z2[20], z3[20]; - uint32_t a[20], aa[20], b[20], bb[20]; - uint32_t c[20], d[20], e[20], da[20], cb[20]; - unsigned char k[32]; - uint32_t swap; - int i; - - (void)curve; - - /* - * Points are encoded over exactly 32 bytes. Multipliers must fit - * in 32 bytes as well. - * RFC 7748 mandates that the high bit of the last point byte must - * be ignored/cleared. - */ - if (Glen != 32 || kblen > 32) { - return 0; - } - G[31] &= 0x7F; - - /* - * Initialise variables x1, x2, z2, x3 and z3. We set all of them - * into Montgomery representation. - */ - x1[19] = le8_to_le13(x1, G, 32); - memcpy(x3, x1, sizeof x1); - memset(z2, 0, sizeof z2); - memset(x2, 0, sizeof x2); - x2[0] = 1; - memset(z3, 0, sizeof z3); - z3[0] = 1; - - memcpy(k, kb, kblen); - memset(k + kblen, 0, (sizeof k) - kblen); - k[0] &= 0xF8; - k[31] &= 0x7F; - k[31] |= 0x40; - - /* obsolete - print_int("x1", x1); - */ - - swap = 0; - for (i = 254; i >= 0; i --) { - uint32_t kt; - - kt = (k[i >> 3] >> (i & 7)) & 1; - swap ^= kt; - cswap(x2, x3, swap); - cswap(z2, z3, swap); - swap = kt; - - /* obsolete - print_int("x2", x2); - print_int("z2", z2); - print_int("x3", x3); - print_int("z3", z3); - */ - - f255_add(a, x2, z2); - f255_square(aa, a); - f255_sub(b, x2, z2); - f255_square(bb, b); - f255_sub(e, aa, bb); - f255_add(c, x3, z3); - f255_sub(d, x3, z3); - f255_mul(da, d, a); - f255_mul(cb, c, b); - - /* obsolete - print_int("a ", a); - print_int("aa", aa); - print_int("b ", b); - print_int("bb", bb); - print_int("e ", e); - print_int("c ", c); - print_int("d ", d); - print_int("da", da); - print_int("cb", cb); - */ - - f255_add(x3, da, cb); - f255_square(x3, x3); - f255_sub(z3, da, cb); - f255_square(z3, z3); - f255_mul(z3, z3, x1); - f255_mul(x2, aa, bb); - f255_mul_a24(z2, e); - f255_add(z2, z2, aa); - f255_mul(z2, e, z2); - - /* obsolete - print_int("x2", x2); - print_int("z2", z2); - print_int("x3", x3); - print_int("z3", z3); - */ - } - cswap(x2, x3, swap); - cswap(z2, z3, swap); - - /* - * Inverse z2 with a modular exponentiation. This is a simple - * square-and-multiply algorithm; we mutualise most non-squarings - * since the exponent contains almost only ones. - */ - memcpy(a, z2, sizeof z2); - for (i = 0; i < 15; i ++) { - f255_square(a, a); - f255_mul(a, a, z2); - } - memcpy(b, a, sizeof a); - for (i = 0; i < 14; i ++) { - int j; - - for (j = 0; j < 16; j ++) { - f255_square(b, b); - } - f255_mul(b, b, a); - } - for (i = 14; i >= 0; i --) { - f255_square(b, b); - if ((0xFFEB >> i) & 1) { - f255_mul(b, z2, b); - } - } - f255_mul(x2, x2, b); - reduce_final_f255(x2); - le13_to_le8(G, 32, x2); - return 1; -} - -static size_t -api_mulgen(unsigned char *R, - const unsigned char *x, size_t xlen, int curve) -{ - const unsigned char *G; - size_t Glen; - - G = api_generator(curve, &Glen); - memcpy(R, G, Glen); - api_mul(R, Glen, x, xlen, curve); - return Glen; -} - -static uint32_t -api_muladd(unsigned char *A, const unsigned char *B, size_t len, - const unsigned char *x, size_t xlen, - const unsigned char *y, size_t ylen, int curve) -{ - /* - * We don't implement this method, since it is used for ECDSA - * only, and there is no ECDSA over Curve25519 (which instead - * uses EdDSA). - */ - (void)A; - (void)B; - (void)len; - (void)x; - (void)xlen; - (void)y; - (void)ylen; - (void)curve; - return 0; -} - -/* see bearssl_ec.h */ -const br_ec_impl br_ec_c25519_m15 = { - (uint32_t)0x20000000, - &api_generator, - &api_order, - &api_xoff, - &api_mul, - &api_mulgen, - &api_muladd -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ec_c25519_m31.c b/src/tls/bearssl/ec_c25519_m31.c deleted file mode 100644 index c1497bd25..000000000 --- a/src/tls/bearssl/ec_c25519_m31.c +++ /dev/null @@ -1,774 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* obsolete -#include -#include -static void -print_int(const char *name, const uint32_t *x) -{ - size_t u; - unsigned char tmp[40]; - - printf("%s = ", name); - for (u = 0; u < 9; u ++) { - if (x[u] > 0x3FFFFFFF) { - printf("INVALID:"); - for (u = 0; u < 9; u ++) { - printf(" %08X", x[u]); - } - printf("\n"); - return; - } - } - memset(tmp, 0, sizeof tmp); - for (u = 0; u < 9; u ++) { - uint64_t w; - int j, k; - - w = x[u]; - j = 30 * (int)u; - k = j & 7; - if (k != 0) { - w <<= k; - j -= k; - } - k = j >> 3; - for (j = 0; j < 8; j ++) { - tmp[39 - k - j] |= (unsigned char)w; - w >>= 8; - } - } - for (u = 8; u < 40; u ++) { - printf("%02X", tmp[u]); - } - printf("\n"); -} -*/ - -/* - * If BR_NO_ARITH_SHIFT is undefined, or defined to 0, then we _assume_ - * that right-shifting a signed negative integer copies the sign bit - * (arithmetic right-shift). This is "implementation-defined behaviour", - * i.e. it is not undefined, but it may differ between compilers. Each - * compiler is supposed to document its behaviour in that respect. GCC - * explicitly defines that an arithmetic right shift is used. We expect - * all other compilers to do the same, because underlying CPU offer an - * arithmetic right shift opcode that could not be used otherwise. - */ -#if BR_NO_ARITH_SHIFT -#define ARSH(x, n) (((uint32_t)(x) >> (n)) \ - | ((-((uint32_t)(x) >> 31)) << (32 - (n)))) -#else -#define ARSH(x, n) ((*(int32_t *)&(x)) >> (n)) -#endif - -/* - * Convert an integer from unsigned little-endian encoding to a sequence of - * 30-bit words in little-endian order. The final "partial" word is - * returned. - */ -static uint32_t -le8_to_le30(uint32_t *dst, const unsigned char *src, size_t len) -{ - uint32_t acc; - int acc_len; - - acc = 0; - acc_len = 0; - while (len -- > 0) { - uint32_t b; - - b = *src ++; - if (acc_len < 22) { - acc |= b << acc_len; - acc_len += 8; - } else { - *dst ++ = (acc | (b << acc_len)) & 0x3FFFFFFF; - acc = b >> (30 - acc_len); - acc_len -= 22; - } - } - return acc; -} - -/* - * Convert an integer (30-bit words, little-endian) to unsigned - * little-endian encoding. The total encoding length is provided; all - * the destination bytes will be filled. - */ -static void -le30_to_le8(unsigned char *dst, size_t len, const uint32_t *src) -{ - uint32_t acc; - int acc_len; - - acc = 0; - acc_len = 0; - while (len -- > 0) { - if (acc_len < 8) { - uint32_t w; - - w = *src ++; - *dst ++ = (unsigned char)(acc | (w << acc_len)); - acc = w >> (8 - acc_len); - acc_len += 22; - } else { - *dst ++ = (unsigned char)acc; - acc >>= 8; - acc_len -= 8; - } - } -} - -/* - * Multiply two integers. Source integers are represented as arrays of - * nine 30-bit words, for values up to 2^270-1. Result is encoded over - * 18 words of 30 bits each. - */ -static void -mul9(uint32_t *d, const uint32_t *a, const uint32_t *b) -{ - /* - * Maximum intermediate result is no more than - * 10376293531797946367, which fits in 64 bits. Reason: - * - * 10376293531797946367 = 9 * (2^30-1)^2 + 9663676406 - * 10376293531797946367 < 9663676407 * 2^30 - * - * Thus, adding together 9 products of 30-bit integers, with - * a carry of at most 9663676406, yields an integer that fits - * on 64 bits and generates a carry of at most 9663676406. - */ - uint64_t t[17]; - uint64_t cc; - int i; - - t[ 0] = MUL31(a[0], b[0]); - t[ 1] = MUL31(a[0], b[1]) - + MUL31(a[1], b[0]); - t[ 2] = MUL31(a[0], b[2]) - + MUL31(a[1], b[1]) - + MUL31(a[2], b[0]); - t[ 3] = MUL31(a[0], b[3]) - + MUL31(a[1], b[2]) - + MUL31(a[2], b[1]) - + MUL31(a[3], b[0]); - t[ 4] = MUL31(a[0], b[4]) - + MUL31(a[1], b[3]) - + MUL31(a[2], b[2]) - + MUL31(a[3], b[1]) - + MUL31(a[4], b[0]); - t[ 5] = MUL31(a[0], b[5]) - + MUL31(a[1], b[4]) - + MUL31(a[2], b[3]) - + MUL31(a[3], b[2]) - + MUL31(a[4], b[1]) - + MUL31(a[5], b[0]); - t[ 6] = MUL31(a[0], b[6]) - + MUL31(a[1], b[5]) - + MUL31(a[2], b[4]) - + MUL31(a[3], b[3]) - + MUL31(a[4], b[2]) - + MUL31(a[5], b[1]) - + MUL31(a[6], b[0]); - t[ 7] = MUL31(a[0], b[7]) - + MUL31(a[1], b[6]) - + MUL31(a[2], b[5]) - + MUL31(a[3], b[4]) - + MUL31(a[4], b[3]) - + MUL31(a[5], b[2]) - + MUL31(a[6], b[1]) - + MUL31(a[7], b[0]); - t[ 8] = MUL31(a[0], b[8]) - + MUL31(a[1], b[7]) - + MUL31(a[2], b[6]) - + MUL31(a[3], b[5]) - + MUL31(a[4], b[4]) - + MUL31(a[5], b[3]) - + MUL31(a[6], b[2]) - + MUL31(a[7], b[1]) - + MUL31(a[8], b[0]); - t[ 9] = MUL31(a[1], b[8]) - + MUL31(a[2], b[7]) - + MUL31(a[3], b[6]) - + MUL31(a[4], b[5]) - + MUL31(a[5], b[4]) - + MUL31(a[6], b[3]) - + MUL31(a[7], b[2]) - + MUL31(a[8], b[1]); - t[10] = MUL31(a[2], b[8]) - + MUL31(a[3], b[7]) - + MUL31(a[4], b[6]) - + MUL31(a[5], b[5]) - + MUL31(a[6], b[4]) - + MUL31(a[7], b[3]) - + MUL31(a[8], b[2]); - t[11] = MUL31(a[3], b[8]) - + MUL31(a[4], b[7]) - + MUL31(a[5], b[6]) - + MUL31(a[6], b[5]) - + MUL31(a[7], b[4]) - + MUL31(a[8], b[3]); - t[12] = MUL31(a[4], b[8]) - + MUL31(a[5], b[7]) - + MUL31(a[6], b[6]) - + MUL31(a[7], b[5]) - + MUL31(a[8], b[4]); - t[13] = MUL31(a[5], b[8]) - + MUL31(a[6], b[7]) - + MUL31(a[7], b[6]) - + MUL31(a[8], b[5]); - t[14] = MUL31(a[6], b[8]) - + MUL31(a[7], b[7]) - + MUL31(a[8], b[6]); - t[15] = MUL31(a[7], b[8]) - + MUL31(a[8], b[7]); - t[16] = MUL31(a[8], b[8]); - - /* - * Propagate carries. - */ - cc = 0; - for (i = 0; i < 17; i ++) { - uint64_t w; - - w = t[i] + cc; - d[i] = (uint32_t)w & 0x3FFFFFFF; - cc = w >> 30; - } - d[17] = (uint32_t)cc; -} - -/* - * Square a 270-bit integer, represented as an array of nine 30-bit words. - * Result uses 18 words of 30 bits each. - */ -static void -square9(uint32_t *d, const uint32_t *a) -{ - uint64_t t[17]; - uint64_t cc; - int i; - - t[ 0] = MUL31(a[0], a[0]); - t[ 1] = ((MUL31(a[0], a[1])) << 1); - t[ 2] = MUL31(a[1], a[1]) - + ((MUL31(a[0], a[2])) << 1); - t[ 3] = ((MUL31(a[0], a[3]) - + MUL31(a[1], a[2])) << 1); - t[ 4] = MUL31(a[2], a[2]) - + ((MUL31(a[0], a[4]) - + MUL31(a[1], a[3])) << 1); - t[ 5] = ((MUL31(a[0], a[5]) - + MUL31(a[1], a[4]) - + MUL31(a[2], a[3])) << 1); - t[ 6] = MUL31(a[3], a[3]) - + ((MUL31(a[0], a[6]) - + MUL31(a[1], a[5]) - + MUL31(a[2], a[4])) << 1); - t[ 7] = ((MUL31(a[0], a[7]) - + MUL31(a[1], a[6]) - + MUL31(a[2], a[5]) - + MUL31(a[3], a[4])) << 1); - t[ 8] = MUL31(a[4], a[4]) - + ((MUL31(a[0], a[8]) - + MUL31(a[1], a[7]) - + MUL31(a[2], a[6]) - + MUL31(a[3], a[5])) << 1); - t[ 9] = ((MUL31(a[1], a[8]) - + MUL31(a[2], a[7]) - + MUL31(a[3], a[6]) - + MUL31(a[4], a[5])) << 1); - t[10] = MUL31(a[5], a[5]) - + ((MUL31(a[2], a[8]) - + MUL31(a[3], a[7]) - + MUL31(a[4], a[6])) << 1); - t[11] = ((MUL31(a[3], a[8]) - + MUL31(a[4], a[7]) - + MUL31(a[5], a[6])) << 1); - t[12] = MUL31(a[6], a[6]) - + ((MUL31(a[4], a[8]) - + MUL31(a[5], a[7])) << 1); - t[13] = ((MUL31(a[5], a[8]) - + MUL31(a[6], a[7])) << 1); - t[14] = MUL31(a[7], a[7]) - + ((MUL31(a[6], a[8])) << 1); - t[15] = ((MUL31(a[7], a[8])) << 1); - t[16] = MUL31(a[8], a[8]); - - /* - * Propagate carries. - */ - cc = 0; - for (i = 0; i < 17; i ++) { - uint64_t w; - - w = t[i] + cc; - d[i] = (uint32_t)w & 0x3FFFFFFF; - cc = w >> 30; - } - d[17] = (uint32_t)cc; -} - -/* - * Perform a "final reduction" in field F255 (field for Curve25519) - * The source value must be less than twice the modulus. If the value - * is not lower than the modulus, then the modulus is subtracted and - * this function returns 1; otherwise, it leaves it untouched and it - * returns 0. - */ -static uint32_t -reduce_final_f255(uint32_t *d) -{ - uint32_t t[9]; - uint32_t cc; - int i; - - memcpy(t, d, sizeof t); - cc = 19; - for (i = 0; i < 9; i ++) { - uint32_t w; - - w = t[i] + cc; - cc = w >> 30; - t[i] = w & 0x3FFFFFFF; - } - cc = t[8] >> 15; - t[8] &= 0x7FFF; - CCOPY(cc, d, t, sizeof t); - return cc; -} - -/* - * Perform a multiplication of two integers modulo 2^255-19. - * Operands are arrays of 9 words, each containing 30 bits of data, in - * little-endian order. Input value may be up to 2^256-1; on output, value - * fits on 256 bits and is lower than twice the modulus. - */ -static void -f255_mul(uint32_t *d, const uint32_t *a, const uint32_t *b) -{ - uint32_t t[18]; - uint64_t cc, w; - int i; - - /* - * Compute raw multiplication. All result words fit in 30 bits - * each; upper word (t[17]) must fit on 2 bits, since the product - * of two 256-bit integers must fit on 512 bits. - */ - mul9(t, a, b); - - /* - * Modular reduction: each high word is added where necessary. - * Since the modulus is 2^255-19 and word 9 corresponds to - * offset 9*30 = 270, word 9+k must be added to word k with - * a factor of 19*2^15 = 622592. The extra bits in word 8 are also - * added that way. - */ - cc = MUL31(t[8] >> 15, 19); - t[8] &= 0x7FFF; - for (i = 0; i < 9; i ++) { - w = (uint64_t)t[i] + cc + MUL31(t[i + 9], 622592); - t[i] = (uint32_t)w & 0x3FFFFFFF; - cc = w >> 30; - } - cc = MUL31(w >> 15, 19); - t[8] &= 0x7FFF; - for (i = 0; i < 9; i ++) { - w = t[i] + cc; - d[i] = (uint32_t)w & 0x3FFFFFFF; - cc = w >> 30; - } -} - -/* - * Perform a squaring of an integer modulo 2^255-19. - * Operands are arrays of 9 words, each containing 30 bits of data, in - * little-endian order. Input value may be up to 2^256-1; on output, value - * fits on 256 bits and is lower than twice the modulus. - */ -static void -f255_square(uint32_t *d, const uint32_t *a) -{ - uint32_t t[18]; - uint64_t cc, w; - int i; - - /* - * Compute raw squaring. All result words fit in 30 bits - * each; upper word (t[17]) must fit on 2 bits, since the square - * of a 256-bit integers must fit on 512 bits. - */ - square9(t, a); - - /* - * Modular reduction: each high word is added where necessary. - * Since the modulus is 2^255-19 and word 9 corresponds to - * offset 9*30 = 270, word 9+k must be added to word k with - * a factor of 19*2^15 = 622592. The extra bits in word 8 are also - * added that way. - */ - cc = MUL31(t[8] >> 15, 19); - t[8] &= 0x7FFF; - for (i = 0; i < 9; i ++) { - w = (uint64_t)t[i] + cc + MUL31(t[i + 9], 622592); - t[i] = (uint32_t)w & 0x3FFFFFFF; - cc = w >> 30; - } - cc = MUL31(w >> 15, 19); - t[8] &= 0x7FFF; - for (i = 0; i < 9; i ++) { - w = t[i] + cc; - d[i] = (uint32_t)w & 0x3FFFFFFF; - cc = w >> 30; - } -} - -/* - * Add two values in F255. Partial reduction is performed (down to less - * than twice the modulus). - */ -static void -f255_add(uint32_t *d, const uint32_t *a, const uint32_t *b) -{ - /* - * Since operand words fit on 30 bits, we can use 32-bit - * variables throughout. - */ - int i; - uint32_t cc, w; - - cc = 0; - for (i = 0; i < 9; i ++) { - w = a[i] + b[i] + cc; - d[i] = w & 0x3FFFFFFF; - cc = w >> 30; - } - cc = MUL15(w >> 15, 19); - d[8] &= 0x7FFF; - for (i = 0; i < 9; i ++) { - w = d[i] + cc; - d[i] = w & 0x3FFFFFFF; - cc = w >> 30; - } -} - -/* - * Subtract one value from another in F255. Partial reduction is - * performed (down to less than twice the modulus). - */ -static void -f255_sub(uint32_t *d, const uint32_t *a, const uint32_t *b) -{ - /* - * We actually compute a - b + 2*p, so that the final value is - * necessarily positive. - */ - int i; - uint32_t cc, w; - - cc = (uint32_t)-38; - for (i = 0; i < 9; i ++) { - w = a[i] - b[i] + cc; - d[i] = w & 0x3FFFFFFF; - cc = ARSH(w, 30); - } - cc = MUL15((w + 0x10000) >> 15, 19); - d[8] &= 0x7FFF; - for (i = 0; i < 9; i ++) { - w = d[i] + cc; - d[i] = w & 0x3FFFFFFF; - cc = w >> 30; - } -} - -/* - * Multiply an integer by the 'A24' constant (121665). Partial reduction - * is performed (down to less than twice the modulus). - */ -static void -f255_mul_a24(uint32_t *d, const uint32_t *a) -{ - int i; - uint64_t cc, w; - - cc = 0; - for (i = 0; i < 9; i ++) { - w = MUL31(a[i], 121665) + cc; - d[i] = (uint32_t)w & 0x3FFFFFFF; - cc = w >> 30; - } - cc = MUL31((uint32_t)(w >> 15), 19); - d[8] &= 0x7FFF; - for (i = 0; i < 9; i ++) { - w = (uint64_t)d[i] + cc; - d[i] = w & 0x3FFFFFFF; - cc = w >> 30; - } -} - -static const unsigned char GEN[] = { - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -static const unsigned char ORDER[] = { - 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF -}; - -static const unsigned char * -api_generator(int curve, size_t *len) -{ - (void)curve; - *len = 32; - return GEN; -} - -static const unsigned char * -api_order(int curve, size_t *len) -{ - (void)curve; - *len = 32; - return ORDER; -} - -static size_t -api_xoff(int curve, size_t *len) -{ - (void)curve; - *len = 32; - return 0; -} - -static void -cswap(uint32_t *a, uint32_t *b, uint32_t ctl) -{ - int i; - - ctl = -ctl; - for (i = 0; i < 9; i ++) { - uint32_t aw, bw, tw; - - aw = a[i]; - bw = b[i]; - tw = ctl & (aw ^ bw); - a[i] = aw ^ tw; - b[i] = bw ^ tw; - } -} - -static uint32_t -api_mul(unsigned char *G, size_t Glen, - const unsigned char *kb, size_t kblen, int curve) -{ - uint32_t x1[9], x2[9], x3[9], z2[9], z3[9]; - uint32_t a[9], aa[9], b[9], bb[9]; - uint32_t c[9], d[9], e[9], da[9], cb[9]; - unsigned char k[32]; - uint32_t swap; - int i; - - (void)curve; - - /* - * Points are encoded over exactly 32 bytes. Multipliers must fit - * in 32 bytes as well. - * RFC 7748 mandates that the high bit of the last point byte must - * be ignored/cleared. - */ - if (Glen != 32 || kblen > 32) { - return 0; - } - G[31] &= 0x7F; - - /* - * Initialise variables x1, x2, z2, x3 and z3. We set all of them - * into Montgomery representation. - */ - x1[8] = le8_to_le30(x1, G, 32); - memcpy(x3, x1, sizeof x1); - memset(z2, 0, sizeof z2); - memset(x2, 0, sizeof x2); - x2[0] = 1; - memset(z3, 0, sizeof z3); - z3[0] = 1; - - memcpy(k, kb, kblen); - memset(k + kblen, 0, (sizeof k) - kblen); - k[0] &= 0xF8; - k[31] &= 0x7F; - k[31] |= 0x40; - - /* obsolete - print_int("x1", x1); - */ - - swap = 0; - for (i = 254; i >= 0; i --) { - uint32_t kt; - - kt = (k[i >> 3] >> (i & 7)) & 1; - swap ^= kt; - cswap(x2, x3, swap); - cswap(z2, z3, swap); - swap = kt; - - /* obsolete - print_int("x2", x2); - print_int("z2", z2); - print_int("x3", x3); - print_int("z3", z3); - */ - - f255_add(a, x2, z2); - f255_square(aa, a); - f255_sub(b, x2, z2); - f255_square(bb, b); - f255_sub(e, aa, bb); - f255_add(c, x3, z3); - f255_sub(d, x3, z3); - f255_mul(da, d, a); - f255_mul(cb, c, b); - - /* obsolete - print_int("a ", a); - print_int("aa", aa); - print_int("b ", b); - print_int("bb", bb); - print_int("e ", e); - print_int("c ", c); - print_int("d ", d); - print_int("da", da); - print_int("cb", cb); - */ - - f255_add(x3, da, cb); - f255_square(x3, x3); - f255_sub(z3, da, cb); - f255_square(z3, z3); - f255_mul(z3, z3, x1); - f255_mul(x2, aa, bb); - f255_mul_a24(z2, e); - f255_add(z2, z2, aa); - f255_mul(z2, e, z2); - - /* obsolete - print_int("x2", x2); - print_int("z2", z2); - print_int("x3", x3); - print_int("z3", z3); - */ - } - cswap(x2, x3, swap); - cswap(z2, z3, swap); - - /* - * Inverse z2 with a modular exponentiation. This is a simple - * square-and-multiply algorithm; we mutualise most non-squarings - * since the exponent contains almost only ones. - */ - memcpy(a, z2, sizeof z2); - for (i = 0; i < 15; i ++) { - f255_square(a, a); - f255_mul(a, a, z2); - } - memcpy(b, a, sizeof a); - for (i = 0; i < 14; i ++) { - int j; - - for (j = 0; j < 16; j ++) { - f255_square(b, b); - } - f255_mul(b, b, a); - } - for (i = 14; i >= 0; i --) { - f255_square(b, b); - if ((0xFFEB >> i) & 1) { - f255_mul(b, z2, b); - } - } - f255_mul(x2, x2, b); - reduce_final_f255(x2); - le30_to_le8(G, 32, x2); - return 1; -} - -static size_t -api_mulgen(unsigned char *R, - const unsigned char *x, size_t xlen, int curve) -{ - const unsigned char *G; - size_t Glen; - - G = api_generator(curve, &Glen); - memcpy(R, G, Glen); - api_mul(R, Glen, x, xlen, curve); - return Glen; -} - -static uint32_t -api_muladd(unsigned char *A, const unsigned char *B, size_t len, - const unsigned char *x, size_t xlen, - const unsigned char *y, size_t ylen, int curve) -{ - /* - * We don't implement this method, since it is used for ECDSA - * only, and there is no ECDSA over Curve25519 (which instead - * uses EdDSA). - */ - (void)A; - (void)B; - (void)len; - (void)x; - (void)xlen; - (void)y; - (void)ylen; - (void)curve; - return 0; -} - -/* see bearssl_ec.h */ -const br_ec_impl br_ec_c25519_m31 = { - (uint32_t)0x20000000, - &api_generator, - &api_order, - &api_xoff, - &api_mul, - &api_mulgen, - &api_muladd -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ec_curve25519.c b/src/tls/bearssl/ec_curve25519.c deleted file mode 100644 index b9318ef0b..000000000 --- a/src/tls/bearssl/ec_curve25519.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -static const unsigned char GEN[] = { - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -static const unsigned char ORDER[] = { - 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF -}; - -/* see inner.h */ -const br_ec_curve_def br_curve25519 = { - BR_EC_curve25519, - ORDER, sizeof ORDER, - GEN, sizeof GEN -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ec_default.c b/src/tls/bearssl/ec_default.c deleted file mode 100644 index d7d699d08..000000000 --- a/src/tls/bearssl/ec_default.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_ec.h */ -const br_ec_impl * -br_ec_get_default(void) -{ -#if BR_LOMUL - return &br_ec_all_m15; -#else - return &br_ec_all_m31; -#endif -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ec_keygen.c b/src/tls/bearssl/ec_keygen.c deleted file mode 100644 index 62e746905..000000000 --- a/src/tls/bearssl/ec_keygen.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_ec.h */ -size_t -br_ec_keygen(const br_prng_class **rng_ctx, - const br_ec_impl *impl, br_ec_private_key *sk, - void *kbuf, int curve) -{ - const unsigned char *order; - unsigned char *buf; - size_t len; - unsigned mask; - - if (curve < 0 || curve >= 32 - || ((impl->supported_curves >> curve) & 1) == 0) - { - return 0; - } - order = impl->order(curve, &len); - while (len > 0 && *order == 0) { - order ++; - len --; - } - if (kbuf == NULL || len == 0) { - return len; - } - mask = order[0]; - mask |= (mask >> 1); - mask |= (mask >> 2); - mask |= (mask >> 4); - - /* - * We generate sequences of random bits of the right size, until - * the value is strictly lower than the curve order (we also - * check for all-zero values, which are invalid). - */ - buf = kbuf; - for (;;) { - size_t u; - unsigned cc, zz; - - (*rng_ctx)->generate(rng_ctx, buf, len); - buf[0] &= mask; - cc = 0; - u = len; - zz = 0; - while (u -- > 0) { - cc = ((unsigned)(buf[u] - order[u] - cc) >> 8) & 1; - zz |= buf[u]; - } - if (cc != 0 && zz != 0) { - break; - } - } - - if (sk != NULL) { - sk->curve = curve; - sk->x = buf; - sk->xlen = len; - } - return len; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ec_p256_m15.c b/src/tls/bearssl/ec_p256_m15.c deleted file mode 100644 index 71709a68b..000000000 --- a/src/tls/bearssl/ec_p256_m15.c +++ /dev/null @@ -1,2135 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * If BR_NO_ARITH_SHIFT is undefined, or defined to 0, then we _assume_ - * that right-shifting a signed negative integer copies the sign bit - * (arithmetic right-shift). This is "implementation-defined behaviour", - * i.e. it is not undefined, but it may differ between compilers. Each - * compiler is supposed to document its behaviour in that respect. GCC - * explicitly defines that an arithmetic right shift is used. We expect - * all other compilers to do the same, because underlying CPU offer an - * arithmetic right shift opcode that could not be used otherwise. - */ -#if BR_NO_ARITH_SHIFT -#define ARSH(x, n) (((uint32_t)(x) >> (n)) \ - | ((-((uint32_t)(x) >> 31)) << (32 - (n)))) -#else -#define ARSH(x, n) ((*(int32_t *)&(x)) >> (n)) -#endif - -/* - * Convert an integer from unsigned big-endian encoding to a sequence of - * 13-bit words in little-endian order. The final "partial" word is - * returned. - */ -static uint32_t -be8_to_le13(uint32_t *dst, const unsigned char *src, size_t len) -{ - uint32_t acc; - int acc_len; - - acc = 0; - acc_len = 0; - while (len -- > 0) { - acc |= (uint32_t)src[len] << acc_len; - acc_len += 8; - if (acc_len >= 13) { - *dst ++ = acc & 0x1FFF; - acc >>= 13; - acc_len -= 13; - } - } - return acc; -} - -/* - * Convert an integer (13-bit words, little-endian) to unsigned - * big-endian encoding. The total encoding length is provided; all - * the destination bytes will be filled. - */ -static void -le13_to_be8(unsigned char *dst, size_t len, const uint32_t *src) -{ - uint32_t acc; - int acc_len; - - acc = 0; - acc_len = 0; - while (len -- > 0) { - if (acc_len < 8) { - acc |= (*src ++) << acc_len; - acc_len += 13; - } - dst[len] = (unsigned char)acc; - acc >>= 8; - acc_len -= 8; - } -} - -/* - * Normalise an array of words to a strict 13 bits per word. Returned - * value is the resulting carry. The source (w) and destination (d) - * arrays may be identical, but shall not overlap partially. - */ -static inline uint32_t -norm13(uint32_t *d, const uint32_t *w, size_t len) -{ - size_t u; - uint32_t cc; - - cc = 0; - for (u = 0; u < len; u ++) { - int32_t z; - - z = w[u] + cc; - d[u] = z & 0x1FFF; - cc = ARSH(z, 13); - } - return cc; -} - -/* - * mul20() multiplies two 260-bit integers together. Each word must fit - * on 13 bits; source operands use 20 words, destination operand - * receives 40 words. All overlaps allowed. - * - * square20() computes the square of a 260-bit integer. Each word must - * fit on 13 bits; source operand uses 20 words, destination operand - * receives 40 words. All overlaps allowed. - */ - -#if BR_SLOW_MUL15 - -static void -mul20(uint32_t *d, const uint32_t *a, const uint32_t *b) -{ - /* - * Two-level Karatsuba: turns a 20x20 multiplication into - * nine 5x5 multiplications. We use 13-bit words but do not - * propagate carries immediately, so words may expand: - * - * - First Karatsuba decomposition turns the 20x20 mul on - * 13-bit words into three 10x10 muls, two on 13-bit words - * and one on 14-bit words. - * - * - Second Karatsuba decomposition further splits these into: - * - * * four 5x5 muls on 13-bit words - * * four 5x5 muls on 14-bit words - * * one 5x5 mul on 15-bit words - * - * Highest word value is 8191, 16382 or 32764, for 13-bit, 14-bit - * or 15-bit words, respectively. - */ - uint32_t u[45], v[45], w[90]; - uint32_t cc; - int i; - -#define ZADD(dw, d_off, s1w, s1_off, s2w, s2_off) do { \ - (dw)[5 * (d_off) + 0] = (s1w)[5 * (s1_off) + 0] \ - + (s2w)[5 * (s2_off) + 0]; \ - (dw)[5 * (d_off) + 1] = (s1w)[5 * (s1_off) + 1] \ - + (s2w)[5 * (s2_off) + 1]; \ - (dw)[5 * (d_off) + 2] = (s1w)[5 * (s1_off) + 2] \ - + (s2w)[5 * (s2_off) + 2]; \ - (dw)[5 * (d_off) + 3] = (s1w)[5 * (s1_off) + 3] \ - + (s2w)[5 * (s2_off) + 3]; \ - (dw)[5 * (d_off) + 4] = (s1w)[5 * (s1_off) + 4] \ - + (s2w)[5 * (s2_off) + 4]; \ - } while (0) - -#define ZADDT(dw, d_off, sw, s_off) do { \ - (dw)[5 * (d_off) + 0] += (sw)[5 * (s_off) + 0]; \ - (dw)[5 * (d_off) + 1] += (sw)[5 * (s_off) + 1]; \ - (dw)[5 * (d_off) + 2] += (sw)[5 * (s_off) + 2]; \ - (dw)[5 * (d_off) + 3] += (sw)[5 * (s_off) + 3]; \ - (dw)[5 * (d_off) + 4] += (sw)[5 * (s_off) + 4]; \ - } while (0) - -#define ZSUB2F(dw, d_off, s1w, s1_off, s2w, s2_off) do { \ - (dw)[5 * (d_off) + 0] -= (s1w)[5 * (s1_off) + 0] \ - + (s2w)[5 * (s2_off) + 0]; \ - (dw)[5 * (d_off) + 1] -= (s1w)[5 * (s1_off) + 1] \ - + (s2w)[5 * (s2_off) + 1]; \ - (dw)[5 * (d_off) + 2] -= (s1w)[5 * (s1_off) + 2] \ - + (s2w)[5 * (s2_off) + 2]; \ - (dw)[5 * (d_off) + 3] -= (s1w)[5 * (s1_off) + 3] \ - + (s2w)[5 * (s2_off) + 3]; \ - (dw)[5 * (d_off) + 4] -= (s1w)[5 * (s1_off) + 4] \ - + (s2w)[5 * (s2_off) + 4]; \ - } while (0) - -#define CPR1(w, cprcc) do { \ - uint32_t cprz = (w) + cprcc; \ - (w) = cprz & 0x1FFF; \ - cprcc = cprz >> 13; \ - } while (0) - -#define CPR(dw, d_off) do { \ - uint32_t cprcc; \ - cprcc = 0; \ - CPR1((dw)[(d_off) + 0], cprcc); \ - CPR1((dw)[(d_off) + 1], cprcc); \ - CPR1((dw)[(d_off) + 2], cprcc); \ - CPR1((dw)[(d_off) + 3], cprcc); \ - CPR1((dw)[(d_off) + 4], cprcc); \ - CPR1((dw)[(d_off) + 5], cprcc); \ - CPR1((dw)[(d_off) + 6], cprcc); \ - CPR1((dw)[(d_off) + 7], cprcc); \ - CPR1((dw)[(d_off) + 8], cprcc); \ - (dw)[(d_off) + 9] = cprcc; \ - } while (0) - - memcpy(u, a, 20 * sizeof *a); - ZADD(u, 4, a, 0, a, 1); - ZADD(u, 5, a, 2, a, 3); - ZADD(u, 6, a, 0, a, 2); - ZADD(u, 7, a, 1, a, 3); - ZADD(u, 8, u, 6, u, 7); - - memcpy(v, b, 20 * sizeof *b); - ZADD(v, 4, b, 0, b, 1); - ZADD(v, 5, b, 2, b, 3); - ZADD(v, 6, b, 0, b, 2); - ZADD(v, 7, b, 1, b, 3); - ZADD(v, 8, v, 6, v, 7); - - /* - * Do the eight first 8x8 muls. Source words are at most 16382 - * each, so we can add product results together "as is" in 32-bit - * words. - */ - for (i = 0; i < 40; i += 5) { - w[(i << 1) + 0] = MUL15(u[i + 0], v[i + 0]); - w[(i << 1) + 1] = MUL15(u[i + 0], v[i + 1]) - + MUL15(u[i + 1], v[i + 0]); - w[(i << 1) + 2] = MUL15(u[i + 0], v[i + 2]) - + MUL15(u[i + 1], v[i + 1]) - + MUL15(u[i + 2], v[i + 0]); - w[(i << 1) + 3] = MUL15(u[i + 0], v[i + 3]) - + MUL15(u[i + 1], v[i + 2]) - + MUL15(u[i + 2], v[i + 1]) - + MUL15(u[i + 3], v[i + 0]); - w[(i << 1) + 4] = MUL15(u[i + 0], v[i + 4]) - + MUL15(u[i + 1], v[i + 3]) - + MUL15(u[i + 2], v[i + 2]) - + MUL15(u[i + 3], v[i + 1]) - + MUL15(u[i + 4], v[i + 0]); - w[(i << 1) + 5] = MUL15(u[i + 1], v[i + 4]) - + MUL15(u[i + 2], v[i + 3]) - + MUL15(u[i + 3], v[i + 2]) - + MUL15(u[i + 4], v[i + 1]); - w[(i << 1) + 6] = MUL15(u[i + 2], v[i + 4]) - + MUL15(u[i + 3], v[i + 3]) - + MUL15(u[i + 4], v[i + 2]); - w[(i << 1) + 7] = MUL15(u[i + 3], v[i + 4]) - + MUL15(u[i + 4], v[i + 3]); - w[(i << 1) + 8] = MUL15(u[i + 4], v[i + 4]); - w[(i << 1) + 9] = 0; - } - - /* - * For the 9th multiplication, source words are up to 32764, - * so we must do some carry propagation. If we add up to - * 4 products and the carry is no more than 524224, then the - * result fits in 32 bits, and the next carry will be no more - * than 524224 (because 4*(32764^2)+524224 < 8192*524225). - * - * We thus just skip one of the products in the middle word, - * then do a carry propagation (this reduces words to 13 bits - * each, except possibly the last, which may use up to 17 bits - * or so), then add the missing product. - */ - w[80 + 0] = MUL15(u[40 + 0], v[40 + 0]); - w[80 + 1] = MUL15(u[40 + 0], v[40 + 1]) - + MUL15(u[40 + 1], v[40 + 0]); - w[80 + 2] = MUL15(u[40 + 0], v[40 + 2]) - + MUL15(u[40 + 1], v[40 + 1]) - + MUL15(u[40 + 2], v[40 + 0]); - w[80 + 3] = MUL15(u[40 + 0], v[40 + 3]) - + MUL15(u[40 + 1], v[40 + 2]) - + MUL15(u[40 + 2], v[40 + 1]) - + MUL15(u[40 + 3], v[40 + 0]); - w[80 + 4] = MUL15(u[40 + 0], v[40 + 4]) - + MUL15(u[40 + 1], v[40 + 3]) - + MUL15(u[40 + 2], v[40 + 2]) - + MUL15(u[40 + 3], v[40 + 1]); - /* + MUL15(u[40 + 4], v[40 + 0]) */ - w[80 + 5] = MUL15(u[40 + 1], v[40 + 4]) - + MUL15(u[40 + 2], v[40 + 3]) - + MUL15(u[40 + 3], v[40 + 2]) - + MUL15(u[40 + 4], v[40 + 1]); - w[80 + 6] = MUL15(u[40 + 2], v[40 + 4]) - + MUL15(u[40 + 3], v[40 + 3]) - + MUL15(u[40 + 4], v[40 + 2]); - w[80 + 7] = MUL15(u[40 + 3], v[40 + 4]) - + MUL15(u[40 + 4], v[40 + 3]); - w[80 + 8] = MUL15(u[40 + 4], v[40 + 4]); - - CPR(w, 80); - - w[80 + 4] += MUL15(u[40 + 4], v[40 + 0]); - - /* - * The products on 14-bit words in slots 6 and 7 yield values - * up to 5*(16382^2) each, and we need to subtract two such - * values from the higher word. We need the subtraction to fit - * in a _signed_ 32-bit integer, i.e. 31 bits + a sign bit. - * However, 10*(16382^2) does not fit. So we must perform a - * bit of reduction here. - */ - CPR(w, 60); - CPR(w, 70); - - /* - * Recompose results. - */ - - /* 0..1*0..1 into 0..3 */ - ZSUB2F(w, 8, w, 0, w, 2); - ZSUB2F(w, 9, w, 1, w, 3); - ZADDT(w, 1, w, 8); - ZADDT(w, 2, w, 9); - - /* 2..3*2..3 into 4..7 */ - ZSUB2F(w, 10, w, 4, w, 6); - ZSUB2F(w, 11, w, 5, w, 7); - ZADDT(w, 5, w, 10); - ZADDT(w, 6, w, 11); - - /* (0..1+2..3)*(0..1+2..3) into 12..15 */ - ZSUB2F(w, 16, w, 12, w, 14); - ZSUB2F(w, 17, w, 13, w, 15); - ZADDT(w, 13, w, 16); - ZADDT(w, 14, w, 17); - - /* first-level recomposition */ - ZSUB2F(w, 12, w, 0, w, 4); - ZSUB2F(w, 13, w, 1, w, 5); - ZSUB2F(w, 14, w, 2, w, 6); - ZSUB2F(w, 15, w, 3, w, 7); - ZADDT(w, 2, w, 12); - ZADDT(w, 3, w, 13); - ZADDT(w, 4, w, 14); - ZADDT(w, 5, w, 15); - - /* - * Perform carry propagation to bring all words down to 13 bits. - */ - cc = norm13(d, w, 40); - d[39] += (cc << 13); - -#undef ZADD -#undef ZADDT -#undef ZSUB2F -#undef CPR1 -#undef CPR -} - -static inline void -square20(uint32_t *d, const uint32_t *a) -{ - mul20(d, a, a); -} - -#else - -static void -mul20(uint32_t *d, const uint32_t *a, const uint32_t *b) -{ - uint32_t t[39]; - - t[ 0] = MUL15(a[ 0], b[ 0]); - t[ 1] = MUL15(a[ 0], b[ 1]) - + MUL15(a[ 1], b[ 0]); - t[ 2] = MUL15(a[ 0], b[ 2]) - + MUL15(a[ 1], b[ 1]) - + MUL15(a[ 2], b[ 0]); - t[ 3] = MUL15(a[ 0], b[ 3]) - + MUL15(a[ 1], b[ 2]) - + MUL15(a[ 2], b[ 1]) - + MUL15(a[ 3], b[ 0]); - t[ 4] = MUL15(a[ 0], b[ 4]) - + MUL15(a[ 1], b[ 3]) - + MUL15(a[ 2], b[ 2]) - + MUL15(a[ 3], b[ 1]) - + MUL15(a[ 4], b[ 0]); - t[ 5] = MUL15(a[ 0], b[ 5]) - + MUL15(a[ 1], b[ 4]) - + MUL15(a[ 2], b[ 3]) - + MUL15(a[ 3], b[ 2]) - + MUL15(a[ 4], b[ 1]) - + MUL15(a[ 5], b[ 0]); - t[ 6] = MUL15(a[ 0], b[ 6]) - + MUL15(a[ 1], b[ 5]) - + MUL15(a[ 2], b[ 4]) - + MUL15(a[ 3], b[ 3]) - + MUL15(a[ 4], b[ 2]) - + MUL15(a[ 5], b[ 1]) - + MUL15(a[ 6], b[ 0]); - t[ 7] = MUL15(a[ 0], b[ 7]) - + MUL15(a[ 1], b[ 6]) - + MUL15(a[ 2], b[ 5]) - + MUL15(a[ 3], b[ 4]) - + MUL15(a[ 4], b[ 3]) - + MUL15(a[ 5], b[ 2]) - + MUL15(a[ 6], b[ 1]) - + MUL15(a[ 7], b[ 0]); - t[ 8] = MUL15(a[ 0], b[ 8]) - + MUL15(a[ 1], b[ 7]) - + MUL15(a[ 2], b[ 6]) - + MUL15(a[ 3], b[ 5]) - + MUL15(a[ 4], b[ 4]) - + MUL15(a[ 5], b[ 3]) - + MUL15(a[ 6], b[ 2]) - + MUL15(a[ 7], b[ 1]) - + MUL15(a[ 8], b[ 0]); - t[ 9] = MUL15(a[ 0], b[ 9]) - + MUL15(a[ 1], b[ 8]) - + MUL15(a[ 2], b[ 7]) - + MUL15(a[ 3], b[ 6]) - + MUL15(a[ 4], b[ 5]) - + MUL15(a[ 5], b[ 4]) - + MUL15(a[ 6], b[ 3]) - + MUL15(a[ 7], b[ 2]) - + MUL15(a[ 8], b[ 1]) - + MUL15(a[ 9], b[ 0]); - t[10] = MUL15(a[ 0], b[10]) - + MUL15(a[ 1], b[ 9]) - + MUL15(a[ 2], b[ 8]) - + MUL15(a[ 3], b[ 7]) - + MUL15(a[ 4], b[ 6]) - + MUL15(a[ 5], b[ 5]) - + MUL15(a[ 6], b[ 4]) - + MUL15(a[ 7], b[ 3]) - + MUL15(a[ 8], b[ 2]) - + MUL15(a[ 9], b[ 1]) - + MUL15(a[10], b[ 0]); - t[11] = MUL15(a[ 0], b[11]) - + MUL15(a[ 1], b[10]) - + MUL15(a[ 2], b[ 9]) - + MUL15(a[ 3], b[ 8]) - + MUL15(a[ 4], b[ 7]) - + MUL15(a[ 5], b[ 6]) - + MUL15(a[ 6], b[ 5]) - + MUL15(a[ 7], b[ 4]) - + MUL15(a[ 8], b[ 3]) - + MUL15(a[ 9], b[ 2]) - + MUL15(a[10], b[ 1]) - + MUL15(a[11], b[ 0]); - t[12] = MUL15(a[ 0], b[12]) - + MUL15(a[ 1], b[11]) - + MUL15(a[ 2], b[10]) - + MUL15(a[ 3], b[ 9]) - + MUL15(a[ 4], b[ 8]) - + MUL15(a[ 5], b[ 7]) - + MUL15(a[ 6], b[ 6]) - + MUL15(a[ 7], b[ 5]) - + MUL15(a[ 8], b[ 4]) - + MUL15(a[ 9], b[ 3]) - + MUL15(a[10], b[ 2]) - + MUL15(a[11], b[ 1]) - + MUL15(a[12], b[ 0]); - t[13] = MUL15(a[ 0], b[13]) - + MUL15(a[ 1], b[12]) - + MUL15(a[ 2], b[11]) - + MUL15(a[ 3], b[10]) - + MUL15(a[ 4], b[ 9]) - + MUL15(a[ 5], b[ 8]) - + MUL15(a[ 6], b[ 7]) - + MUL15(a[ 7], b[ 6]) - + MUL15(a[ 8], b[ 5]) - + MUL15(a[ 9], b[ 4]) - + MUL15(a[10], b[ 3]) - + MUL15(a[11], b[ 2]) - + MUL15(a[12], b[ 1]) - + MUL15(a[13], b[ 0]); - t[14] = MUL15(a[ 0], b[14]) - + MUL15(a[ 1], b[13]) - + MUL15(a[ 2], b[12]) - + MUL15(a[ 3], b[11]) - + MUL15(a[ 4], b[10]) - + MUL15(a[ 5], b[ 9]) - + MUL15(a[ 6], b[ 8]) - + MUL15(a[ 7], b[ 7]) - + MUL15(a[ 8], b[ 6]) - + MUL15(a[ 9], b[ 5]) - + MUL15(a[10], b[ 4]) - + MUL15(a[11], b[ 3]) - + MUL15(a[12], b[ 2]) - + MUL15(a[13], b[ 1]) - + MUL15(a[14], b[ 0]); - t[15] = MUL15(a[ 0], b[15]) - + MUL15(a[ 1], b[14]) - + MUL15(a[ 2], b[13]) - + MUL15(a[ 3], b[12]) - + MUL15(a[ 4], b[11]) - + MUL15(a[ 5], b[10]) - + MUL15(a[ 6], b[ 9]) - + MUL15(a[ 7], b[ 8]) - + MUL15(a[ 8], b[ 7]) - + MUL15(a[ 9], b[ 6]) - + MUL15(a[10], b[ 5]) - + MUL15(a[11], b[ 4]) - + MUL15(a[12], b[ 3]) - + MUL15(a[13], b[ 2]) - + MUL15(a[14], b[ 1]) - + MUL15(a[15], b[ 0]); - t[16] = MUL15(a[ 0], b[16]) - + MUL15(a[ 1], b[15]) - + MUL15(a[ 2], b[14]) - + MUL15(a[ 3], b[13]) - + MUL15(a[ 4], b[12]) - + MUL15(a[ 5], b[11]) - + MUL15(a[ 6], b[10]) - + MUL15(a[ 7], b[ 9]) - + MUL15(a[ 8], b[ 8]) - + MUL15(a[ 9], b[ 7]) - + MUL15(a[10], b[ 6]) - + MUL15(a[11], b[ 5]) - + MUL15(a[12], b[ 4]) - + MUL15(a[13], b[ 3]) - + MUL15(a[14], b[ 2]) - + MUL15(a[15], b[ 1]) - + MUL15(a[16], b[ 0]); - t[17] = MUL15(a[ 0], b[17]) - + MUL15(a[ 1], b[16]) - + MUL15(a[ 2], b[15]) - + MUL15(a[ 3], b[14]) - + MUL15(a[ 4], b[13]) - + MUL15(a[ 5], b[12]) - + MUL15(a[ 6], b[11]) - + MUL15(a[ 7], b[10]) - + MUL15(a[ 8], b[ 9]) - + MUL15(a[ 9], b[ 8]) - + MUL15(a[10], b[ 7]) - + MUL15(a[11], b[ 6]) - + MUL15(a[12], b[ 5]) - + MUL15(a[13], b[ 4]) - + MUL15(a[14], b[ 3]) - + MUL15(a[15], b[ 2]) - + MUL15(a[16], b[ 1]) - + MUL15(a[17], b[ 0]); - t[18] = MUL15(a[ 0], b[18]) - + MUL15(a[ 1], b[17]) - + MUL15(a[ 2], b[16]) - + MUL15(a[ 3], b[15]) - + MUL15(a[ 4], b[14]) - + MUL15(a[ 5], b[13]) - + MUL15(a[ 6], b[12]) - + MUL15(a[ 7], b[11]) - + MUL15(a[ 8], b[10]) - + MUL15(a[ 9], b[ 9]) - + MUL15(a[10], b[ 8]) - + MUL15(a[11], b[ 7]) - + MUL15(a[12], b[ 6]) - + MUL15(a[13], b[ 5]) - + MUL15(a[14], b[ 4]) - + MUL15(a[15], b[ 3]) - + MUL15(a[16], b[ 2]) - + MUL15(a[17], b[ 1]) - + MUL15(a[18], b[ 0]); - t[19] = MUL15(a[ 0], b[19]) - + MUL15(a[ 1], b[18]) - + MUL15(a[ 2], b[17]) - + MUL15(a[ 3], b[16]) - + MUL15(a[ 4], b[15]) - + MUL15(a[ 5], b[14]) - + MUL15(a[ 6], b[13]) - + MUL15(a[ 7], b[12]) - + MUL15(a[ 8], b[11]) - + MUL15(a[ 9], b[10]) - + MUL15(a[10], b[ 9]) - + MUL15(a[11], b[ 8]) - + MUL15(a[12], b[ 7]) - + MUL15(a[13], b[ 6]) - + MUL15(a[14], b[ 5]) - + MUL15(a[15], b[ 4]) - + MUL15(a[16], b[ 3]) - + MUL15(a[17], b[ 2]) - + MUL15(a[18], b[ 1]) - + MUL15(a[19], b[ 0]); - t[20] = MUL15(a[ 1], b[19]) - + MUL15(a[ 2], b[18]) - + MUL15(a[ 3], b[17]) - + MUL15(a[ 4], b[16]) - + MUL15(a[ 5], b[15]) - + MUL15(a[ 6], b[14]) - + MUL15(a[ 7], b[13]) - + MUL15(a[ 8], b[12]) - + MUL15(a[ 9], b[11]) - + MUL15(a[10], b[10]) - + MUL15(a[11], b[ 9]) - + MUL15(a[12], b[ 8]) - + MUL15(a[13], b[ 7]) - + MUL15(a[14], b[ 6]) - + MUL15(a[15], b[ 5]) - + MUL15(a[16], b[ 4]) - + MUL15(a[17], b[ 3]) - + MUL15(a[18], b[ 2]) - + MUL15(a[19], b[ 1]); - t[21] = MUL15(a[ 2], b[19]) - + MUL15(a[ 3], b[18]) - + MUL15(a[ 4], b[17]) - + MUL15(a[ 5], b[16]) - + MUL15(a[ 6], b[15]) - + MUL15(a[ 7], b[14]) - + MUL15(a[ 8], b[13]) - + MUL15(a[ 9], b[12]) - + MUL15(a[10], b[11]) - + MUL15(a[11], b[10]) - + MUL15(a[12], b[ 9]) - + MUL15(a[13], b[ 8]) - + MUL15(a[14], b[ 7]) - + MUL15(a[15], b[ 6]) - + MUL15(a[16], b[ 5]) - + MUL15(a[17], b[ 4]) - + MUL15(a[18], b[ 3]) - + MUL15(a[19], b[ 2]); - t[22] = MUL15(a[ 3], b[19]) - + MUL15(a[ 4], b[18]) - + MUL15(a[ 5], b[17]) - + MUL15(a[ 6], b[16]) - + MUL15(a[ 7], b[15]) - + MUL15(a[ 8], b[14]) - + MUL15(a[ 9], b[13]) - + MUL15(a[10], b[12]) - + MUL15(a[11], b[11]) - + MUL15(a[12], b[10]) - + MUL15(a[13], b[ 9]) - + MUL15(a[14], b[ 8]) - + MUL15(a[15], b[ 7]) - + MUL15(a[16], b[ 6]) - + MUL15(a[17], b[ 5]) - + MUL15(a[18], b[ 4]) - + MUL15(a[19], b[ 3]); - t[23] = MUL15(a[ 4], b[19]) - + MUL15(a[ 5], b[18]) - + MUL15(a[ 6], b[17]) - + MUL15(a[ 7], b[16]) - + MUL15(a[ 8], b[15]) - + MUL15(a[ 9], b[14]) - + MUL15(a[10], b[13]) - + MUL15(a[11], b[12]) - + MUL15(a[12], b[11]) - + MUL15(a[13], b[10]) - + MUL15(a[14], b[ 9]) - + MUL15(a[15], b[ 8]) - + MUL15(a[16], b[ 7]) - + MUL15(a[17], b[ 6]) - + MUL15(a[18], b[ 5]) - + MUL15(a[19], b[ 4]); - t[24] = MUL15(a[ 5], b[19]) - + MUL15(a[ 6], b[18]) - + MUL15(a[ 7], b[17]) - + MUL15(a[ 8], b[16]) - + MUL15(a[ 9], b[15]) - + MUL15(a[10], b[14]) - + MUL15(a[11], b[13]) - + MUL15(a[12], b[12]) - + MUL15(a[13], b[11]) - + MUL15(a[14], b[10]) - + MUL15(a[15], b[ 9]) - + MUL15(a[16], b[ 8]) - + MUL15(a[17], b[ 7]) - + MUL15(a[18], b[ 6]) - + MUL15(a[19], b[ 5]); - t[25] = MUL15(a[ 6], b[19]) - + MUL15(a[ 7], b[18]) - + MUL15(a[ 8], b[17]) - + MUL15(a[ 9], b[16]) - + MUL15(a[10], b[15]) - + MUL15(a[11], b[14]) - + MUL15(a[12], b[13]) - + MUL15(a[13], b[12]) - + MUL15(a[14], b[11]) - + MUL15(a[15], b[10]) - + MUL15(a[16], b[ 9]) - + MUL15(a[17], b[ 8]) - + MUL15(a[18], b[ 7]) - + MUL15(a[19], b[ 6]); - t[26] = MUL15(a[ 7], b[19]) - + MUL15(a[ 8], b[18]) - + MUL15(a[ 9], b[17]) - + MUL15(a[10], b[16]) - + MUL15(a[11], b[15]) - + MUL15(a[12], b[14]) - + MUL15(a[13], b[13]) - + MUL15(a[14], b[12]) - + MUL15(a[15], b[11]) - + MUL15(a[16], b[10]) - + MUL15(a[17], b[ 9]) - + MUL15(a[18], b[ 8]) - + MUL15(a[19], b[ 7]); - t[27] = MUL15(a[ 8], b[19]) - + MUL15(a[ 9], b[18]) - + MUL15(a[10], b[17]) - + MUL15(a[11], b[16]) - + MUL15(a[12], b[15]) - + MUL15(a[13], b[14]) - + MUL15(a[14], b[13]) - + MUL15(a[15], b[12]) - + MUL15(a[16], b[11]) - + MUL15(a[17], b[10]) - + MUL15(a[18], b[ 9]) - + MUL15(a[19], b[ 8]); - t[28] = MUL15(a[ 9], b[19]) - + MUL15(a[10], b[18]) - + MUL15(a[11], b[17]) - + MUL15(a[12], b[16]) - + MUL15(a[13], b[15]) - + MUL15(a[14], b[14]) - + MUL15(a[15], b[13]) - + MUL15(a[16], b[12]) - + MUL15(a[17], b[11]) - + MUL15(a[18], b[10]) - + MUL15(a[19], b[ 9]); - t[29] = MUL15(a[10], b[19]) - + MUL15(a[11], b[18]) - + MUL15(a[12], b[17]) - + MUL15(a[13], b[16]) - + MUL15(a[14], b[15]) - + MUL15(a[15], b[14]) - + MUL15(a[16], b[13]) - + MUL15(a[17], b[12]) - + MUL15(a[18], b[11]) - + MUL15(a[19], b[10]); - t[30] = MUL15(a[11], b[19]) - + MUL15(a[12], b[18]) - + MUL15(a[13], b[17]) - + MUL15(a[14], b[16]) - + MUL15(a[15], b[15]) - + MUL15(a[16], b[14]) - + MUL15(a[17], b[13]) - + MUL15(a[18], b[12]) - + MUL15(a[19], b[11]); - t[31] = MUL15(a[12], b[19]) - + MUL15(a[13], b[18]) - + MUL15(a[14], b[17]) - + MUL15(a[15], b[16]) - + MUL15(a[16], b[15]) - + MUL15(a[17], b[14]) - + MUL15(a[18], b[13]) - + MUL15(a[19], b[12]); - t[32] = MUL15(a[13], b[19]) - + MUL15(a[14], b[18]) - + MUL15(a[15], b[17]) - + MUL15(a[16], b[16]) - + MUL15(a[17], b[15]) - + MUL15(a[18], b[14]) - + MUL15(a[19], b[13]); - t[33] = MUL15(a[14], b[19]) - + MUL15(a[15], b[18]) - + MUL15(a[16], b[17]) - + MUL15(a[17], b[16]) - + MUL15(a[18], b[15]) - + MUL15(a[19], b[14]); - t[34] = MUL15(a[15], b[19]) - + MUL15(a[16], b[18]) - + MUL15(a[17], b[17]) - + MUL15(a[18], b[16]) - + MUL15(a[19], b[15]); - t[35] = MUL15(a[16], b[19]) - + MUL15(a[17], b[18]) - + MUL15(a[18], b[17]) - + MUL15(a[19], b[16]); - t[36] = MUL15(a[17], b[19]) - + MUL15(a[18], b[18]) - + MUL15(a[19], b[17]); - t[37] = MUL15(a[18], b[19]) - + MUL15(a[19], b[18]); - t[38] = MUL15(a[19], b[19]); - d[39] = norm13(d, t, 39); -} - -static void -square20(uint32_t *d, const uint32_t *a) -{ - uint32_t t[39]; - - t[ 0] = MUL15(a[ 0], a[ 0]); - t[ 1] = ((MUL15(a[ 0], a[ 1])) << 1); - t[ 2] = MUL15(a[ 1], a[ 1]) - + ((MUL15(a[ 0], a[ 2])) << 1); - t[ 3] = ((MUL15(a[ 0], a[ 3]) - + MUL15(a[ 1], a[ 2])) << 1); - t[ 4] = MUL15(a[ 2], a[ 2]) - + ((MUL15(a[ 0], a[ 4]) - + MUL15(a[ 1], a[ 3])) << 1); - t[ 5] = ((MUL15(a[ 0], a[ 5]) - + MUL15(a[ 1], a[ 4]) - + MUL15(a[ 2], a[ 3])) << 1); - t[ 6] = MUL15(a[ 3], a[ 3]) - + ((MUL15(a[ 0], a[ 6]) - + MUL15(a[ 1], a[ 5]) - + MUL15(a[ 2], a[ 4])) << 1); - t[ 7] = ((MUL15(a[ 0], a[ 7]) - + MUL15(a[ 1], a[ 6]) - + MUL15(a[ 2], a[ 5]) - + MUL15(a[ 3], a[ 4])) << 1); - t[ 8] = MUL15(a[ 4], a[ 4]) - + ((MUL15(a[ 0], a[ 8]) - + MUL15(a[ 1], a[ 7]) - + MUL15(a[ 2], a[ 6]) - + MUL15(a[ 3], a[ 5])) << 1); - t[ 9] = ((MUL15(a[ 0], a[ 9]) - + MUL15(a[ 1], a[ 8]) - + MUL15(a[ 2], a[ 7]) - + MUL15(a[ 3], a[ 6]) - + MUL15(a[ 4], a[ 5])) << 1); - t[10] = MUL15(a[ 5], a[ 5]) - + ((MUL15(a[ 0], a[10]) - + MUL15(a[ 1], a[ 9]) - + MUL15(a[ 2], a[ 8]) - + MUL15(a[ 3], a[ 7]) - + MUL15(a[ 4], a[ 6])) << 1); - t[11] = ((MUL15(a[ 0], a[11]) - + MUL15(a[ 1], a[10]) - + MUL15(a[ 2], a[ 9]) - + MUL15(a[ 3], a[ 8]) - + MUL15(a[ 4], a[ 7]) - + MUL15(a[ 5], a[ 6])) << 1); - t[12] = MUL15(a[ 6], a[ 6]) - + ((MUL15(a[ 0], a[12]) - + MUL15(a[ 1], a[11]) - + MUL15(a[ 2], a[10]) - + MUL15(a[ 3], a[ 9]) - + MUL15(a[ 4], a[ 8]) - + MUL15(a[ 5], a[ 7])) << 1); - t[13] = ((MUL15(a[ 0], a[13]) - + MUL15(a[ 1], a[12]) - + MUL15(a[ 2], a[11]) - + MUL15(a[ 3], a[10]) - + MUL15(a[ 4], a[ 9]) - + MUL15(a[ 5], a[ 8]) - + MUL15(a[ 6], a[ 7])) << 1); - t[14] = MUL15(a[ 7], a[ 7]) - + ((MUL15(a[ 0], a[14]) - + MUL15(a[ 1], a[13]) - + MUL15(a[ 2], a[12]) - + MUL15(a[ 3], a[11]) - + MUL15(a[ 4], a[10]) - + MUL15(a[ 5], a[ 9]) - + MUL15(a[ 6], a[ 8])) << 1); - t[15] = ((MUL15(a[ 0], a[15]) - + MUL15(a[ 1], a[14]) - + MUL15(a[ 2], a[13]) - + MUL15(a[ 3], a[12]) - + MUL15(a[ 4], a[11]) - + MUL15(a[ 5], a[10]) - + MUL15(a[ 6], a[ 9]) - + MUL15(a[ 7], a[ 8])) << 1); - t[16] = MUL15(a[ 8], a[ 8]) - + ((MUL15(a[ 0], a[16]) - + MUL15(a[ 1], a[15]) - + MUL15(a[ 2], a[14]) - + MUL15(a[ 3], a[13]) - + MUL15(a[ 4], a[12]) - + MUL15(a[ 5], a[11]) - + MUL15(a[ 6], a[10]) - + MUL15(a[ 7], a[ 9])) << 1); - t[17] = ((MUL15(a[ 0], a[17]) - + MUL15(a[ 1], a[16]) - + MUL15(a[ 2], a[15]) - + MUL15(a[ 3], a[14]) - + MUL15(a[ 4], a[13]) - + MUL15(a[ 5], a[12]) - + MUL15(a[ 6], a[11]) - + MUL15(a[ 7], a[10]) - + MUL15(a[ 8], a[ 9])) << 1); - t[18] = MUL15(a[ 9], a[ 9]) - + ((MUL15(a[ 0], a[18]) - + MUL15(a[ 1], a[17]) - + MUL15(a[ 2], a[16]) - + MUL15(a[ 3], a[15]) - + MUL15(a[ 4], a[14]) - + MUL15(a[ 5], a[13]) - + MUL15(a[ 6], a[12]) - + MUL15(a[ 7], a[11]) - + MUL15(a[ 8], a[10])) << 1); - t[19] = ((MUL15(a[ 0], a[19]) - + MUL15(a[ 1], a[18]) - + MUL15(a[ 2], a[17]) - + MUL15(a[ 3], a[16]) - + MUL15(a[ 4], a[15]) - + MUL15(a[ 5], a[14]) - + MUL15(a[ 6], a[13]) - + MUL15(a[ 7], a[12]) - + MUL15(a[ 8], a[11]) - + MUL15(a[ 9], a[10])) << 1); - t[20] = MUL15(a[10], a[10]) - + ((MUL15(a[ 1], a[19]) - + MUL15(a[ 2], a[18]) - + MUL15(a[ 3], a[17]) - + MUL15(a[ 4], a[16]) - + MUL15(a[ 5], a[15]) - + MUL15(a[ 6], a[14]) - + MUL15(a[ 7], a[13]) - + MUL15(a[ 8], a[12]) - + MUL15(a[ 9], a[11])) << 1); - t[21] = ((MUL15(a[ 2], a[19]) - + MUL15(a[ 3], a[18]) - + MUL15(a[ 4], a[17]) - + MUL15(a[ 5], a[16]) - + MUL15(a[ 6], a[15]) - + MUL15(a[ 7], a[14]) - + MUL15(a[ 8], a[13]) - + MUL15(a[ 9], a[12]) - + MUL15(a[10], a[11])) << 1); - t[22] = MUL15(a[11], a[11]) - + ((MUL15(a[ 3], a[19]) - + MUL15(a[ 4], a[18]) - + MUL15(a[ 5], a[17]) - + MUL15(a[ 6], a[16]) - + MUL15(a[ 7], a[15]) - + MUL15(a[ 8], a[14]) - + MUL15(a[ 9], a[13]) - + MUL15(a[10], a[12])) << 1); - t[23] = ((MUL15(a[ 4], a[19]) - + MUL15(a[ 5], a[18]) - + MUL15(a[ 6], a[17]) - + MUL15(a[ 7], a[16]) - + MUL15(a[ 8], a[15]) - + MUL15(a[ 9], a[14]) - + MUL15(a[10], a[13]) - + MUL15(a[11], a[12])) << 1); - t[24] = MUL15(a[12], a[12]) - + ((MUL15(a[ 5], a[19]) - + MUL15(a[ 6], a[18]) - + MUL15(a[ 7], a[17]) - + MUL15(a[ 8], a[16]) - + MUL15(a[ 9], a[15]) - + MUL15(a[10], a[14]) - + MUL15(a[11], a[13])) << 1); - t[25] = ((MUL15(a[ 6], a[19]) - + MUL15(a[ 7], a[18]) - + MUL15(a[ 8], a[17]) - + MUL15(a[ 9], a[16]) - + MUL15(a[10], a[15]) - + MUL15(a[11], a[14]) - + MUL15(a[12], a[13])) << 1); - t[26] = MUL15(a[13], a[13]) - + ((MUL15(a[ 7], a[19]) - + MUL15(a[ 8], a[18]) - + MUL15(a[ 9], a[17]) - + MUL15(a[10], a[16]) - + MUL15(a[11], a[15]) - + MUL15(a[12], a[14])) << 1); - t[27] = ((MUL15(a[ 8], a[19]) - + MUL15(a[ 9], a[18]) - + MUL15(a[10], a[17]) - + MUL15(a[11], a[16]) - + MUL15(a[12], a[15]) - + MUL15(a[13], a[14])) << 1); - t[28] = MUL15(a[14], a[14]) - + ((MUL15(a[ 9], a[19]) - + MUL15(a[10], a[18]) - + MUL15(a[11], a[17]) - + MUL15(a[12], a[16]) - + MUL15(a[13], a[15])) << 1); - t[29] = ((MUL15(a[10], a[19]) - + MUL15(a[11], a[18]) - + MUL15(a[12], a[17]) - + MUL15(a[13], a[16]) - + MUL15(a[14], a[15])) << 1); - t[30] = MUL15(a[15], a[15]) - + ((MUL15(a[11], a[19]) - + MUL15(a[12], a[18]) - + MUL15(a[13], a[17]) - + MUL15(a[14], a[16])) << 1); - t[31] = ((MUL15(a[12], a[19]) - + MUL15(a[13], a[18]) - + MUL15(a[14], a[17]) - + MUL15(a[15], a[16])) << 1); - t[32] = MUL15(a[16], a[16]) - + ((MUL15(a[13], a[19]) - + MUL15(a[14], a[18]) - + MUL15(a[15], a[17])) << 1); - t[33] = ((MUL15(a[14], a[19]) - + MUL15(a[15], a[18]) - + MUL15(a[16], a[17])) << 1); - t[34] = MUL15(a[17], a[17]) - + ((MUL15(a[15], a[19]) - + MUL15(a[16], a[18])) << 1); - t[35] = ((MUL15(a[16], a[19]) - + MUL15(a[17], a[18])) << 1); - t[36] = MUL15(a[18], a[18]) - + ((MUL15(a[17], a[19])) << 1); - t[37] = ((MUL15(a[18], a[19])) << 1); - t[38] = MUL15(a[19], a[19]); - d[39] = norm13(d, t, 39); -} - -#endif - -/* - * Modulus for field F256 (field for point coordinates in curve P-256). - */ -static const uint32_t F256[] = { - 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x001F, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0400, 0x0000, - 0x0000, 0x1FF8, 0x1FFF, 0x01FF -}; - -/* - * The 'b' curve equation coefficient for P-256. - */ -static const uint32_t P256_B[] = { - 0x004B, 0x1E93, 0x0F89, 0x1C78, 0x03BC, 0x187B, 0x114E, 0x1619, - 0x1D06, 0x0328, 0x01AF, 0x0D31, 0x1557, 0x15DE, 0x1ECF, 0x127C, - 0x0A3A, 0x0EC5, 0x118D, 0x00B5 -}; - -/* - * Perform a "short reduction" in field F256 (field for curve P-256). - * The source value should be less than 262 bits; on output, it will - * be at most 257 bits, and less than twice the modulus. - */ -static void -reduce_f256(uint32_t *d) -{ - uint32_t x; - - x = d[19] >> 9; - d[19] &= 0x01FF; - d[17] += x << 3; - d[14] -= x << 10; - d[7] -= x << 5; - d[0] += x; - norm13(d, d, 20); -} - -/* - * Perform a "final reduction" in field F256 (field for curve P-256). - * The source value must be less than twice the modulus. If the value - * is not lower than the modulus, then the modulus is subtracted and - * this function returns 1; otherwise, it leaves it untouched and it - * returns 0. - */ -static uint32_t -reduce_final_f256(uint32_t *d) -{ - uint32_t t[20]; - uint32_t cc; - int i; - - memcpy(t, d, sizeof t); - cc = 0; - for (i = 0; i < 20; i ++) { - uint32_t w; - - w = t[i] - F256[i] - cc; - cc = w >> 31; - t[i] = w & 0x1FFF; - } - cc ^= 1; - CCOPY(cc, d, t, sizeof t); - return cc; -} - -/* - * Perform a multiplication of two integers modulo - * 2^256-2^224+2^192+2^96-1 (for NIST curve P-256). Operands are arrays - * of 20 words, each containing 13 bits of data, in little-endian order. - * On input, upper word may be up to 13 bits (hence value up to 2^260-1); - * on output, value fits on 257 bits and is lower than twice the modulus. - */ -static void -mul_f256(uint32_t *d, const uint32_t *a, const uint32_t *b) -{ - uint32_t t[40], cc; - int i; - - /* - * Compute raw multiplication. All result words fit in 13 bits - * each. - */ - mul20(t, a, b); - - /* - * Modular reduction: each high word in added/subtracted where - * necessary. - * - * The modulus is: - * p = 2^256 - 2^224 + 2^192 + 2^96 - 1 - * Therefore: - * 2^256 = 2^224 - 2^192 - 2^96 + 1 mod p - * - * For a word x at bit offset n (n >= 256), we have: - * x*2^n = x*2^(n-32) - x*2^(n-64) - * - x*2^(n - 160) + x*2^(n-256) mod p - * - * Thus, we can nullify the high word if we reinject it at some - * proper emplacements. - */ - for (i = 39; i >= 20; i --) { - uint32_t x; - - x = t[i]; - t[i - 2] += ARSH(x, 6); - t[i - 3] += (x << 7) & 0x1FFF; - t[i - 4] -= ARSH(x, 12); - t[i - 5] -= (x << 1) & 0x1FFF; - t[i - 12] -= ARSH(x, 4); - t[i - 13] -= (x << 9) & 0x1FFF; - t[i - 19] += ARSH(x, 9); - t[i - 20] += (x << 4) & 0x1FFF; - } - - /* - * Propagate carries. This is a signed propagation, and the - * result may be negative. The loop above may enlarge values, - * but not two much: worst case is the chain involving t[i - 3], - * in which a value may be added to itself up to 7 times. Since - * starting values are 13-bit each, all words fit on 20 bits - * (21 to account for the sign bit). - */ - cc = norm13(t, t, 20); - - /* - * Perform modular reduction again for the bits beyond 256 (the carry - * and the bits 256..259). Since the largest shift below is by 10 - * bits, and the values fit on 21 bits, values fit in 32-bit words, - * thereby allowing injecting full word values. - */ - cc = (cc << 4) | (t[19] >> 9); - t[19] &= 0x01FF; - t[17] += cc << 3; - t[14] -= cc << 10; - t[7] -= cc << 5; - t[0] += cc; - - /* - * If the carry is negative, then after carry propagation, we may - * end up with a value which is negative, and we don't want that. - * Thus, in that case, we add the modulus. Note that the subtraction - * result, when the carry is negative, is always smaller than the - * modulus, so the extra addition will not make the value exceed - * twice the modulus. - */ - cc >>= 31; - t[0] -= cc; - t[7] += cc << 5; - t[14] += cc << 10; - t[17] -= cc << 3; - t[19] += cc << 9; - - norm13(d, t, 20); -} - -/* - * Square an integer modulo 2^256-2^224+2^192+2^96-1 (for NIST curve - * P-256). Operand is an array of 20 words, each containing 13 bits of - * data, in little-endian order. On input, upper word may be up to 13 - * bits (hence value up to 2^260-1); on output, value fits on 257 bits - * and is lower than twice the modulus. - */ -static void -square_f256(uint32_t *d, const uint32_t *a) -{ - uint32_t t[40], cc; - int i; - - /* - * Compute raw square. All result words fit in 13 bits each. - */ - square20(t, a); - - /* - * Modular reduction: each high word in added/subtracted where - * necessary. - * - * The modulus is: - * p = 2^256 - 2^224 + 2^192 + 2^96 - 1 - * Therefore: - * 2^256 = 2^224 - 2^192 - 2^96 + 1 mod p - * - * For a word x at bit offset n (n >= 256), we have: - * x*2^n = x*2^(n-32) - x*2^(n-64) - * - x*2^(n - 160) + x*2^(n-256) mod p - * - * Thus, we can nullify the high word if we reinject it at some - * proper emplacements. - */ - for (i = 39; i >= 20; i --) { - uint32_t x; - - x = t[i]; - t[i - 2] += ARSH(x, 6); - t[i - 3] += (x << 7) & 0x1FFF; - t[i - 4] -= ARSH(x, 12); - t[i - 5] -= (x << 1) & 0x1FFF; - t[i - 12] -= ARSH(x, 4); - t[i - 13] -= (x << 9) & 0x1FFF; - t[i - 19] += ARSH(x, 9); - t[i - 20] += (x << 4) & 0x1FFF; - } - - /* - * Propagate carries. This is a signed propagation, and the - * result may be negative. The loop above may enlarge values, - * but not two much: worst case is the chain involving t[i - 3], - * in which a value may be added to itself up to 7 times. Since - * starting values are 13-bit each, all words fit on 20 bits - * (21 to account for the sign bit). - */ - cc = norm13(t, t, 20); - - /* - * Perform modular reduction again for the bits beyond 256 (the carry - * and the bits 256..259). Since the largest shift below is by 10 - * bits, and the values fit on 21 bits, values fit in 32-bit words, - * thereby allowing injecting full word values. - */ - cc = (cc << 4) | (t[19] >> 9); - t[19] &= 0x01FF; - t[17] += cc << 3; - t[14] -= cc << 10; - t[7] -= cc << 5; - t[0] += cc; - - /* - * If the carry is negative, then after carry propagation, we may - * end up with a value which is negative, and we don't want that. - * Thus, in that case, we add the modulus. Note that the subtraction - * result, when the carry is negative, is always smaller than the - * modulus, so the extra addition will not make the value exceed - * twice the modulus. - */ - cc >>= 31; - t[0] -= cc; - t[7] += cc << 5; - t[14] += cc << 10; - t[17] -= cc << 3; - t[19] += cc << 9; - - norm13(d, t, 20); -} - -/* - * Jacobian coordinates for a point in P-256: affine coordinates (X,Y) - * are such that: - * X = x / z^2 - * Y = y / z^3 - * For the point at infinity, z = 0. - * Each point thus admits many possible representations. - * - * Coordinates are represented in arrays of 32-bit integers, each holding - * 13 bits of data. Values may also be slightly greater than the modulus, - * but they will always be lower than twice the modulus. - */ -typedef struct { - uint32_t x[20]; - uint32_t y[20]; - uint32_t z[20]; -} p256_jacobian; - -/* - * Convert a point to affine coordinates: - * - If the point is the point at infinity, then all three coordinates - * are set to 0. - * - Otherwise, the 'z' coordinate is set to 1, and the 'x' and 'y' - * coordinates are the 'X' and 'Y' affine coordinates. - * The coordinates are guaranteed to be lower than the modulus. - */ -static void -p256_to_affine(p256_jacobian *P) -{ - uint32_t t1[20], t2[20]; - int i; - - /* - * Invert z with a modular exponentiation: the modulus is - * p = 2^256 - 2^224 + 2^192 + 2^96 - 1, and the exponent is - * p-2. Exponent bit pattern (from high to low) is: - * - 32 bits of value 1 - * - 31 bits of value 0 - * - 1 bit of value 1 - * - 96 bits of value 0 - * - 94 bits of value 1 - * - 1 bit of value 0 - * - 1 bit of value 1 - * Thus, we precompute z^(2^31-1) to speed things up. - * - * If z = 0 (point at infinity) then the modular exponentiation - * will yield 0, which leads to the expected result (all three - * coordinates set to 0). - */ - - /* - * A simple square-and-multiply for z^(2^31-1). We could save about - * two dozen multiplications here with an addition chain, but - * this would require a bit more code, and extra stack buffers. - */ - memcpy(t1, P->z, sizeof P->z); - for (i = 0; i < 30; i ++) { - square_f256(t1, t1); - mul_f256(t1, t1, P->z); - } - - /* - * Square-and-multiply. Apart from the squarings, we have a few - * multiplications to set bits to 1; we multiply by the original z - * for setting 1 bit, and by t1 for setting 31 bits. - */ - memcpy(t2, P->z, sizeof P->z); - for (i = 1; i < 256; i ++) { - square_f256(t2, t2); - switch (i) { - case 31: - case 190: - case 221: - case 252: - mul_f256(t2, t2, t1); - break; - case 63: - case 253: - case 255: - mul_f256(t2, t2, P->z); - break; - } - } - - /* - * Now that we have 1/z, multiply x by 1/z^2 and y by 1/z^3. - */ - mul_f256(t1, t2, t2); - mul_f256(P->x, t1, P->x); - mul_f256(t1, t1, t2); - mul_f256(P->y, t1, P->y); - reduce_final_f256(P->x); - reduce_final_f256(P->y); - - /* - * Multiply z by 1/z. If z = 0, then this will yield 0, otherwise - * this will set z to 1. - */ - mul_f256(P->z, P->z, t2); - reduce_final_f256(P->z); -} - -/* - * Double a point in P-256. This function works for all valid points, - * including the point at infinity. - */ -static void -p256_double(p256_jacobian *Q) -{ - /* - * Doubling formulas are: - * - * s = 4*x*y^2 - * m = 3*(x + z^2)*(x - z^2) - * x' = m^2 - 2*s - * y' = m*(s - x') - 8*y^4 - * z' = 2*y*z - * - * These formulas work for all points, including points of order 2 - * and points at infinity: - * - If y = 0 then z' = 0. But there is no such point in P-256 - * anyway. - * - If z = 0 then z' = 0. - */ - uint32_t t1[20], t2[20], t3[20], t4[20]; - int i; - - /* - * Compute z^2 in t1. - */ - square_f256(t1, Q->z); - - /* - * Compute x-z^2 in t2 and x+z^2 in t1. - */ - for (i = 0; i < 20; i ++) { - t2[i] = (F256[i] << 1) + Q->x[i] - t1[i]; - t1[i] += Q->x[i]; - } - norm13(t1, t1, 20); - norm13(t2, t2, 20); - - /* - * Compute 3*(x+z^2)*(x-z^2) in t1. - */ - mul_f256(t3, t1, t2); - for (i = 0; i < 20; i ++) { - t1[i] = MUL15(3, t3[i]); - } - norm13(t1, t1, 20); - - /* - * Compute 4*x*y^2 (in t2) and 2*y^2 (in t3). - */ - square_f256(t3, Q->y); - for (i = 0; i < 20; i ++) { - t3[i] <<= 1; - } - norm13(t3, t3, 20); - mul_f256(t2, Q->x, t3); - for (i = 0; i < 20; i ++) { - t2[i] <<= 1; - } - norm13(t2, t2, 20); - reduce_f256(t2); - - /* - * Compute x' = m^2 - 2*s. - */ - square_f256(Q->x, t1); - for (i = 0; i < 20; i ++) { - Q->x[i] += (F256[i] << 2) - (t2[i] << 1); - } - norm13(Q->x, Q->x, 20); - reduce_f256(Q->x); - - /* - * Compute z' = 2*y*z. - */ - mul_f256(t4, Q->y, Q->z); - for (i = 0; i < 20; i ++) { - Q->z[i] = t4[i] << 1; - } - norm13(Q->z, Q->z, 20); - reduce_f256(Q->z); - - /* - * Compute y' = m*(s - x') - 8*y^4. Note that we already have - * 2*y^2 in t3. - */ - for (i = 0; i < 20; i ++) { - t2[i] += (F256[i] << 1) - Q->x[i]; - } - norm13(t2, t2, 20); - mul_f256(Q->y, t1, t2); - square_f256(t4, t3); - for (i = 0; i < 20; i ++) { - Q->y[i] += (F256[i] << 2) - (t4[i] << 1); - } - norm13(Q->y, Q->y, 20); - reduce_f256(Q->y); -} - -/* - * Add point P2 to point P1. - * - * This function computes the wrong result in the following cases: - * - * - If P1 == 0 but P2 != 0 - * - If P1 != 0 but P2 == 0 - * - If P1 == P2 - * - * In all three cases, P1 is set to the point at infinity. - * - * Returned value is 0 if one of the following occurs: - * - * - P1 and P2 have the same Y coordinate - * - P1 == 0 and P2 == 0 - * - The Y coordinate of one of the points is 0 and the other point is - * the point at infinity. - * - * The third case cannot actually happen with valid points, since a point - * with Y == 0 is a point of order 2, and there is no point of order 2 on - * curve P-256. - * - * Therefore, assuming that P1 != 0 and P2 != 0 on input, then the caller - * can apply the following: - * - * - If the result is not the point at infinity, then it is correct. - * - Otherwise, if the returned value is 1, then this is a case of - * P1+P2 == 0, so the result is indeed the point at infinity. - * - Otherwise, P1 == P2, so a "double" operation should have been - * performed. - */ -static uint32_t -p256_add(p256_jacobian *P1, const p256_jacobian *P2) -{ - /* - * Addtions formulas are: - * - * u1 = x1 * z2^2 - * u2 = x2 * z1^2 - * s1 = y1 * z2^3 - * s2 = y2 * z1^3 - * h = u2 - u1 - * r = s2 - s1 - * x3 = r^2 - h^3 - 2 * u1 * h^2 - * y3 = r * (u1 * h^2 - x3) - s1 * h^3 - * z3 = h * z1 * z2 - */ - uint32_t t1[20], t2[20], t3[20], t4[20], t5[20], t6[20], t7[20]; - uint32_t ret; - int i; - - /* - * Compute u1 = x1*z2^2 (in t1) and s1 = y1*z2^3 (in t3). - */ - square_f256(t3, P2->z); - mul_f256(t1, P1->x, t3); - mul_f256(t4, P2->z, t3); - mul_f256(t3, P1->y, t4); - - /* - * Compute u2 = x2*z1^2 (in t2) and s2 = y2*z1^3 (in t4). - */ - square_f256(t4, P1->z); - mul_f256(t2, P2->x, t4); - mul_f256(t5, P1->z, t4); - mul_f256(t4, P2->y, t5); - - /* - * Compute h = h2 - u1 (in t2) and r = s2 - s1 (in t4). - * We need to test whether r is zero, so we will do some extra - * reduce. - */ - for (i = 0; i < 20; i ++) { - t2[i] += (F256[i] << 1) - t1[i]; - t4[i] += (F256[i] << 1) - t3[i]; - } - norm13(t2, t2, 20); - norm13(t4, t4, 20); - reduce_f256(t4); - reduce_final_f256(t4); - ret = 0; - for (i = 0; i < 20; i ++) { - ret |= t4[i]; - } - ret = (ret | -ret) >> 31; - - /* - * Compute u1*h^2 (in t6) and h^3 (in t5); - */ - square_f256(t7, t2); - mul_f256(t6, t1, t7); - mul_f256(t5, t7, t2); - - /* - * Compute x3 = r^2 - h^3 - 2*u1*h^2. - */ - square_f256(P1->x, t4); - for (i = 0; i < 20; i ++) { - P1->x[i] += (F256[i] << 3) - t5[i] - (t6[i] << 1); - } - norm13(P1->x, P1->x, 20); - reduce_f256(P1->x); - - /* - * Compute y3 = r*(u1*h^2 - x3) - s1*h^3. - */ - for (i = 0; i < 20; i ++) { - t6[i] += (F256[i] << 1) - P1->x[i]; - } - norm13(t6, t6, 20); - mul_f256(P1->y, t4, t6); - mul_f256(t1, t5, t3); - for (i = 0; i < 20; i ++) { - P1->y[i] += (F256[i] << 1) - t1[i]; - } - norm13(P1->y, P1->y, 20); - reduce_f256(P1->y); - - /* - * Compute z3 = h*z1*z2. - */ - mul_f256(t1, P1->z, P2->z); - mul_f256(P1->z, t1, t2); - - return ret; -} - -/* - * Add point P2 to point P1. This is a specialised function for the - * case when P2 is a non-zero point in affine coordinate. - * - * This function computes the wrong result in the following cases: - * - * - If P1 == 0 - * - If P1 == P2 - * - * In both cases, P1 is set to the point at infinity. - * - * Returned value is 0 if one of the following occurs: - * - * - P1 and P2 have the same Y coordinate - * - The Y coordinate of P2 is 0 and P1 is the point at infinity. - * - * The second case cannot actually happen with valid points, since a point - * with Y == 0 is a point of order 2, and there is no point of order 2 on - * curve P-256. - * - * Therefore, assuming that P1 != 0 on input, then the caller - * can apply the following: - * - * - If the result is not the point at infinity, then it is correct. - * - Otherwise, if the returned value is 1, then this is a case of - * P1+P2 == 0, so the result is indeed the point at infinity. - * - Otherwise, P1 == P2, so a "double" operation should have been - * performed. - */ -static uint32_t -p256_add_mixed(p256_jacobian *P1, const p256_jacobian *P2) -{ - /* - * Addtions formulas are: - * - * u1 = x1 - * u2 = x2 * z1^2 - * s1 = y1 - * s2 = y2 * z1^3 - * h = u2 - u1 - * r = s2 - s1 - * x3 = r^2 - h^3 - 2 * u1 * h^2 - * y3 = r * (u1 * h^2 - x3) - s1 * h^3 - * z3 = h * z1 - */ - uint32_t t1[20], t2[20], t3[20], t4[20], t5[20], t6[20], t7[20]; - uint32_t ret; - int i; - - /* - * Compute u1 = x1 (in t1) and s1 = y1 (in t3). - */ - memcpy(t1, P1->x, sizeof t1); - memcpy(t3, P1->y, sizeof t3); - - /* - * Compute u2 = x2*z1^2 (in t2) and s2 = y2*z1^3 (in t4). - */ - square_f256(t4, P1->z); - mul_f256(t2, P2->x, t4); - mul_f256(t5, P1->z, t4); - mul_f256(t4, P2->y, t5); - - /* - * Compute h = h2 - u1 (in t2) and r = s2 - s1 (in t4). - * We need to test whether r is zero, so we will do some extra - * reduce. - */ - for (i = 0; i < 20; i ++) { - t2[i] += (F256[i] << 1) - t1[i]; - t4[i] += (F256[i] << 1) - t3[i]; - } - norm13(t2, t2, 20); - norm13(t4, t4, 20); - reduce_f256(t4); - reduce_final_f256(t4); - ret = 0; - for (i = 0; i < 20; i ++) { - ret |= t4[i]; - } - ret = (ret | -ret) >> 31; - - /* - * Compute u1*h^2 (in t6) and h^3 (in t5); - */ - square_f256(t7, t2); - mul_f256(t6, t1, t7); - mul_f256(t5, t7, t2); - - /* - * Compute x3 = r^2 - h^3 - 2*u1*h^2. - */ - square_f256(P1->x, t4); - for (i = 0; i < 20; i ++) { - P1->x[i] += (F256[i] << 3) - t5[i] - (t6[i] << 1); - } - norm13(P1->x, P1->x, 20); - reduce_f256(P1->x); - - /* - * Compute y3 = r*(u1*h^2 - x3) - s1*h^3. - */ - for (i = 0; i < 20; i ++) { - t6[i] += (F256[i] << 1) - P1->x[i]; - } - norm13(t6, t6, 20); - mul_f256(P1->y, t4, t6); - mul_f256(t1, t5, t3); - for (i = 0; i < 20; i ++) { - P1->y[i] += (F256[i] << 1) - t1[i]; - } - norm13(P1->y, P1->y, 20); - reduce_f256(P1->y); - - /* - * Compute z3 = h*z1*z2. - */ - mul_f256(P1->z, P1->z, t2); - - return ret; -} - -/* - * Decode a P-256 point. This function does not support the point at - * infinity. Returned value is 0 if the point is invalid, 1 otherwise. - */ -static uint32_t -p256_decode(p256_jacobian *P, const void *src, size_t len) -{ - const unsigned char *buf; - uint32_t tx[20], ty[20], t1[20], t2[20]; - uint32_t bad; - int i; - - if (len != 65) { - return 0; - } - buf = src; - - /* - * First byte must be 0x04 (uncompressed format). We could support - * "hybrid format" (first byte is 0x06 or 0x07, and encodes the - * least significant bit of the Y coordinate), but it is explicitly - * forbidden by RFC 5480 (section 2.2). - */ - bad = NEQ(buf[0], 0x04); - - /* - * Decode the coordinates, and check that they are both lower - * than the modulus. - */ - tx[19] = be8_to_le13(tx, buf + 1, 32); - ty[19] = be8_to_le13(ty, buf + 33, 32); - bad |= reduce_final_f256(tx); - bad |= reduce_final_f256(ty); - - /* - * Check curve equation. - */ - square_f256(t1, tx); - mul_f256(t1, tx, t1); - square_f256(t2, ty); - for (i = 0; i < 20; i ++) { - t1[i] += (F256[i] << 3) - MUL15(3, tx[i]) + P256_B[i] - t2[i]; - } - norm13(t1, t1, 20); - reduce_f256(t1); - reduce_final_f256(t1); - for (i = 0; i < 20; i ++) { - bad |= t1[i]; - } - - /* - * Copy coordinates to the point structure. - */ - memcpy(P->x, tx, sizeof tx); - memcpy(P->y, ty, sizeof ty); - memset(P->z, 0, sizeof P->z); - P->z[0] = 1; - return NEQ(bad, 0) ^ 1; -} - -/* - * Encode a point into a buffer. This function assumes that the point is - * valid, in affine coordinates, and not the point at infinity. - */ -static void -p256_encode(void *dst, const p256_jacobian *P) -{ - unsigned char *buf; - - buf = dst; - buf[0] = 0x04; - le13_to_be8(buf + 1, 32, P->x); - le13_to_be8(buf + 33, 32, P->y); -} - -/* - * Multiply a curve point by an integer. The integer is assumed to be - * lower than the curve order, and the base point must not be the point - * at infinity. - */ -static void -p256_mul(p256_jacobian *P, const unsigned char *x, size_t xlen) -{ - /* - * qz is a flag that is initially 1, and remains equal to 1 - * as long as the point is the point at infinity. - * - * We use a 2-bit window to handle multiplier bits by pairs. - * The precomputed window really is the points P2 and P3. - */ - uint32_t qz; - p256_jacobian P2, P3, Q, T, U; - - /* - * Compute window values. - */ - P2 = *P; - p256_double(&P2); - P3 = *P; - p256_add(&P3, &P2); - - /* - * We start with Q = 0. We process multiplier bits 2 by 2. - */ - memset(&Q, 0, sizeof Q); - qz = 1; - while (xlen -- > 0) { - int k; - - for (k = 6; k >= 0; k -= 2) { - uint32_t bits; - uint32_t bnz; - - p256_double(&Q); - p256_double(&Q); - T = *P; - U = Q; - bits = (*x >> k) & (uint32_t)3; - bnz = NEQ(bits, 0); - CCOPY(EQ(bits, 2), &T, &P2, sizeof T); - CCOPY(EQ(bits, 3), &T, &P3, sizeof T); - p256_add(&U, &T); - CCOPY(bnz & qz, &Q, &T, sizeof Q); - CCOPY(bnz & ~qz, &Q, &U, sizeof Q); - qz &= ~bnz; - } - x ++; - } - *P = Q; -} - -/* - * Precomputed window: k*G points, where G is the curve generator, and k - * is an integer from 1 to 15 (inclusive). The X and Y coordinates of - * the point are encoded as 20 words of 13 bits each (little-endian - * order); 13-bit words are then grouped 2-by-2 into 32-bit words - * (little-endian order within each word). - */ -static const uint32_t Gwin[15][20] = { - - { 0x04C60296, 0x02721176, 0x19D00F4A, 0x102517AC, - 0x13B8037D, 0x0748103C, 0x1E730E56, 0x08481FE2, - 0x0F97012C, 0x00D605F4, 0x1DFA11F5, 0x0C801A0D, - 0x0F670CBB, 0x0AED0CC5, 0x115E0E33, 0x181F0785, - 0x13F514A7, 0x0FF30E3B, 0x17171E1A, 0x009F18D0 }, - - { 0x1B341978, 0x16911F11, 0x0D9A1A60, 0x1C4E1FC8, - 0x1E040969, 0x096A06B0, 0x091C0030, 0x09EF1A29, - 0x18C40D03, 0x00F91C9E, 0x13C313D1, 0x096F0748, - 0x011419E0, 0x1CC713A6, 0x1DD31DAD, 0x1EE80C36, - 0x1ECD0C69, 0x1A0800A4, 0x08861B8E, 0x000E1DD5 }, - - { 0x173F1D6C, 0x02CC06F1, 0x14C21FB4, 0x043D1EB6, - 0x0F3606B7, 0x1A971C59, 0x1BF71951, 0x01481323, - 0x068D0633, 0x00BD12F9, 0x13EA1032, 0x136209E8, - 0x1C1E19A7, 0x06C7013E, 0x06C10AB0, 0x14C908BB, - 0x05830CE1, 0x1FEF18DD, 0x00620998, 0x010E0D19 }, - - { 0x18180852, 0x0604111A, 0x0B771509, 0x1B6F0156, - 0x00181FE2, 0x1DCC0AF4, 0x16EF0659, 0x11F70E80, - 0x11A912D0, 0x01C414D2, 0x027618C6, 0x05840FC6, - 0x100215C4, 0x187E0C3B, 0x12771C96, 0x150C0B5D, - 0x0FF705FD, 0x07981C67, 0x1AD20C63, 0x01C11C55 }, - - { 0x1E8113ED, 0x0A940370, 0x12920215, 0x1FA31D6F, - 0x1F7C0C82, 0x10CD03F7, 0x02640560, 0x081A0B5E, - 0x1BD21151, 0x00A21642, 0x0D0B0DA4, 0x0176113F, - 0x04440D1D, 0x001A1360, 0x1068012F, 0x1F141E49, - 0x10DF136B, 0x0E4F162B, 0x0D44104A, 0x01C1105F }, - - { 0x011411A9, 0x01551A4F, 0x0ADA0C6B, 0x01BD0EC8, - 0x18120C74, 0x112F1778, 0x099202CB, 0x0C05124B, - 0x195316A4, 0x01600685, 0x1E3B1FE2, 0x189014E3, - 0x0B5E1FD7, 0x0E0311F8, 0x08E000F7, 0x174E00DE, - 0x160702DF, 0x1B5A15BF, 0x03A11237, 0x01D01704 }, - - { 0x0C3D12A3, 0x0C501C0C, 0x17AD1300, 0x1715003F, - 0x03F719F8, 0x18031ED8, 0x1D980667, 0x0F681896, - 0x1B7D00BF, 0x011C14CE, 0x0FA000B4, 0x1C3501B0, - 0x0D901C55, 0x06790C10, 0x029E0736, 0x0DEB0400, - 0x034F183A, 0x030619B4, 0x0DEF0033, 0x00E71AC7 }, - - { 0x1B7D1393, 0x1B3B1076, 0x0BED1B4D, 0x13011F3A, - 0x0E0E1238, 0x156A132B, 0x013A02D3, 0x160A0D01, - 0x1CED1EE9, 0x00C5165D, 0x184C157E, 0x08141A83, - 0x153C0DA5, 0x1ED70F9D, 0x05170D51, 0x02CF13B8, - 0x18AE1771, 0x1B04113F, 0x05EC11E9, 0x015A16B3 }, - - { 0x04A41EE0, 0x1D1412E4, 0x1C591D79, 0x118511B7, - 0x14F00ACB, 0x1AE31E1C, 0x049C0D51, 0x016E061E, - 0x1DB71EDF, 0x01D41A35, 0x0E8208FA, 0x14441293, - 0x011F1E85, 0x1D54137A, 0x026B114F, 0x151D0832, - 0x00A50964, 0x1F9C1E1C, 0x064B12C9, 0x005409D1 }, - - { 0x062B123F, 0x0C0D0501, 0x183704C3, 0x08E31120, - 0x0A2E0A6C, 0x14440FED, 0x090A0D1E, 0x13271964, - 0x0B590A3A, 0x019D1D9B, 0x05780773, 0x09770A91, - 0x0F770CA3, 0x053F19D4, 0x02C80DED, 0x1A761304, - 0x091E0DD9, 0x15D201B8, 0x151109AA, 0x010F0198 }, - - { 0x05E101D1, 0x072314DD, 0x045F1433, 0x1A041541, - 0x10B3142E, 0x01840736, 0x1C1B19DB, 0x098B0418, - 0x1DBC083B, 0x007D1444, 0x01511740, 0x11DD1F3A, - 0x04ED0E2F, 0x1B4B1A62, 0x10480D04, 0x09E911A2, - 0x04211AFA, 0x19140893, 0x04D60CC4, 0x01210648 }, - - { 0x112703C4, 0x018B1BA1, 0x164C1D50, 0x05160BE0, - 0x0BCC1830, 0x01CB1554, 0x13291732, 0x1B2B1918, - 0x0DED0817, 0x00E80775, 0x0A2401D3, 0x0BFE08B3, - 0x0E531199, 0x058616E9, 0x04770B91, 0x110F0C55, - 0x19C11554, 0x0BFB1159, 0x03541C38, 0x000E1C2D }, - - { 0x10390C01, 0x02BB0751, 0x0AC5098E, 0x096C17AB, - 0x03C90E28, 0x10BD18BF, 0x002E1F2D, 0x092B0986, - 0x1BD700AC, 0x002E1F20, 0x1E3D1FD8, 0x077718BB, - 0x06F919C4, 0x187407ED, 0x11370E14, 0x081E139C, - 0x00481ADB, 0x14AB0289, 0x066A0EBE, 0x00C70ED6 }, - - { 0x0694120B, 0x124E1CC9, 0x0E2F0570, 0x17CF081A, - 0x078906AC, 0x066D17CF, 0x1B3207F4, 0x0C5705E9, - 0x10001C38, 0x00A919DE, 0x06851375, 0x0F900BD8, - 0x080401BA, 0x0EEE0D42, 0x1B8B11EA, 0x0B4519F0, - 0x090F18C0, 0x062E1508, 0x0DD909F4, 0x01EB067C }, - - { 0x0CDC1D5F, 0x0D1818F9, 0x07781636, 0x125B18E8, - 0x0D7003AF, 0x13110099, 0x1D9B1899, 0x175C1EB7, - 0x0E34171A, 0x01E01153, 0x081A0F36, 0x0B391783, - 0x1D1F147E, 0x19CE16D7, 0x11511B21, 0x1F2C10F9, - 0x12CA0E51, 0x05A31D39, 0x171A192E, 0x016B0E4F } -}; - -/* - * Lookup one of the Gwin[] values, by index. This is constant-time. - */ -static void -lookup_Gwin(p256_jacobian *T, uint32_t idx) -{ - uint32_t xy[20]; - uint32_t k; - size_t u; - - memset(xy, 0, sizeof xy); - for (k = 0; k < 15; k ++) { - uint32_t m; - - m = -EQ(idx, k + 1); - for (u = 0; u < 20; u ++) { - xy[u] |= m & Gwin[k][u]; - } - } - for (u = 0; u < 10; u ++) { - T->x[(u << 1) + 0] = xy[u] & 0xFFFF; - T->x[(u << 1) + 1] = xy[u] >> 16; - T->y[(u << 1) + 0] = xy[u + 10] & 0xFFFF; - T->y[(u << 1) + 1] = xy[u + 10] >> 16; - } - memset(T->z, 0, sizeof T->z); - T->z[0] = 1; -} - -/* - * Multiply the generator by an integer. The integer is assumed non-zero - * and lower than the curve order. - */ -static void -p256_mulgen(p256_jacobian *P, const unsigned char *x, size_t xlen) -{ - /* - * qz is a flag that is initially 1, and remains equal to 1 - * as long as the point is the point at infinity. - * - * We use a 4-bit window to handle multiplier bits by groups - * of 4. The precomputed window is constant static data, with - * points in affine coordinates; we use a constant-time lookup. - */ - p256_jacobian Q; - uint32_t qz; - - memset(&Q, 0, sizeof Q); - qz = 1; - while (xlen -- > 0) { - int k; - unsigned bx; - - bx = *x ++; - for (k = 0; k < 2; k ++) { - uint32_t bits; - uint32_t bnz; - p256_jacobian T, U; - - p256_double(&Q); - p256_double(&Q); - p256_double(&Q); - p256_double(&Q); - bits = (bx >> 4) & 0x0F; - bnz = NEQ(bits, 0); - lookup_Gwin(&T, bits); - U = Q; - p256_add_mixed(&U, &T); - CCOPY(bnz & qz, &Q, &T, sizeof Q); - CCOPY(bnz & ~qz, &Q, &U, sizeof Q); - qz &= ~bnz; - bx <<= 4; - } - } - *P = Q; -} - -static const unsigned char P256_G[] = { - 0x04, 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, - 0xBC, 0xE6, 0xE5, 0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, - 0x81, 0x2D, 0xEB, 0x33, 0xA0, 0xF4, 0xA1, 0x39, 0x45, 0xD8, - 0x98, 0xC2, 0x96, 0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, - 0x9B, 0x8E, 0xE7, 0xEB, 0x4A, 0x7C, 0x0F, 0x9E, 0x16, 0x2B, - 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE, 0xCB, 0xB6, 0x40, - 0x68, 0x37, 0xBF, 0x51, 0xF5 -}; - -static const unsigned char P256_N[] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, - 0xA7, 0x17, 0x9E, 0x84, 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, - 0x25, 0x51 -}; - -static const unsigned char * -api_generator(int curve, size_t *len) -{ - (void)curve; - *len = sizeof P256_G; - return P256_G; -} - -static const unsigned char * -api_order(int curve, size_t *len) -{ - (void)curve; - *len = sizeof P256_N; - return P256_N; -} - -static size_t -api_xoff(int curve, size_t *len) -{ - (void)curve; - *len = 32; - return 1; -} - -static uint32_t -api_mul(unsigned char *G, size_t Glen, - const unsigned char *x, size_t xlen, int curve) -{ - uint32_t r; - p256_jacobian P; - - (void)curve; - r = p256_decode(&P, G, Glen); - p256_mul(&P, x, xlen); - if (Glen >= 65) { - p256_to_affine(&P); - p256_encode(G, &P); - } - return r; -} - -static size_t -api_mulgen(unsigned char *R, - const unsigned char *x, size_t xlen, int curve) -{ - p256_jacobian P; - - (void)curve; - p256_mulgen(&P, x, xlen); - p256_to_affine(&P); - p256_encode(R, &P); - return 65; - - /* - const unsigned char *G; - size_t Glen; - - G = api_generator(curve, &Glen); - memcpy(R, G, Glen); - api_mul(R, Glen, x, xlen, curve); - return Glen; - */ -} - -static uint32_t -api_muladd(unsigned char *A, const unsigned char *B, size_t len, - const unsigned char *x, size_t xlen, - const unsigned char *y, size_t ylen, int curve) -{ - p256_jacobian P, Q; - uint32_t r, t, z; - int i; - - (void)curve; - r = p256_decode(&P, A, len); - p256_mul(&P, x, xlen); - if (B == NULL) { - p256_mulgen(&Q, y, ylen); - } else { - r &= p256_decode(&Q, B, len); - p256_mul(&Q, y, ylen); - } - - /* - * The final addition may fail in case both points are equal. - */ - t = p256_add(&P, &Q); - reduce_final_f256(P.z); - z = 0; - for (i = 0; i < 20; i ++) { - z |= P.z[i]; - } - z = EQ(z, 0); - p256_double(&Q); - - /* - * If z is 1 then either P+Q = 0 (t = 1) or P = Q (t = 0). So we - * have the following: - * - * z = 0, t = 0 return P (normal addition) - * z = 0, t = 1 return P (normal addition) - * z = 1, t = 0 return Q (a 'double' case) - * z = 1, t = 1 report an error (P+Q = 0) - */ - CCOPY(z & ~t, &P, &Q, sizeof Q); - p256_to_affine(&P); - p256_encode(A, &P); - r &= ~(z & t); - return r; -} - -/* see bearssl_ec.h */ -const br_ec_impl br_ec_p256_m15 = { - (uint32_t)0x00800000, - &api_generator, - &api_order, - &api_xoff, - &api_mul, - &api_mulgen, - &api_muladd -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ec_p256_m31.c b/src/tls/bearssl/ec_p256_m31.c deleted file mode 100644 index 9e7e83fea..000000000 --- a/src/tls/bearssl/ec_p256_m31.c +++ /dev/null @@ -1,1480 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * If BR_NO_ARITH_SHIFT is undefined, or defined to 0, then we _assume_ - * that right-shifting a signed negative integer copies the sign bit - * (arithmetic right-shift). This is "implementation-defined behaviour", - * i.e. it is not undefined, but it may differ between compilers. Each - * compiler is supposed to document its behaviour in that respect. GCC - * explicitly defines that an arithmetic right shift is used. We expect - * all other compilers to do the same, because underlying CPU offer an - * arithmetic right shift opcode that could not be used otherwise. - */ -#if BR_NO_ARITH_SHIFT -#define ARSH(x, n) (((uint32_t)(x) >> (n)) \ - | ((-((uint32_t)(x) >> 31)) << (32 - (n)))) -#define ARSHW(x, n) (((uint64_t)(x) >> (n)) \ - | ((-((uint64_t)(x) >> 63)) << (64 - (n)))) -#else -#define ARSH(x, n) ((*(int32_t *)&(x)) >> (n)) -#define ARSHW(x, n) ((*(int64_t *)&(x)) >> (n)) -#endif - -/* - * Convert an integer from unsigned big-endian encoding to a sequence of - * 30-bit words in little-endian order. The final "partial" word is - * returned. - */ -static uint32_t -be8_to_le30(uint32_t *dst, const unsigned char *src, size_t len) -{ - uint32_t acc; - int acc_len; - - acc = 0; - acc_len = 0; - while (len -- > 0) { - uint32_t b; - - b = src[len]; - if (acc_len < 22) { - acc |= b << acc_len; - acc_len += 8; - } else { - *dst ++ = (acc | (b << acc_len)) & 0x3FFFFFFF; - acc = b >> (30 - acc_len); - acc_len -= 22; - } - } - return acc; -} - -/* - * Convert an integer (30-bit words, little-endian) to unsigned - * big-endian encoding. The total encoding length is provided; all - * the destination bytes will be filled. - */ -static void -le30_to_be8(unsigned char *dst, size_t len, const uint32_t *src) -{ - uint32_t acc; - int acc_len; - - acc = 0; - acc_len = 0; - while (len -- > 0) { - if (acc_len < 8) { - uint32_t w; - - w = *src ++; - dst[len] = (unsigned char)(acc | (w << acc_len)); - acc = w >> (8 - acc_len); - acc_len += 22; - } else { - dst[len] = (unsigned char)acc; - acc >>= 8; - acc_len -= 8; - } - } -} - -/* - * Multiply two integers. Source integers are represented as arrays of - * nine 30-bit words, for values up to 2^270-1. Result is encoded over - * 18 words of 30 bits each. - */ -static void -mul9(uint32_t *d, const uint32_t *a, const uint32_t *b) -{ - /* - * Maximum intermediate result is no more than - * 10376293531797946367, which fits in 64 bits. Reason: - * - * 10376293531797946367 = 9 * (2^30-1)^2 + 9663676406 - * 10376293531797946367 < 9663676407 * 2^30 - * - * Thus, adding together 9 products of 30-bit integers, with - * a carry of at most 9663676406, yields an integer that fits - * on 64 bits and generates a carry of at most 9663676406. - */ - uint64_t t[17]; - uint64_t cc; - int i; - - t[ 0] = MUL31(a[0], b[0]); - t[ 1] = MUL31(a[0], b[1]) - + MUL31(a[1], b[0]); - t[ 2] = MUL31(a[0], b[2]) - + MUL31(a[1], b[1]) - + MUL31(a[2], b[0]); - t[ 3] = MUL31(a[0], b[3]) - + MUL31(a[1], b[2]) - + MUL31(a[2], b[1]) - + MUL31(a[3], b[0]); - t[ 4] = MUL31(a[0], b[4]) - + MUL31(a[1], b[3]) - + MUL31(a[2], b[2]) - + MUL31(a[3], b[1]) - + MUL31(a[4], b[0]); - t[ 5] = MUL31(a[0], b[5]) - + MUL31(a[1], b[4]) - + MUL31(a[2], b[3]) - + MUL31(a[3], b[2]) - + MUL31(a[4], b[1]) - + MUL31(a[5], b[0]); - t[ 6] = MUL31(a[0], b[6]) - + MUL31(a[1], b[5]) - + MUL31(a[2], b[4]) - + MUL31(a[3], b[3]) - + MUL31(a[4], b[2]) - + MUL31(a[5], b[1]) - + MUL31(a[6], b[0]); - t[ 7] = MUL31(a[0], b[7]) - + MUL31(a[1], b[6]) - + MUL31(a[2], b[5]) - + MUL31(a[3], b[4]) - + MUL31(a[4], b[3]) - + MUL31(a[5], b[2]) - + MUL31(a[6], b[1]) - + MUL31(a[7], b[0]); - t[ 8] = MUL31(a[0], b[8]) - + MUL31(a[1], b[7]) - + MUL31(a[2], b[6]) - + MUL31(a[3], b[5]) - + MUL31(a[4], b[4]) - + MUL31(a[5], b[3]) - + MUL31(a[6], b[2]) - + MUL31(a[7], b[1]) - + MUL31(a[8], b[0]); - t[ 9] = MUL31(a[1], b[8]) - + MUL31(a[2], b[7]) - + MUL31(a[3], b[6]) - + MUL31(a[4], b[5]) - + MUL31(a[5], b[4]) - + MUL31(a[6], b[3]) - + MUL31(a[7], b[2]) - + MUL31(a[8], b[1]); - t[10] = MUL31(a[2], b[8]) - + MUL31(a[3], b[7]) - + MUL31(a[4], b[6]) - + MUL31(a[5], b[5]) - + MUL31(a[6], b[4]) - + MUL31(a[7], b[3]) - + MUL31(a[8], b[2]); - t[11] = MUL31(a[3], b[8]) - + MUL31(a[4], b[7]) - + MUL31(a[5], b[6]) - + MUL31(a[6], b[5]) - + MUL31(a[7], b[4]) - + MUL31(a[8], b[3]); - t[12] = MUL31(a[4], b[8]) - + MUL31(a[5], b[7]) - + MUL31(a[6], b[6]) - + MUL31(a[7], b[5]) - + MUL31(a[8], b[4]); - t[13] = MUL31(a[5], b[8]) - + MUL31(a[6], b[7]) - + MUL31(a[7], b[6]) - + MUL31(a[8], b[5]); - t[14] = MUL31(a[6], b[8]) - + MUL31(a[7], b[7]) - + MUL31(a[8], b[6]); - t[15] = MUL31(a[7], b[8]) - + MUL31(a[8], b[7]); - t[16] = MUL31(a[8], b[8]); - - /* - * Propagate carries. - */ - cc = 0; - for (i = 0; i < 17; i ++) { - uint64_t w; - - w = t[i] + cc; - d[i] = (uint32_t)w & 0x3FFFFFFF; - cc = w >> 30; - } - d[17] = (uint32_t)cc; -} - -/* - * Square a 270-bit integer, represented as an array of nine 30-bit words. - * Result uses 18 words of 30 bits each. - */ -static void -square9(uint32_t *d, const uint32_t *a) -{ - uint64_t t[17]; - uint64_t cc; - int i; - - t[ 0] = MUL31(a[0], a[0]); - t[ 1] = ((MUL31(a[0], a[1])) << 1); - t[ 2] = MUL31(a[1], a[1]) - + ((MUL31(a[0], a[2])) << 1); - t[ 3] = ((MUL31(a[0], a[3]) - + MUL31(a[1], a[2])) << 1); - t[ 4] = MUL31(a[2], a[2]) - + ((MUL31(a[0], a[4]) - + MUL31(a[1], a[3])) << 1); - t[ 5] = ((MUL31(a[0], a[5]) - + MUL31(a[1], a[4]) - + MUL31(a[2], a[3])) << 1); - t[ 6] = MUL31(a[3], a[3]) - + ((MUL31(a[0], a[6]) - + MUL31(a[1], a[5]) - + MUL31(a[2], a[4])) << 1); - t[ 7] = ((MUL31(a[0], a[7]) - + MUL31(a[1], a[6]) - + MUL31(a[2], a[5]) - + MUL31(a[3], a[4])) << 1); - t[ 8] = MUL31(a[4], a[4]) - + ((MUL31(a[0], a[8]) - + MUL31(a[1], a[7]) - + MUL31(a[2], a[6]) - + MUL31(a[3], a[5])) << 1); - t[ 9] = ((MUL31(a[1], a[8]) - + MUL31(a[2], a[7]) - + MUL31(a[3], a[6]) - + MUL31(a[4], a[5])) << 1); - t[10] = MUL31(a[5], a[5]) - + ((MUL31(a[2], a[8]) - + MUL31(a[3], a[7]) - + MUL31(a[4], a[6])) << 1); - t[11] = ((MUL31(a[3], a[8]) - + MUL31(a[4], a[7]) - + MUL31(a[5], a[6])) << 1); - t[12] = MUL31(a[6], a[6]) - + ((MUL31(a[4], a[8]) - + MUL31(a[5], a[7])) << 1); - t[13] = ((MUL31(a[5], a[8]) - + MUL31(a[6], a[7])) << 1); - t[14] = MUL31(a[7], a[7]) - + ((MUL31(a[6], a[8])) << 1); - t[15] = ((MUL31(a[7], a[8])) << 1); - t[16] = MUL31(a[8], a[8]); - - /* - * Propagate carries. - */ - cc = 0; - for (i = 0; i < 17; i ++) { - uint64_t w; - - w = t[i] + cc; - d[i] = (uint32_t)w & 0x3FFFFFFF; - cc = w >> 30; - } - d[17] = (uint32_t)cc; -} - -/* - * Base field modulus for P-256. - */ -static const uint32_t F256[] = { - - 0x3FFFFFFF, 0x3FFFFFFF, 0x3FFFFFFF, 0x0000003F, 0x00000000, - 0x00000000, 0x00001000, 0x3FFFC000, 0x0000FFFF -}; - -/* - * The 'b' curve equation coefficient for P-256. - */ -static const uint32_t P256_B[] = { - - 0x27D2604B, 0x2F38F0F8, 0x053B0F63, 0x0741AC33, 0x1886BC65, - 0x2EF555DA, 0x293E7B3E, 0x0D762A8E, 0x00005AC6 -}; - -/* - * Addition in the field. Source operands shall fit on 257 bits; output - * will be lower than twice the modulus. - */ -static void -add_f256(uint32_t *d, const uint32_t *a, const uint32_t *b) -{ - uint32_t w, cc; - int i; - - cc = 0; - for (i = 0; i < 9; i ++) { - w = a[i] + b[i] + cc; - d[i] = w & 0x3FFFFFFF; - cc = w >> 30; - } - w >>= 16; - d[8] &= 0xFFFF; - d[3] -= w << 6; - d[6] -= w << 12; - d[7] += w << 14; - cc = w; - for (i = 0; i < 9; i ++) { - w = d[i] + cc; - d[i] = w & 0x3FFFFFFF; - cc = ARSH(w, 30); - } -} - -/* - * Subtraction in the field. Source operands shall be smaller than twice - * the modulus; the result will fulfill the same property. - */ -static void -sub_f256(uint32_t *d, const uint32_t *a, const uint32_t *b) -{ - uint32_t w, cc; - int i; - - /* - * We really compute a - b + 2*p to make sure that the result is - * positive. - */ - w = a[0] - b[0] - 0x00002; - d[0] = w & 0x3FFFFFFF; - w = a[1] - b[1] + ARSH(w, 30); - d[1] = w & 0x3FFFFFFF; - w = a[2] - b[2] + ARSH(w, 30); - d[2] = w & 0x3FFFFFFF; - w = a[3] - b[3] + ARSH(w, 30) + 0x00080; - d[3] = w & 0x3FFFFFFF; - w = a[4] - b[4] + ARSH(w, 30); - d[4] = w & 0x3FFFFFFF; - w = a[5] - b[5] + ARSH(w, 30); - d[5] = w & 0x3FFFFFFF; - w = a[6] - b[6] + ARSH(w, 30) + 0x02000; - d[6] = w & 0x3FFFFFFF; - w = a[7] - b[7] + ARSH(w, 30) - 0x08000; - d[7] = w & 0x3FFFFFFF; - w = a[8] - b[8] + ARSH(w, 30) + 0x20000; - d[8] = w & 0xFFFF; - w >>= 16; - d[8] &= 0xFFFF; - d[3] -= w << 6; - d[6] -= w << 12; - d[7] += w << 14; - cc = w; - for (i = 0; i < 9; i ++) { - w = d[i] + cc; - d[i] = w & 0x3FFFFFFF; - cc = ARSH(w, 30); - } -} - -/* - * Compute a multiplication in F256. Source operands shall be less than - * twice the modulus. - */ -static void -mul_f256(uint32_t *d, const uint32_t *a, const uint32_t *b) -{ - uint32_t t[18]; - uint64_t s[18]; - uint64_t cc, x; - uint32_t z, c; - int i; - - mul9(t, a, b); - - /* - * Modular reduction: each high word in added/subtracted where - * necessary. - * - * The modulus is: - * p = 2^256 - 2^224 + 2^192 + 2^96 - 1 - * Therefore: - * 2^256 = 2^224 - 2^192 - 2^96 + 1 mod p - * - * For a word x at bit offset n (n >= 256), we have: - * x*2^n = x*2^(n-32) - x*2^(n-64) - * - x*2^(n - 160) + x*2^(n-256) mod p - * - * Thus, we can nullify the high word if we reinject it at some - * proper emplacements. - * - * We use 64-bit intermediate words to allow for carries to - * accumulate easily, before performing the final propagation. - */ - for (i = 0; i < 18; i ++) { - s[i] = t[i]; - } - - for (i = 17; i >= 9; i --) { - uint64_t y; - - y = s[i]; - s[i - 1] += ARSHW(y, 2); - s[i - 2] += (y << 28) & 0x3FFFFFFF; - s[i - 2] -= ARSHW(y, 4); - s[i - 3] -= (y << 26) & 0x3FFFFFFF; - s[i - 5] -= ARSHW(y, 10); - s[i - 6] -= (y << 20) & 0x3FFFFFFF; - s[i - 8] += ARSHW(y, 16); - s[i - 9] += (y << 14) & 0x3FFFFFFF; - } - - /* - * Carry propagation must be signed. Moreover, we may have overdone - * it a bit, and obtain a negative result. - * - * The loop above ran 9 times; each time, each word was augmented - * by at most one extra word (in absolute value). Thus, the top - * word must in fine fit in 39 bits, so the carry below will fit - * on 9 bits. - */ - cc = 0; - for (i = 0; i < 9; i ++) { - x = s[i] + cc; - d[i] = (uint32_t)x & 0x3FFFFFFF; - cc = ARSHW(x, 30); - } - - /* - * All nine words fit on 30 bits, but there may be an extra - * carry for a few bits (at most 9), and that carry may be - * negative. Moreover, we want the result to fit on 257 bits. - * The two lines below ensure that the word in d[] has length - * 256 bits, and the (signed) carry (beyond 2^256) is in cc. The - * significant length of cc is less than 24 bits, so we will be - * able to switch to 32-bit operations. - */ - cc = ARSHW(x, 16); - d[8] &= 0xFFFF; - - /* - * One extra round of reduction, for cc*2^256, which means - * adding cc*(2^224-2^192-2^96+1) to a 256-bit (nonnegative) - * value. If cc is negative, then it may happen (rarely, but - * not neglectibly so) that the result would be negative. In - * order to avoid that, if cc is negative, then we add the - * modulus once. Note that if cc is negative, then propagating - * that carry must yield a value lower than the modulus, so - * adding the modulus once will keep the final result under - * twice the modulus. - */ - z = (uint32_t)cc; - d[3] -= z << 6; - d[6] -= (z << 12) & 0x3FFFFFFF; - d[7] -= ARSH(z, 18); - d[7] += (z << 14) & 0x3FFFFFFF; - d[8] += ARSH(z, 16); - c = z >> 31; - d[0] -= c; - d[3] += c << 6; - d[6] += c << 12; - d[7] -= c << 14; - d[8] += c << 16; - for (i = 0; i < 9; i ++) { - uint32_t w; - - w = d[i] + z; - d[i] = w & 0x3FFFFFFF; - z = ARSH(w, 30); - } -} - -/* - * Compute a square in F256. Source operand shall be less than - * twice the modulus. - */ -static void -square_f256(uint32_t *d, const uint32_t *a) -{ - uint32_t t[18]; - uint64_t s[18]; - uint64_t cc, x; - uint32_t z, c; - int i; - - square9(t, a); - - /* - * Modular reduction: each high word in added/subtracted where - * necessary. - * - * The modulus is: - * p = 2^256 - 2^224 + 2^192 + 2^96 - 1 - * Therefore: - * 2^256 = 2^224 - 2^192 - 2^96 + 1 mod p - * - * For a word x at bit offset n (n >= 256), we have: - * x*2^n = x*2^(n-32) - x*2^(n-64) - * - x*2^(n - 160) + x*2^(n-256) mod p - * - * Thus, we can nullify the high word if we reinject it at some - * proper emplacements. - * - * We use 64-bit intermediate words to allow for carries to - * accumulate easily, before performing the final propagation. - */ - for (i = 0; i < 18; i ++) { - s[i] = t[i]; - } - - for (i = 17; i >= 9; i --) { - uint64_t y; - - y = s[i]; - s[i - 1] += ARSHW(y, 2); - s[i - 2] += (y << 28) & 0x3FFFFFFF; - s[i - 2] -= ARSHW(y, 4); - s[i - 3] -= (y << 26) & 0x3FFFFFFF; - s[i - 5] -= ARSHW(y, 10); - s[i - 6] -= (y << 20) & 0x3FFFFFFF; - s[i - 8] += ARSHW(y, 16); - s[i - 9] += (y << 14) & 0x3FFFFFFF; - } - - /* - * Carry propagation must be signed. Moreover, we may have overdone - * it a bit, and obtain a negative result. - * - * The loop above ran 9 times; each time, each word was augmented - * by at most one extra word (in absolute value). Thus, the top - * word must in fine fit in 39 bits, so the carry below will fit - * on 9 bits. - */ - cc = 0; - for (i = 0; i < 9; i ++) { - x = s[i] + cc; - d[i] = (uint32_t)x & 0x3FFFFFFF; - cc = ARSHW(x, 30); - } - - /* - * All nine words fit on 30 bits, but there may be an extra - * carry for a few bits (at most 9), and that carry may be - * negative. Moreover, we want the result to fit on 257 bits. - * The two lines below ensure that the word in d[] has length - * 256 bits, and the (signed) carry (beyond 2^256) is in cc. The - * significant length of cc is less than 24 bits, so we will be - * able to switch to 32-bit operations. - */ - cc = ARSHW(x, 16); - d[8] &= 0xFFFF; - - /* - * One extra round of reduction, for cc*2^256, which means - * adding cc*(2^224-2^192-2^96+1) to a 256-bit (nonnegative) - * value. If cc is negative, then it may happen (rarely, but - * not neglectibly so) that the result would be negative. In - * order to avoid that, if cc is negative, then we add the - * modulus once. Note that if cc is negative, then propagating - * that carry must yield a value lower than the modulus, so - * adding the modulus once will keep the final result under - * twice the modulus. - */ - z = (uint32_t)cc; - d[3] -= z << 6; - d[6] -= (z << 12) & 0x3FFFFFFF; - d[7] -= ARSH(z, 18); - d[7] += (z << 14) & 0x3FFFFFFF; - d[8] += ARSH(z, 16); - c = z >> 31; - d[0] -= c; - d[3] += c << 6; - d[6] += c << 12; - d[7] -= c << 14; - d[8] += c << 16; - for (i = 0; i < 9; i ++) { - uint32_t w; - - w = d[i] + z; - d[i] = w & 0x3FFFFFFF; - z = ARSH(w, 30); - } -} - -/* - * Perform a "final reduction" in field F256 (field for curve P-256). - * The source value must be less than twice the modulus. If the value - * is not lower than the modulus, then the modulus is subtracted and - * this function returns 1; otherwise, it leaves it untouched and it - * returns 0. - */ -static uint32_t -reduce_final_f256(uint32_t *d) -{ - uint32_t t[9]; - uint32_t cc; - int i; - - cc = 0; - for (i = 0; i < 9; i ++) { - uint32_t w; - - w = d[i] - F256[i] - cc; - cc = w >> 31; - t[i] = w & 0x3FFFFFFF; - } - cc ^= 1; - CCOPY(cc, d, t, sizeof t); - return cc; -} - -/* - * Jacobian coordinates for a point in P-256: affine coordinates (X,Y) - * are such that: - * X = x / z^2 - * Y = y / z^3 - * For the point at infinity, z = 0. - * Each point thus admits many possible representations. - * - * Coordinates are represented in arrays of 32-bit integers, each holding - * 30 bits of data. Values may also be slightly greater than the modulus, - * but they will always be lower than twice the modulus. - */ -typedef struct { - uint32_t x[9]; - uint32_t y[9]; - uint32_t z[9]; -} p256_jacobian; - -/* - * Convert a point to affine coordinates: - * - If the point is the point at infinity, then all three coordinates - * are set to 0. - * - Otherwise, the 'z' coordinate is set to 1, and the 'x' and 'y' - * coordinates are the 'X' and 'Y' affine coordinates. - * The coordinates are guaranteed to be lower than the modulus. - */ -static void -p256_to_affine(p256_jacobian *P) -{ - uint32_t t1[9], t2[9]; - int i; - - /* - * Invert z with a modular exponentiation: the modulus is - * p = 2^256 - 2^224 + 2^192 + 2^96 - 1, and the exponent is - * p-2. Exponent bit pattern (from high to low) is: - * - 32 bits of value 1 - * - 31 bits of value 0 - * - 1 bit of value 1 - * - 96 bits of value 0 - * - 94 bits of value 1 - * - 1 bit of value 0 - * - 1 bit of value 1 - * Thus, we precompute z^(2^31-1) to speed things up. - * - * If z = 0 (point at infinity) then the modular exponentiation - * will yield 0, which leads to the expected result (all three - * coordinates set to 0). - */ - - /* - * A simple square-and-multiply for z^(2^31-1). We could save about - * two dozen multiplications here with an addition chain, but - * this would require a bit more code, and extra stack buffers. - */ - memcpy(t1, P->z, sizeof P->z); - for (i = 0; i < 30; i ++) { - square_f256(t1, t1); - mul_f256(t1, t1, P->z); - } - - /* - * Square-and-multiply. Apart from the squarings, we have a few - * multiplications to set bits to 1; we multiply by the original z - * for setting 1 bit, and by t1 for setting 31 bits. - */ - memcpy(t2, P->z, sizeof P->z); - for (i = 1; i < 256; i ++) { - square_f256(t2, t2); - switch (i) { - case 31: - case 190: - case 221: - case 252: - mul_f256(t2, t2, t1); - break; - case 63: - case 253: - case 255: - mul_f256(t2, t2, P->z); - break; - } - } - - /* - * Now that we have 1/z, multiply x by 1/z^2 and y by 1/z^3. - */ - mul_f256(t1, t2, t2); - mul_f256(P->x, t1, P->x); - mul_f256(t1, t1, t2); - mul_f256(P->y, t1, P->y); - reduce_final_f256(P->x); - reduce_final_f256(P->y); - - /* - * Multiply z by 1/z. If z = 0, then this will yield 0, otherwise - * this will set z to 1. - */ - mul_f256(P->z, P->z, t2); - reduce_final_f256(P->z); -} - -/* - * Double a point in P-256. This function works for all valid points, - * including the point at infinity. - */ -static void -p256_double(p256_jacobian *Q) -{ - /* - * Doubling formulas are: - * - * s = 4*x*y^2 - * m = 3*(x + z^2)*(x - z^2) - * x' = m^2 - 2*s - * y' = m*(s - x') - 8*y^4 - * z' = 2*y*z - * - * These formulas work for all points, including points of order 2 - * and points at infinity: - * - If y = 0 then z' = 0. But there is no such point in P-256 - * anyway. - * - If z = 0 then z' = 0. - */ - uint32_t t1[9], t2[9], t3[9], t4[9]; - - /* - * Compute z^2 in t1. - */ - square_f256(t1, Q->z); - - /* - * Compute x-z^2 in t2 and x+z^2 in t1. - */ - add_f256(t2, Q->x, t1); - sub_f256(t1, Q->x, t1); - - /* - * Compute 3*(x+z^2)*(x-z^2) in t1. - */ - mul_f256(t3, t1, t2); - add_f256(t1, t3, t3); - add_f256(t1, t3, t1); - - /* - * Compute 4*x*y^2 (in t2) and 2*y^2 (in t3). - */ - square_f256(t3, Q->y); - add_f256(t3, t3, t3); - mul_f256(t2, Q->x, t3); - add_f256(t2, t2, t2); - - /* - * Compute x' = m^2 - 2*s. - */ - square_f256(Q->x, t1); - sub_f256(Q->x, Q->x, t2); - sub_f256(Q->x, Q->x, t2); - - /* - * Compute z' = 2*y*z. - */ - mul_f256(t4, Q->y, Q->z); - add_f256(Q->z, t4, t4); - - /* - * Compute y' = m*(s - x') - 8*y^4. Note that we already have - * 2*y^2 in t3. - */ - sub_f256(t2, t2, Q->x); - mul_f256(Q->y, t1, t2); - square_f256(t4, t3); - add_f256(t4, t4, t4); - sub_f256(Q->y, Q->y, t4); -} - -/* - * Add point P2 to point P1. - * - * This function computes the wrong result in the following cases: - * - * - If P1 == 0 but P2 != 0 - * - If P1 != 0 but P2 == 0 - * - If P1 == P2 - * - * In all three cases, P1 is set to the point at infinity. - * - * Returned value is 0 if one of the following occurs: - * - * - P1 and P2 have the same Y coordinate - * - P1 == 0 and P2 == 0 - * - The Y coordinate of one of the points is 0 and the other point is - * the point at infinity. - * - * The third case cannot actually happen with valid points, since a point - * with Y == 0 is a point of order 2, and there is no point of order 2 on - * curve P-256. - * - * Therefore, assuming that P1 != 0 and P2 != 0 on input, then the caller - * can apply the following: - * - * - If the result is not the point at infinity, then it is correct. - * - Otherwise, if the returned value is 1, then this is a case of - * P1+P2 == 0, so the result is indeed the point at infinity. - * - Otherwise, P1 == P2, so a "double" operation should have been - * performed. - */ -static uint32_t -p256_add(p256_jacobian *P1, const p256_jacobian *P2) -{ - /* - * Addtions formulas are: - * - * u1 = x1 * z2^2 - * u2 = x2 * z1^2 - * s1 = y1 * z2^3 - * s2 = y2 * z1^3 - * h = u2 - u1 - * r = s2 - s1 - * x3 = r^2 - h^3 - 2 * u1 * h^2 - * y3 = r * (u1 * h^2 - x3) - s1 * h^3 - * z3 = h * z1 * z2 - */ - uint32_t t1[9], t2[9], t3[9], t4[9], t5[9], t6[9], t7[9]; - uint32_t ret; - int i; - - /* - * Compute u1 = x1*z2^2 (in t1) and s1 = y1*z2^3 (in t3). - */ - square_f256(t3, P2->z); - mul_f256(t1, P1->x, t3); - mul_f256(t4, P2->z, t3); - mul_f256(t3, P1->y, t4); - - /* - * Compute u2 = x2*z1^2 (in t2) and s2 = y2*z1^3 (in t4). - */ - square_f256(t4, P1->z); - mul_f256(t2, P2->x, t4); - mul_f256(t5, P1->z, t4); - mul_f256(t4, P2->y, t5); - - /* - * Compute h = h2 - u1 (in t2) and r = s2 - s1 (in t4). - * We need to test whether r is zero, so we will do some extra - * reduce. - */ - sub_f256(t2, t2, t1); - sub_f256(t4, t4, t3); - reduce_final_f256(t4); - ret = 0; - for (i = 0; i < 9; i ++) { - ret |= t4[i]; - } - ret = (ret | -ret) >> 31; - - /* - * Compute u1*h^2 (in t6) and h^3 (in t5); - */ - square_f256(t7, t2); - mul_f256(t6, t1, t7); - mul_f256(t5, t7, t2); - - /* - * Compute x3 = r^2 - h^3 - 2*u1*h^2. - */ - square_f256(P1->x, t4); - sub_f256(P1->x, P1->x, t5); - sub_f256(P1->x, P1->x, t6); - sub_f256(P1->x, P1->x, t6); - - /* - * Compute y3 = r*(u1*h^2 - x3) - s1*h^3. - */ - sub_f256(t6, t6, P1->x); - mul_f256(P1->y, t4, t6); - mul_f256(t1, t5, t3); - sub_f256(P1->y, P1->y, t1); - - /* - * Compute z3 = h*z1*z2. - */ - mul_f256(t1, P1->z, P2->z); - mul_f256(P1->z, t1, t2); - - return ret; -} - -/* - * Add point P2 to point P1. This is a specialised function for the - * case when P2 is a non-zero point in affine coordinate. - * - * This function computes the wrong result in the following cases: - * - * - If P1 == 0 - * - If P1 == P2 - * - * In both cases, P1 is set to the point at infinity. - * - * Returned value is 0 if one of the following occurs: - * - * - P1 and P2 have the same Y coordinate - * - The Y coordinate of P2 is 0 and P1 is the point at infinity. - * - * The second case cannot actually happen with valid points, since a point - * with Y == 0 is a point of order 2, and there is no point of order 2 on - * curve P-256. - * - * Therefore, assuming that P1 != 0 on input, then the caller - * can apply the following: - * - * - If the result is not the point at infinity, then it is correct. - * - Otherwise, if the returned value is 1, then this is a case of - * P1+P2 == 0, so the result is indeed the point at infinity. - * - Otherwise, P1 == P2, so a "double" operation should have been - * performed. - */ -static uint32_t -p256_add_mixed(p256_jacobian *P1, const p256_jacobian *P2) -{ - /* - * Addtions formulas are: - * - * u1 = x1 - * u2 = x2 * z1^2 - * s1 = y1 - * s2 = y2 * z1^3 - * h = u2 - u1 - * r = s2 - s1 - * x3 = r^2 - h^3 - 2 * u1 * h^2 - * y3 = r * (u1 * h^2 - x3) - s1 * h^3 - * z3 = h * z1 - */ - uint32_t t1[9], t2[9], t3[9], t4[9], t5[9], t6[9], t7[9]; - uint32_t ret; - int i; - - /* - * Compute u1 = x1 (in t1) and s1 = y1 (in t3). - */ - memcpy(t1, P1->x, sizeof t1); - memcpy(t3, P1->y, sizeof t3); - - /* - * Compute u2 = x2*z1^2 (in t2) and s2 = y2*z1^3 (in t4). - */ - square_f256(t4, P1->z); - mul_f256(t2, P2->x, t4); - mul_f256(t5, P1->z, t4); - mul_f256(t4, P2->y, t5); - - /* - * Compute h = h2 - u1 (in t2) and r = s2 - s1 (in t4). - * We need to test whether r is zero, so we will do some extra - * reduce. - */ - sub_f256(t2, t2, t1); - sub_f256(t4, t4, t3); - reduce_final_f256(t4); - ret = 0; - for (i = 0; i < 9; i ++) { - ret |= t4[i]; - } - ret = (ret | -ret) >> 31; - - /* - * Compute u1*h^2 (in t6) and h^3 (in t5); - */ - square_f256(t7, t2); - mul_f256(t6, t1, t7); - mul_f256(t5, t7, t2); - - /* - * Compute x3 = r^2 - h^3 - 2*u1*h^2. - */ - square_f256(P1->x, t4); - sub_f256(P1->x, P1->x, t5); - sub_f256(P1->x, P1->x, t6); - sub_f256(P1->x, P1->x, t6); - - /* - * Compute y3 = r*(u1*h^2 - x3) - s1*h^3. - */ - sub_f256(t6, t6, P1->x); - mul_f256(P1->y, t4, t6); - mul_f256(t1, t5, t3); - sub_f256(P1->y, P1->y, t1); - - /* - * Compute z3 = h*z1*z2. - */ - mul_f256(P1->z, P1->z, t2); - - return ret; -} - -/* - * Decode a P-256 point. This function does not support the point at - * infinity. Returned value is 0 if the point is invalid, 1 otherwise. - */ -static uint32_t -p256_decode(p256_jacobian *P, const void *src, size_t len) -{ - const unsigned char *buf; - uint32_t tx[9], ty[9], t1[9], t2[9]; - uint32_t bad; - int i; - - if (len != 65) { - return 0; - } - buf = src; - - /* - * First byte must be 0x04 (uncompressed format). We could support - * "hybrid format" (first byte is 0x06 or 0x07, and encodes the - * least significant bit of the Y coordinate), but it is explicitly - * forbidden by RFC 5480 (section 2.2). - */ - bad = NEQ(buf[0], 0x04); - - /* - * Decode the coordinates, and check that they are both lower - * than the modulus. - */ - tx[8] = be8_to_le30(tx, buf + 1, 32); - ty[8] = be8_to_le30(ty, buf + 33, 32); - bad |= reduce_final_f256(tx); - bad |= reduce_final_f256(ty); - - /* - * Check curve equation. - */ - square_f256(t1, tx); - mul_f256(t1, tx, t1); - square_f256(t2, ty); - sub_f256(t1, t1, tx); - sub_f256(t1, t1, tx); - sub_f256(t1, t1, tx); - add_f256(t1, t1, P256_B); - sub_f256(t1, t1, t2); - reduce_final_f256(t1); - for (i = 0; i < 9; i ++) { - bad |= t1[i]; - } - - /* - * Copy coordinates to the point structure. - */ - memcpy(P->x, tx, sizeof tx); - memcpy(P->y, ty, sizeof ty); - memset(P->z, 0, sizeof P->z); - P->z[0] = 1; - return NEQ(bad, 0) ^ 1; -} - -/* - * Encode a point into a buffer. This function assumes that the point is - * valid, in affine coordinates, and not the point at infinity. - */ -static void -p256_encode(void *dst, const p256_jacobian *P) -{ - unsigned char *buf; - - buf = dst; - buf[0] = 0x04; - le30_to_be8(buf + 1, 32, P->x); - le30_to_be8(buf + 33, 32, P->y); -} - -/* - * Multiply a curve point by an integer. The integer is assumed to be - * lower than the curve order, and the base point must not be the point - * at infinity. - */ -static void -p256_mul(p256_jacobian *P, const unsigned char *x, size_t xlen) -{ - /* - * qz is a flag that is initially 1, and remains equal to 1 - * as long as the point is the point at infinity. - * - * We use a 2-bit window to handle multiplier bits by pairs. - * The precomputed window really is the points P2 and P3. - */ - uint32_t qz; - p256_jacobian P2, P3, Q, T, U; - - /* - * Compute window values. - */ - P2 = *P; - p256_double(&P2); - P3 = *P; - p256_add(&P3, &P2); - - /* - * We start with Q = 0. We process multiplier bits 2 by 2. - */ - memset(&Q, 0, sizeof Q); - qz = 1; - while (xlen -- > 0) { - int k; - - for (k = 6; k >= 0; k -= 2) { - uint32_t bits; - uint32_t bnz; - - p256_double(&Q); - p256_double(&Q); - T = *P; - U = Q; - bits = (*x >> k) & (uint32_t)3; - bnz = NEQ(bits, 0); - CCOPY(EQ(bits, 2), &T, &P2, sizeof T); - CCOPY(EQ(bits, 3), &T, &P3, sizeof T); - p256_add(&U, &T); - CCOPY(bnz & qz, &Q, &T, sizeof Q); - CCOPY(bnz & ~qz, &Q, &U, sizeof Q); - qz &= ~bnz; - } - x ++; - } - *P = Q; -} - -/* - * Precomputed window: k*G points, where G is the curve generator, and k - * is an integer from 1 to 15 (inclusive). The X and Y coordinates of - * the point are encoded as 9 words of 30 bits each (little-endian - * order). - */ -static const uint32_t Gwin[15][18] = { - - { 0x1898C296, 0x1284E517, 0x1EB33A0F, 0x00DF604B, - 0x2440F277, 0x339B958E, 0x04247F8B, 0x347CB84B, - 0x00006B17, 0x37BF51F5, 0x2ED901A0, 0x3315ECEC, - 0x338CD5DA, 0x0F9E162B, 0x1FAD29F0, 0x27F9B8EE, - 0x10B8BF86, 0x00004FE3 }, - - { 0x07669978, 0x182D23F1, 0x3F21B35A, 0x225A789D, - 0x351AC3C0, 0x08E00C12, 0x34F7E8A5, 0x1EC62340, - 0x00007CF2, 0x227873D1, 0x3812DE74, 0x0E982299, - 0x1F6B798F, 0x3430DBBA, 0x366B1A7D, 0x2D040293, - 0x154436E3, 0x00000777 }, - - { 0x06E7FD6C, 0x2D05986F, 0x3ADA985F, 0x31ADC87B, - 0x0BF165E6, 0x1FBE5475, 0x30A44C8F, 0x3934698C, - 0x00005ECB, 0x227D5032, 0x29E6C49E, 0x04FB83D9, - 0x0AAC0D8E, 0x24A2ECD8, 0x2C1B3869, 0x0FF7E374, - 0x19031266, 0x00008734 }, - - { 0x2B030852, 0x024C0911, 0x05596EF5, 0x07F8B6DE, - 0x262BD003, 0x3779967B, 0x08FBBA02, 0x128D4CB4, - 0x0000E253, 0x184ED8C6, 0x310B08FC, 0x30EE0055, - 0x3F25B0FC, 0x062D764E, 0x3FB97F6A, 0x33CC719D, - 0x15D69318, 0x0000E0F1 }, - - { 0x03D033ED, 0x05552837, 0x35BE5242, 0x2320BF47, - 0x268FDFEF, 0x13215821, 0x140D2D78, 0x02DE9454, - 0x00005159, 0x3DA16DA4, 0x0742ED13, 0x0D80888D, - 0x004BC035, 0x0A79260D, 0x06FCDAFE, 0x2727D8AE, - 0x1F6A2412, 0x0000E0C1 }, - - { 0x3C2291A9, 0x1AC2ABA4, 0x3B215B4C, 0x131D037A, - 0x17DDE302, 0x0C90B2E2, 0x0602C92D, 0x05CA9DA9, - 0x0000B01A, 0x0FC77FE2, 0x35F1214E, 0x07E16BDF, - 0x003DDC07, 0x2703791C, 0x3038B7EE, 0x3DAD56FE, - 0x041D0C8D, 0x0000E85C }, - - { 0x3187B2A3, 0x0018A1C0, 0x00FEF5B3, 0x3E7E2E2A, - 0x01FB607E, 0x2CC199F0, 0x37B4625B, 0x0EDBE82F, - 0x00008E53, 0x01F400B4, 0x15786A1B, 0x3041B21C, - 0x31CD8CF2, 0x35900053, 0x1A7E0E9B, 0x318366D0, - 0x076F780C, 0x000073EB }, - - { 0x1B6FB393, 0x13767707, 0x3CE97DBB, 0x348E2603, - 0x354CADC1, 0x09D0B4EA, 0x1B053404, 0x1DE76FBA, - 0x000062D9, 0x0F09957E, 0x295029A8, 0x3E76A78D, - 0x3B547DAE, 0x27CEE0A2, 0x0575DC45, 0x1D8244FF, - 0x332F647A, 0x0000AD5A }, - - { 0x10949EE0, 0x1E7A292E, 0x06DF8B3D, 0x02B2E30B, - 0x31F8729E, 0x24E35475, 0x30B71878, 0x35EDBFB7, - 0x0000EA68, 0x0DD048FA, 0x21688929, 0x0DE823FE, - 0x1C53FAA9, 0x0EA0C84D, 0x052A592A, 0x1FCE7870, - 0x11325CB2, 0x00002A27 }, - - { 0x04C5723F, 0x30D81A50, 0x048306E4, 0x329B11C7, - 0x223FB545, 0x085347A8, 0x2993E591, 0x1B5ACA8E, - 0x0000CEF6, 0x04AF0773, 0x28D2EEA9, 0x2751EEEC, - 0x037B4A7F, 0x3B4C1059, 0x08F37674, 0x2AE906E1, - 0x18A88A6A, 0x00008786 }, - - { 0x34BC21D1, 0x0CCE474D, 0x15048BF4, 0x1D0BB409, - 0x021CDA16, 0x20DE76C3, 0x34C59063, 0x04EDE20E, - 0x00003ED1, 0x282A3740, 0x0BE3BBF3, 0x29889DAE, - 0x03413697, 0x34C68A09, 0x210EBE93, 0x0C8A224C, - 0x0826B331, 0x00009099 }, - - { 0x0624E3C4, 0x140317BA, 0x2F82C99D, 0x260C0A2C, - 0x25D55179, 0x194DCC83, 0x3D95E462, 0x356F6A05, - 0x0000741D, 0x0D4481D3, 0x2657FC8B, 0x1BA5CA71, - 0x3AE44B0D, 0x07B1548E, 0x0E0D5522, 0x05FDC567, - 0x2D1AA70E, 0x00000770 }, - - { 0x06072C01, 0x23857675, 0x1EAD58A9, 0x0B8A12D9, - 0x1EE2FC79, 0x0177CB61, 0x0495A618, 0x20DEB82B, - 0x0000177C, 0x2FC7BFD8, 0x310EEF8B, 0x1FB4DF39, - 0x3B8530E8, 0x0F4E7226, 0x0246B6D0, 0x2A558A24, - 0x163353AF, 0x000063BB }, - - { 0x24D2920B, 0x1C249DCC, 0x2069C5E5, 0x09AB2F9E, - 0x36DF3CF1, 0x1991FD0C, 0x062B97A7, 0x1E80070E, - 0x000054E7, 0x20D0B375, 0x2E9F20BD, 0x35090081, - 0x1C7A9DDC, 0x22E7C371, 0x087E3016, 0x03175421, - 0x3C6ECA7D, 0x0000F599 }, - - { 0x259B9D5F, 0x0D9A318F, 0x23A0EF16, 0x00EBE4B7, - 0x088265AE, 0x2CDE2666, 0x2BAE7ADF, 0x1371A5C6, - 0x0000F045, 0x0D034F36, 0x1F967378, 0x1B5FA3F4, - 0x0EC8739D, 0x1643E62A, 0x1653947E, 0x22D1F4E6, - 0x0FB8D64B, 0x0000B5B9 } -}; - -/* - * Lookup one of the Gwin[] values, by index. This is constant-time. - */ -static void -lookup_Gwin(p256_jacobian *T, uint32_t idx) -{ - uint32_t xy[18]; - uint32_t k; - size_t u; - - memset(xy, 0, sizeof xy); - for (k = 0; k < 15; k ++) { - uint32_t m; - - m = -EQ(idx, k + 1); - for (u = 0; u < 18; u ++) { - xy[u] |= m & Gwin[k][u]; - } - } - memcpy(T->x, &xy[0], sizeof T->x); - memcpy(T->y, &xy[9], sizeof T->y); - memset(T->z, 0, sizeof T->z); - T->z[0] = 1; -} - -/* - * Multiply the generator by an integer. The integer is assumed non-zero - * and lower than the curve order. - */ -static void -p256_mulgen(p256_jacobian *P, const unsigned char *x, size_t xlen) -{ - /* - * qz is a flag that is initially 1, and remains equal to 1 - * as long as the point is the point at infinity. - * - * We use a 4-bit window to handle multiplier bits by groups - * of 4. The precomputed window is constant static data, with - * points in affine coordinates; we use a constant-time lookup. - */ - p256_jacobian Q; - uint32_t qz; - - memset(&Q, 0, sizeof Q); - qz = 1; - while (xlen -- > 0) { - int k; - unsigned bx; - - bx = *x ++; - for (k = 0; k < 2; k ++) { - uint32_t bits; - uint32_t bnz; - p256_jacobian T, U; - - p256_double(&Q); - p256_double(&Q); - p256_double(&Q); - p256_double(&Q); - bits = (bx >> 4) & 0x0F; - bnz = NEQ(bits, 0); - lookup_Gwin(&T, bits); - U = Q; - p256_add_mixed(&U, &T); - CCOPY(bnz & qz, &Q, &T, sizeof Q); - CCOPY(bnz & ~qz, &Q, &U, sizeof Q); - qz &= ~bnz; - bx <<= 4; - } - } - *P = Q; -} - -static const unsigned char P256_G[] = { - 0x04, 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, - 0xBC, 0xE6, 0xE5, 0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, - 0x81, 0x2D, 0xEB, 0x33, 0xA0, 0xF4, 0xA1, 0x39, 0x45, 0xD8, - 0x98, 0xC2, 0x96, 0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, - 0x9B, 0x8E, 0xE7, 0xEB, 0x4A, 0x7C, 0x0F, 0x9E, 0x16, 0x2B, - 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE, 0xCB, 0xB6, 0x40, - 0x68, 0x37, 0xBF, 0x51, 0xF5 -}; - -static const unsigned char P256_N[] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, - 0xA7, 0x17, 0x9E, 0x84, 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, - 0x25, 0x51 -}; - -static const unsigned char * -api_generator(int curve, size_t *len) -{ - (void)curve; - *len = sizeof P256_G; - return P256_G; -} - -static const unsigned char * -api_order(int curve, size_t *len) -{ - (void)curve; - *len = sizeof P256_N; - return P256_N; -} - -static size_t -api_xoff(int curve, size_t *len) -{ - (void)curve; - *len = 32; - return 1; -} - -static uint32_t -api_mul(unsigned char *G, size_t Glen, - const unsigned char *x, size_t xlen, int curve) -{ - uint32_t r; - p256_jacobian P; - - (void)curve; - r = p256_decode(&P, G, Glen); - p256_mul(&P, x, xlen); - if (Glen >= 65) { - p256_to_affine(&P); - p256_encode(G, &P); - } - return r; -} - -static size_t -api_mulgen(unsigned char *R, - const unsigned char *x, size_t xlen, int curve) -{ - p256_jacobian P; - - (void)curve; - p256_mulgen(&P, x, xlen); - p256_to_affine(&P); - p256_encode(R, &P); - return 65; - - /* - const unsigned char *G; - size_t Glen; - - G = api_generator(curve, &Glen); - memcpy(R, G, Glen); - api_mul(R, Glen, x, xlen, curve); - return Glen; - */ -} - -static uint32_t -api_muladd(unsigned char *A, const unsigned char *B, size_t len, - const unsigned char *x, size_t xlen, - const unsigned char *y, size_t ylen, int curve) -{ - p256_jacobian P, Q; - uint32_t r, t, z; - int i; - - (void)curve; - r = p256_decode(&P, A, len); - p256_mul(&P, x, xlen); - if (B == NULL) { - p256_mulgen(&Q, y, ylen); - } else { - r &= p256_decode(&Q, B, len); - p256_mul(&Q, y, ylen); - } - - /* - * The final addition may fail in case both points are equal. - */ - t = p256_add(&P, &Q); - reduce_final_f256(P.z); - z = 0; - for (i = 0; i < 9; i ++) { - z |= P.z[i]; - } - z = EQ(z, 0); - p256_double(&Q); - - /* - * If z is 1 then either P+Q = 0 (t = 1) or P = Q (t = 0). So we - * have the following: - * - * z = 0, t = 0 return P (normal addition) - * z = 0, t = 1 return P (normal addition) - * z = 1, t = 0 return Q (a 'double' case) - * z = 1, t = 1 report an error (P+Q = 0) - */ - CCOPY(z & ~t, &P, &Q, sizeof Q); - p256_to_affine(&P); - p256_encode(A, &P); - r &= ~(z & t); - return r; -} - -/* see bearssl_ec.h */ -const br_ec_impl br_ec_p256_m31 = { - (uint32_t)0x00800000, - &api_generator, - &api_order, - &api_xoff, - &api_mul, - &api_mulgen, - &api_muladd -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ec_prime_i15.c b/src/tls/bearssl/ec_prime_i15.c deleted file mode 100644 index bfb5e6b55..000000000 --- a/src/tls/bearssl/ec_prime_i15.c +++ /dev/null @@ -1,825 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * Parameters for supported curves: - * - field modulus p - * - R^2 mod p (R = 2^(15k) for the smallest k such that R >= p) - * - b*R mod p (b is the second curve equation parameter) - */ - -static const uint16_t P256_P[] = { - 0x0111, - 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x003F, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x4000, 0x7FFF, - 0x7FFF, 0x0001 -}; - -static const uint16_t P256_R2[] = { - 0x0111, - 0x0000, 0x6000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7FFC, 0x7FFF, - 0x7FBF, 0x7FFF, 0x7FBF, 0x7FFF, 0x7FFF, 0x7FFF, 0x77FF, 0x7FFF, - 0x4FFF, 0x0000 -}; - -static const uint16_t P256_B[] = { - 0x0111, - 0x770C, 0x5EEF, 0x29C4, 0x3EC4, 0x6273, 0x0486, 0x4543, 0x3993, - 0x3C01, 0x6B56, 0x212E, 0x57EE, 0x4882, 0x204B, 0x7483, 0x3C16, - 0x0187, 0x0000 -}; - -static const uint16_t P384_P[] = { - 0x0199, - 0x7FFF, 0x7FFF, 0x0003, 0x0000, 0x0000, 0x0000, 0x7FC0, 0x7FFF, - 0x7EFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, - 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, - 0x7FFF, 0x01FF -}; - -static const uint16_t P384_R2[] = { - 0x0199, - 0x1000, 0x0000, 0x0000, 0x7FFF, 0x7FFF, 0x0001, 0x0000, 0x0010, - 0x0000, 0x0000, 0x0000, 0x7F00, 0x7FFF, 0x01FF, 0x0000, 0x1000, - 0x0000, 0x2000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000 -}; - -static const uint16_t P384_B[] = { - 0x0199, - 0x7333, 0x2096, 0x70D1, 0x2310, 0x3020, 0x6197, 0x1464, 0x35BB, - 0x70CA, 0x0117, 0x1920, 0x4136, 0x5FC8, 0x5713, 0x4938, 0x7DD2, - 0x4DD2, 0x4A71, 0x0220, 0x683E, 0x2C87, 0x4DB1, 0x7BFF, 0x6C09, - 0x0452, 0x0084 -}; - -static const uint16_t P521_P[] = { - 0x022B, - 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, - 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, - 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, - 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, - 0x7FFF, 0x7FFF, 0x07FF -}; - -static const uint16_t P521_R2[] = { - 0x022B, - 0x0100, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000 -}; - -static const uint16_t P521_B[] = { - 0x022B, - 0x7002, 0x6A07, 0x751A, 0x228F, 0x71EF, 0x5869, 0x20F4, 0x1EFC, - 0x7357, 0x37E0, 0x4EEC, 0x605E, 0x1652, 0x26F6, 0x31FA, 0x4A8F, - 0x6193, 0x3C2A, 0x3C42, 0x48C7, 0x3489, 0x6771, 0x4C57, 0x5CCD, - 0x2725, 0x545B, 0x503B, 0x5B42, 0x21A0, 0x2534, 0x687E, 0x70E4, - 0x1618, 0x27D7, 0x0465 -}; - -typedef struct { - const uint16_t *p; - const uint16_t *b; - const uint16_t *R2; - uint16_t p0i; - size_t point_len; -} curve_params; - -static inline const curve_params * -id_to_curve(int curve) -{ - static const curve_params pp[] = { - { P256_P, P256_B, P256_R2, 0x0001, 65 }, - { P384_P, P384_B, P384_R2, 0x0001, 97 }, - { P521_P, P521_B, P521_R2, 0x0001, 133 } - }; - - return &pp[curve - BR_EC_secp256r1]; -} - -#define I15_LEN ((BR_MAX_EC_SIZE + 29) / 15) - -/* - * Type for a point in Jacobian coordinates: - * -- three values, x, y and z, in Montgomery representation - * -- affine coordinates are X = x / z^2 and Y = y / z^3 - * -- for the point at infinity, z = 0 - */ -typedef struct { - uint16_t c[3][I15_LEN]; -} jacobian; - -/* - * We use a custom interpreter that uses a dozen registers, and - * only six operations: - * MSET(d, a) copy a into d - * MADD(d, a) d = d+a (modular) - * MSUB(d, a) d = d-a (modular) - * MMUL(d, a, b) d = a*b (Montgomery multiplication) - * MINV(d, a, b) invert d modulo p; a and b are used as scratch registers - * MTZ(d) clear return value if d = 0 - * Destination of MMUL (d) must be distinct from operands (a and b). - * There is no such constraint for MSUB and MADD. - * - * Registers include the operand coordinates, and temporaries. - */ -#define MSET(d, a) (0x0000 + ((d) << 8) + ((a) << 4)) -#define MADD(d, a) (0x1000 + ((d) << 8) + ((a) << 4)) -#define MSUB(d, a) (0x2000 + ((d) << 8) + ((a) << 4)) -#define MMUL(d, a, b) (0x3000 + ((d) << 8) + ((a) << 4) + (b)) -#define MINV(d, a, b) (0x4000 + ((d) << 8) + ((a) << 4) + (b)) -#define MTZ(d) (0x5000 + ((d) << 8)) -#define ENDCODE 0 - -/* - * Registers for the input operands. - */ -#define P1x 0 -#define P1y 1 -#define P1z 2 -#define P2x 3 -#define P2y 4 -#define P2z 5 - -/* - * Alternate names for the first input operand. - */ -#define Px 0 -#define Py 1 -#define Pz 2 - -/* - * Temporaries. - */ -#define t1 6 -#define t2 7 -#define t3 8 -#define t4 9 -#define t5 10 -#define t6 11 -#define t7 12 - -/* - * Extra scratch registers available when there is no second operand (e.g. - * for "double" and "affine"). - */ -#define t8 3 -#define t9 4 -#define t10 5 - -/* - * Doubling formulas are: - * - * s = 4*x*y^2 - * m = 3*(x + z^2)*(x - z^2) - * x' = m^2 - 2*s - * y' = m*(s - x') - 8*y^4 - * z' = 2*y*z - * - * If y = 0 (P has order 2) then this yields infinity (z' = 0), as it - * should. This case should not happen anyway, because our curves have - * prime order, and thus do not contain any point of order 2. - * - * If P is infinity (z = 0), then again the formulas yield infinity, - * which is correct. Thus, this code works for all points. - * - * Cost: 8 multiplications - */ -static const uint16_t code_double[] = { - /* - * Compute z^2 (in t1). - */ - MMUL(t1, Pz, Pz), - - /* - * Compute x-z^2 (in t2) and then x+z^2 (in t1). - */ - MSET(t2, Px), - MSUB(t2, t1), - MADD(t1, Px), - - /* - * Compute m = 3*(x+z^2)*(x-z^2) (in t1). - */ - MMUL(t3, t1, t2), - MSET(t1, t3), - MADD(t1, t3), - MADD(t1, t3), - - /* - * Compute s = 4*x*y^2 (in t2) and 2*y^2 (in t3). - */ - MMUL(t3, Py, Py), - MADD(t3, t3), - MMUL(t2, Px, t3), - MADD(t2, t2), - - /* - * Compute x' = m^2 - 2*s. - */ - MMUL(Px, t1, t1), - MSUB(Px, t2), - MSUB(Px, t2), - - /* - * Compute z' = 2*y*z. - */ - MMUL(t4, Py, Pz), - MSET(Pz, t4), - MADD(Pz, t4), - - /* - * Compute y' = m*(s - x') - 8*y^4. Note that we already have - * 2*y^2 in t3. - */ - MSUB(t2, Px), - MMUL(Py, t1, t2), - MMUL(t4, t3, t3), - MSUB(Py, t4), - MSUB(Py, t4), - - ENDCODE -}; - -/* - * Addtions formulas are: - * - * u1 = x1 * z2^2 - * u2 = x2 * z1^2 - * s1 = y1 * z2^3 - * s2 = y2 * z1^3 - * h = u2 - u1 - * r = s2 - s1 - * x3 = r^2 - h^3 - 2 * u1 * h^2 - * y3 = r * (u1 * h^2 - x3) - s1 * h^3 - * z3 = h * z1 * z2 - * - * If both P1 and P2 are infinity, then z1 == 0 and z2 == 0, implying that - * z3 == 0, so the result is correct. - * If either of P1 or P2 is infinity, but not both, then z3 == 0, which is - * not correct. - * h == 0 only if u1 == u2; this happens in two cases: - * -- if s1 == s2 then P1 and/or P2 is infinity, or P1 == P2 - * -- if s1 != s2 then P1 + P2 == infinity (but neither P1 or P2 is infinity) - * - * Thus, the following situations are not handled correctly: - * -- P1 = 0 and P2 != 0 - * -- P1 != 0 and P2 = 0 - * -- P1 = P2 - * All other cases are properly computed. However, even in "incorrect" - * situations, the three coordinates still are properly formed field - * elements. - * - * The returned flag is cleared if r == 0. This happens in the following - * cases: - * -- Both points are on the same horizontal line (same Y coordinate). - * -- Both points are infinity. - * -- One point is infinity and the other is on line Y = 0. - * The third case cannot happen with our curves (there is no valid point - * on line Y = 0 since that would be a point of order 2). If the two - * source points are non-infinity, then remains only the case where the - * two points are on the same horizontal line. - * - * This allows us to detect the "P1 == P2" case, assuming that P1 != 0 and - * P2 != 0: - * -- If the returned value is not the point at infinity, then it was properly - * computed. - * -- Otherwise, if the returned flag is 1, then P1+P2 = 0, and the result - * is indeed the point at infinity. - * -- Otherwise (result is infinity, flag is 0), then P1 = P2 and we should - * use the 'double' code. - * - * Cost: 16 multiplications - */ -static const uint16_t code_add[] = { - /* - * Compute u1 = x1*z2^2 (in t1) and s1 = y1*z2^3 (in t3). - */ - MMUL(t3, P2z, P2z), - MMUL(t1, P1x, t3), - MMUL(t4, P2z, t3), - MMUL(t3, P1y, t4), - - /* - * Compute u2 = x2*z1^2 (in t2) and s2 = y2*z1^3 (in t4). - */ - MMUL(t4, P1z, P1z), - MMUL(t2, P2x, t4), - MMUL(t5, P1z, t4), - MMUL(t4, P2y, t5), - - /* - * Compute h = u2 - u1 (in t2) and r = s2 - s1 (in t4). - */ - MSUB(t2, t1), - MSUB(t4, t3), - - /* - * Report cases where r = 0 through the returned flag. - */ - MTZ(t4), - - /* - * Compute u1*h^2 (in t6) and h^3 (in t5). - */ - MMUL(t7, t2, t2), - MMUL(t6, t1, t7), - MMUL(t5, t7, t2), - - /* - * Compute x3 = r^2 - h^3 - 2*u1*h^2. - * t1 and t7 can be used as scratch registers. - */ - MMUL(P1x, t4, t4), - MSUB(P1x, t5), - MSUB(P1x, t6), - MSUB(P1x, t6), - - /* - * Compute y3 = r*(u1*h^2 - x3) - s1*h^3. - */ - MSUB(t6, P1x), - MMUL(P1y, t4, t6), - MMUL(t1, t5, t3), - MSUB(P1y, t1), - - /* - * Compute z3 = h*z1*z2. - */ - MMUL(t1, P1z, P2z), - MMUL(P1z, t1, t2), - - ENDCODE -}; - -/* - * Check that the point is on the curve. This code snippet assumes the - * following conventions: - * -- Coordinates x and y have been freshly decoded in P1 (but not - * converted to Montgomery coordinates yet). - * -- P2x, P2y and P2z are set to, respectively, R^2, b*R and 1. - */ -static const uint16_t code_check[] = { - - /* Convert x and y to Montgomery representation. */ - MMUL(t1, P1x, P2x), - MMUL(t2, P1y, P2x), - MSET(P1x, t1), - MSET(P1y, t2), - - /* Compute x^3 in t1. */ - MMUL(t2, P1x, P1x), - MMUL(t1, P1x, t2), - - /* Subtract 3*x from t1. */ - MSUB(t1, P1x), - MSUB(t1, P1x), - MSUB(t1, P1x), - - /* Add b. */ - MADD(t1, P2y), - - /* Compute y^2 in t2. */ - MMUL(t2, P1y, P1y), - - /* Compare y^2 with x^3 - 3*x + b; they must match. */ - MSUB(t1, t2), - MTZ(t1), - - /* Set z to 1 (in Montgomery representation). */ - MMUL(P1z, P2x, P2z), - - ENDCODE -}; - -/* - * Conversion back to affine coordinates. This code snippet assumes that - * the z coordinate of P2 is set to 1 (not in Montgomery representation). - */ -static const uint16_t code_affine[] = { - - /* Save z*R in t1. */ - MSET(t1, P1z), - - /* Compute z^3 in t2. */ - MMUL(t2, P1z, P1z), - MMUL(t3, P1z, t2), - MMUL(t2, t3, P2z), - - /* Invert to (1/z^3) in t2. */ - MINV(t2, t3, t4), - - /* Compute y. */ - MSET(t3, P1y), - MMUL(P1y, t2, t3), - - /* Compute (1/z^2) in t3. */ - MMUL(t3, t2, t1), - - /* Compute x. */ - MSET(t2, P1x), - MMUL(P1x, t2, t3), - - ENDCODE -}; - -static uint32_t -run_code(jacobian *P1, const jacobian *P2, - const curve_params *cc, const uint16_t *code) -{ - uint32_t r; - uint16_t t[13][I15_LEN]; - size_t u; - - r = 1; - - /* - * Copy the two operands in the dedicated registers. - */ - memcpy(t[P1x], P1->c, 3 * I15_LEN * sizeof(uint16_t)); - memcpy(t[P2x], P2->c, 3 * I15_LEN * sizeof(uint16_t)); - - /* - * Run formulas. - */ - for (u = 0;; u ++) { - unsigned op, d, a, b; - - op = code[u]; - if (op == 0) { - break; - } - d = (op >> 8) & 0x0F; - a = (op >> 4) & 0x0F; - b = op & 0x0F; - op >>= 12; - switch (op) { - uint32_t ctl; - size_t plen; - unsigned char tp[(BR_MAX_EC_SIZE + 7) >> 3]; - - case 0: - memcpy(t[d], t[a], I15_LEN * sizeof(uint16_t)); - break; - case 1: - ctl = br_i15_add(t[d], t[a], 1); - ctl |= NOT(br_i15_sub(t[d], cc->p, 0)); - br_i15_sub(t[d], cc->p, ctl); - break; - case 2: - br_i15_add(t[d], cc->p, br_i15_sub(t[d], t[a], 1)); - break; - case 3: - br_i15_montymul(t[d], t[a], t[b], cc->p, cc->p0i); - break; - case 4: - plen = (cc->p[0] - (cc->p[0] >> 4) + 7) >> 3; - br_i15_encode(tp, plen, cc->p); - tp[plen - 1] -= 2; - br_i15_modpow(t[d], tp, plen, - cc->p, cc->p0i, t[a], t[b]); - break; - default: - r &= ~br_i15_iszero(t[d]); - break; - } - } - - /* - * Copy back result. - */ - memcpy(P1->c, t[P1x], 3 * I15_LEN * sizeof(uint16_t)); - return r; -} - -static void -set_one(uint16_t *x, const uint16_t *p) -{ - size_t plen; - - plen = (p[0] + 31) >> 4; - memset(x, 0, plen * sizeof *x); - x[0] = p[0]; - x[1] = 0x0001; -} - -static void -point_zero(jacobian *P, const curve_params *cc) -{ - memset(P, 0, sizeof *P); - P->c[0][0] = P->c[1][0] = P->c[2][0] = cc->p[0]; -} - -static inline void -point_double(jacobian *P, const curve_params *cc) -{ - run_code(P, P, cc, code_double); -} - -static inline uint32_t -point_add(jacobian *P1, const jacobian *P2, const curve_params *cc) -{ - return run_code(P1, P2, cc, code_add); -} - -static void -point_mul(jacobian *P, const unsigned char *x, size_t xlen, - const curve_params *cc) -{ - /* - * We do a simple double-and-add ladder with a 2-bit window - * to make only one add every two doublings. We thus first - * precompute 2P and 3P in some local buffers. - * - * We always perform two doublings and one addition; the - * addition is with P, 2P and 3P and is done in a temporary - * array. - * - * The addition code cannot handle cases where one of the - * operands is infinity, which is the case at the start of the - * ladder. We therefore need to maintain a flag that controls - * this situation. - */ - uint32_t qz; - jacobian P2, P3, Q, T, U; - - memcpy(&P2, P, sizeof P2); - point_double(&P2, cc); - memcpy(&P3, P, sizeof P3); - point_add(&P3, &P2, cc); - - point_zero(&Q, cc); - qz = 1; - while (xlen -- > 0) { - int k; - - for (k = 6; k >= 0; k -= 2) { - uint32_t bits; - uint32_t bnz; - - point_double(&Q, cc); - point_double(&Q, cc); - memcpy(&T, P, sizeof T); - memcpy(&U, &Q, sizeof U); - bits = (*x >> k) & (uint32_t)3; - bnz = NEQ(bits, 0); - CCOPY(EQ(bits, 2), &T, &P2, sizeof T); - CCOPY(EQ(bits, 3), &T, &P3, sizeof T); - point_add(&U, &T, cc); - CCOPY(bnz & qz, &Q, &T, sizeof Q); - CCOPY(bnz & ~qz, &Q, &U, sizeof Q); - qz &= ~bnz; - } - x ++; - } - memcpy(P, &Q, sizeof Q); -} - -/* - * Decode point into Jacobian coordinates. This function does not support - * the point at infinity. If the point is invalid then this returns 0, but - * the coordinates are still set to properly formed field elements. - */ -static uint32_t -point_decode(jacobian *P, const void *src, size_t len, const curve_params *cc) -{ - /* - * Points must use uncompressed format: - * -- first byte is 0x04; - * -- coordinates X and Y use unsigned big-endian, with the same - * length as the field modulus. - * - * We don't support hybrid format (uncompressed, but first byte - * has value 0x06 or 0x07, depending on the least significant bit - * of Y) because it is rather useless, and explicitly forbidden - * by PKIX (RFC 5480, section 2.2). - * - * We don't support compressed format either, because it is not - * much used in practice (there are or were patent-related - * concerns about point compression, which explains the lack of - * generalised support). Also, point compression support would - * need a bit more code. - */ - const unsigned char *buf; - size_t plen, zlen; - uint32_t r; - jacobian Q; - - buf = src; - point_zero(P, cc); - plen = (cc->p[0] - (cc->p[0] >> 4) + 7) >> 3; - if (len != 1 + (plen << 1)) { - return 0; - } - r = br_i15_decode_mod(P->c[0], buf + 1, plen, cc->p); - r &= br_i15_decode_mod(P->c[1], buf + 1 + plen, plen, cc->p); - - /* - * Check first byte. - */ - r &= EQ(buf[0], 0x04); - /* obsolete - r &= EQ(buf[0], 0x04) | (EQ(buf[0] & 0xFE, 0x06) - & ~(uint32_t)(buf[0] ^ buf[plen << 1])); - */ - - /* - * Convert coordinates and check that the point is valid. - */ - zlen = ((cc->p[0] + 31) >> 4) * sizeof(uint16_t); - memcpy(Q.c[0], cc->R2, zlen); - memcpy(Q.c[1], cc->b, zlen); - set_one(Q.c[2], cc->p); - r &= ~run_code(P, &Q, cc, code_check); - return r; -} - -/* - * Encode a point. This method assumes that the point is correct and is - * not the point at infinity. Encoded size is always 1+2*plen, where - * plen is the field modulus length, in bytes. - */ -static void -point_encode(void *dst, const jacobian *P, const curve_params *cc) -{ - unsigned char *buf; - size_t plen; - jacobian Q, T; - - buf = dst; - plen = (cc->p[0] - (cc->p[0] >> 4) + 7) >> 3; - buf[0] = 0x04; - memcpy(&Q, P, sizeof *P); - set_one(T.c[2], cc->p); - run_code(&Q, &T, cc, code_affine); - br_i15_encode(buf + 1, plen, Q.c[0]); - br_i15_encode(buf + 1 + plen, plen, Q.c[1]); -} - -static const br_ec_curve_def * -id_to_curve_def(int curve) -{ - switch (curve) { - case BR_EC_secp256r1: - return &br_secp256r1; - case BR_EC_secp384r1: - return &br_secp384r1; - case BR_EC_secp521r1: - return &br_secp521r1; - } - return NULL; -} - -static const unsigned char * -api_generator(int curve, size_t *len) -{ - const br_ec_curve_def *cd; - - cd = id_to_curve_def(curve); - *len = cd->generator_len; - return cd->generator; -} - -static const unsigned char * -api_order(int curve, size_t *len) -{ - const br_ec_curve_def *cd; - - cd = id_to_curve_def(curve); - *len = cd->order_len; - return cd->order; -} - -static size_t -api_xoff(int curve, size_t *len) -{ - api_generator(curve, len); - *len >>= 1; - return 1; -} - -static uint32_t -api_mul(unsigned char *G, size_t Glen, - const unsigned char *x, size_t xlen, int curve) -{ - uint32_t r; - const curve_params *cc; - jacobian P; - - cc = id_to_curve(curve); - r = point_decode(&P, G, Glen, cc); - point_mul(&P, x, xlen, cc); - if (Glen == cc->point_len) { - point_encode(G, &P, cc); - } - return r; -} - -static size_t -api_mulgen(unsigned char *R, - const unsigned char *x, size_t xlen, int curve) -{ - const unsigned char *G; - size_t Glen; - - G = api_generator(curve, &Glen); - memcpy(R, G, Glen); - api_mul(R, Glen, x, xlen, curve); - return Glen; -} - -static uint32_t -api_muladd(unsigned char *A, const unsigned char *B, size_t len, - const unsigned char *x, size_t xlen, - const unsigned char *y, size_t ylen, int curve) -{ - uint32_t r, t, z; - const curve_params *cc; - jacobian P, Q; - - /* - * TODO: see about merging the two ladders. Right now, we do - * two independent point multiplications, which is a bit - * wasteful of CPU resources (but yields short code). - */ - - cc = id_to_curve(curve); - r = point_decode(&P, A, len, cc); - if (B == NULL) { - size_t Glen; - - B = api_generator(curve, &Glen); - } - r &= point_decode(&Q, B, len, cc); - point_mul(&P, x, xlen, cc); - point_mul(&Q, y, ylen, cc); - - /* - * We want to compute P+Q. Since the base points A and B are distinct - * from infinity, and the multipliers are non-zero and lower than the - * curve order, then we know that P and Q are non-infinity. This - * leaves two special situations to test for: - * -- If P = Q then we must use point_double(). - * -- If P+Q = 0 then we must report an error. - */ - t = point_add(&P, &Q, cc); - point_double(&Q, cc); - z = br_i15_iszero(P.c[2]); - - /* - * If z is 1 then either P+Q = 0 (t = 1) or P = Q (t = 0). So we - * have the following: - * - * z = 0, t = 0 return P (normal addition) - * z = 0, t = 1 return P (normal addition) - * z = 1, t = 0 return Q (a 'double' case) - * z = 1, t = 1 report an error (P+Q = 0) - */ - CCOPY(z & ~t, &P, &Q, sizeof Q); - point_encode(A, &P, cc); - r &= ~(z & t); - - return r; -} - -/* see bearssl_ec.h */ -const br_ec_impl br_ec_prime_i15 = { - (uint32_t)0x03800000, - &api_generator, - &api_order, - &api_xoff, - &api_mul, - &api_mulgen, - &api_muladd -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ec_prime_i31.c b/src/tls/bearssl/ec_prime_i31.c deleted file mode 100644 index 783dbf96e..000000000 --- a/src/tls/bearssl/ec_prime_i31.c +++ /dev/null @@ -1,824 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * Parameters for supported curves (field modulus, and 'b' equation - * parameter; both values use the 'i31' format, and 'b' is in Montgomery - * representation). - */ - -static const uint32_t P256_P[] = { - 0x00000108, - 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x00000007, - 0x00000000, 0x00000000, 0x00000040, 0x7FFFFF80, - 0x000000FF -}; - -static const uint32_t P256_R2[] = { - 0x00000108, - 0x00014000, 0x00018000, 0x00000000, 0x7FF40000, - 0x7FEFFFFF, 0x7FF7FFFF, 0x7FAFFFFF, 0x005FFFFF, - 0x00000000 -}; - -static const uint32_t P256_B[] = { - 0x00000108, - 0x6FEE1803, 0x6229C4BD, 0x21B139BE, 0x327150AA, - 0x3567802E, 0x3F7212ED, 0x012E4355, 0x782DD38D, - 0x0000000E -}; - -static const uint32_t P384_P[] = { - 0x0000018C, - 0x7FFFFFFF, 0x00000001, 0x00000000, 0x7FFFFFF8, - 0x7FFFFFEF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, - 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, - 0x00000FFF -}; - -static const uint32_t P384_R2[] = { - 0x0000018C, - 0x00000000, 0x00000080, 0x7FFFFE00, 0x000001FF, - 0x00000800, 0x00000000, 0x7FFFE000, 0x00001FFF, - 0x00008000, 0x00008000, 0x00000000, 0x00000000, - 0x00000000 -}; - -static const uint32_t P384_B[] = { - 0x0000018C, - 0x6E666840, 0x070D0392, 0x5D810231, 0x7651D50C, - 0x17E218D6, 0x1B192002, 0x44EFE441, 0x3A524E2B, - 0x2719BA5F, 0x41F02209, 0x36C5643E, 0x5813EFFE, - 0x000008A5 -}; - -static const uint32_t P521_P[] = { - 0x00000219, - 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, - 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, - 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, - 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, - 0x01FFFFFF -}; - -static const uint32_t P521_R2[] = { - 0x00000219, - 0x00001000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000 -}; - -static const uint32_t P521_B[] = { - 0x00000219, - 0x540FC00A, 0x228FEA35, 0x2C34F1EF, 0x67BF107A, - 0x46FC1CD5, 0x1605E9DD, 0x6937B165, 0x272A3D8F, - 0x42785586, 0x44C8C778, 0x15F3B8B4, 0x64B73366, - 0x03BA8B69, 0x0D05B42A, 0x21F929A2, 0x2C31C393, - 0x00654FAE -}; - -typedef struct { - const uint32_t *p; - const uint32_t *b; - const uint32_t *R2; - uint32_t p0i; -} curve_params; - -static inline const curve_params * -id_to_curve(int curve) -{ - static const curve_params pp[] = { - { P256_P, P256_B, P256_R2, 0x00000001 }, - { P384_P, P384_B, P384_R2, 0x00000001 }, - { P521_P, P521_B, P521_R2, 0x00000001 } - }; - - return &pp[curve - BR_EC_secp256r1]; -} - -#define I31_LEN ((BR_MAX_EC_SIZE + 61) / 31) - -/* - * Type for a point in Jacobian coordinates: - * -- three values, x, y and z, in Montgomery representation - * -- affine coordinates are X = x / z^2 and Y = y / z^3 - * -- for the point at infinity, z = 0 - */ -typedef struct { - uint32_t c[3][I31_LEN]; -} jacobian; - -/* - * We use a custom interpreter that uses a dozen registers, and - * only six operations: - * MSET(d, a) copy a into d - * MADD(d, a) d = d+a (modular) - * MSUB(d, a) d = d-a (modular) - * MMUL(d, a, b) d = a*b (Montgomery multiplication) - * MINV(d, a, b) invert d modulo p; a and b are used as scratch registers - * MTZ(d) clear return value if d = 0 - * Destination of MMUL (d) must be distinct from operands (a and b). - * There is no such constraint for MSUB and MADD. - * - * Registers include the operand coordinates, and temporaries. - */ -#define MSET(d, a) (0x0000 + ((d) << 8) + ((a) << 4)) -#define MADD(d, a) (0x1000 + ((d) << 8) + ((a) << 4)) -#define MSUB(d, a) (0x2000 + ((d) << 8) + ((a) << 4)) -#define MMUL(d, a, b) (0x3000 + ((d) << 8) + ((a) << 4) + (b)) -#define MINV(d, a, b) (0x4000 + ((d) << 8) + ((a) << 4) + (b)) -#define MTZ(d) (0x5000 + ((d) << 8)) -#define ENDCODE 0 - -/* - * Registers for the input operands. - */ -#define P1x 0 -#define P1y 1 -#define P1z 2 -#define P2x 3 -#define P2y 4 -#define P2z 5 - -/* - * Alternate names for the first input operand. - */ -#define Px 0 -#define Py 1 -#define Pz 2 - -/* - * Temporaries. - */ -#define t1 6 -#define t2 7 -#define t3 8 -#define t4 9 -#define t5 10 -#define t6 11 -#define t7 12 - -/* - * Extra scratch registers available when there is no second operand (e.g. - * for "double" and "affine"). - */ -#define t8 3 -#define t9 4 -#define t10 5 - -/* - * Doubling formulas are: - * - * s = 4*x*y^2 - * m = 3*(x + z^2)*(x - z^2) - * x' = m^2 - 2*s - * y' = m*(s - x') - 8*y^4 - * z' = 2*y*z - * - * If y = 0 (P has order 2) then this yields infinity (z' = 0), as it - * should. This case should not happen anyway, because our curves have - * prime order, and thus do not contain any point of order 2. - * - * If P is infinity (z = 0), then again the formulas yield infinity, - * which is correct. Thus, this code works for all points. - * - * Cost: 8 multiplications - */ -static const uint16_t code_double[] = { - /* - * Compute z^2 (in t1). - */ - MMUL(t1, Pz, Pz), - - /* - * Compute x-z^2 (in t2) and then x+z^2 (in t1). - */ - MSET(t2, Px), - MSUB(t2, t1), - MADD(t1, Px), - - /* - * Compute m = 3*(x+z^2)*(x-z^2) (in t1). - */ - MMUL(t3, t1, t2), - MSET(t1, t3), - MADD(t1, t3), - MADD(t1, t3), - - /* - * Compute s = 4*x*y^2 (in t2) and 2*y^2 (in t3). - */ - MMUL(t3, Py, Py), - MADD(t3, t3), - MMUL(t2, Px, t3), - MADD(t2, t2), - - /* - * Compute x' = m^2 - 2*s. - */ - MMUL(Px, t1, t1), - MSUB(Px, t2), - MSUB(Px, t2), - - /* - * Compute z' = 2*y*z. - */ - MMUL(t4, Py, Pz), - MSET(Pz, t4), - MADD(Pz, t4), - - /* - * Compute y' = m*(s - x') - 8*y^4. Note that we already have - * 2*y^2 in t3. - */ - MSUB(t2, Px), - MMUL(Py, t1, t2), - MMUL(t4, t3, t3), - MSUB(Py, t4), - MSUB(Py, t4), - - ENDCODE -}; - -/* - * Addtions formulas are: - * - * u1 = x1 * z2^2 - * u2 = x2 * z1^2 - * s1 = y1 * z2^3 - * s2 = y2 * z1^3 - * h = u2 - u1 - * r = s2 - s1 - * x3 = r^2 - h^3 - 2 * u1 * h^2 - * y3 = r * (u1 * h^2 - x3) - s1 * h^3 - * z3 = h * z1 * z2 - * - * If both P1 and P2 are infinity, then z1 == 0 and z2 == 0, implying that - * z3 == 0, so the result is correct. - * If either of P1 or P2 is infinity, but not both, then z3 == 0, which is - * not correct. - * h == 0 only if u1 == u2; this happens in two cases: - * -- if s1 == s2 then P1 and/or P2 is infinity, or P1 == P2 - * -- if s1 != s2 then P1 + P2 == infinity (but neither P1 or P2 is infinity) - * - * Thus, the following situations are not handled correctly: - * -- P1 = 0 and P2 != 0 - * -- P1 != 0 and P2 = 0 - * -- P1 = P2 - * All other cases are properly computed. However, even in "incorrect" - * situations, the three coordinates still are properly formed field - * elements. - * - * The returned flag is cleared if r == 0. This happens in the following - * cases: - * -- Both points are on the same horizontal line (same Y coordinate). - * -- Both points are infinity. - * -- One point is infinity and the other is on line Y = 0. - * The third case cannot happen with our curves (there is no valid point - * on line Y = 0 since that would be a point of order 2). If the two - * source points are non-infinity, then remains only the case where the - * two points are on the same horizontal line. - * - * This allows us to detect the "P1 == P2" case, assuming that P1 != 0 and - * P2 != 0: - * -- If the returned value is not the point at infinity, then it was properly - * computed. - * -- Otherwise, if the returned flag is 1, then P1+P2 = 0, and the result - * is indeed the point at infinity. - * -- Otherwise (result is infinity, flag is 0), then P1 = P2 and we should - * use the 'double' code. - * - * Cost: 16 multiplications - */ -static const uint16_t code_add[] = { - /* - * Compute u1 = x1*z2^2 (in t1) and s1 = y1*z2^3 (in t3). - */ - MMUL(t3, P2z, P2z), - MMUL(t1, P1x, t3), - MMUL(t4, P2z, t3), - MMUL(t3, P1y, t4), - - /* - * Compute u2 = x2*z1^2 (in t2) and s2 = y2*z1^3 (in t4). - */ - MMUL(t4, P1z, P1z), - MMUL(t2, P2x, t4), - MMUL(t5, P1z, t4), - MMUL(t4, P2y, t5), - - /* - * Compute h = u2 - u1 (in t2) and r = s2 - s1 (in t4). - */ - MSUB(t2, t1), - MSUB(t4, t3), - - /* - * Report cases where r = 0 through the returned flag. - */ - MTZ(t4), - - /* - * Compute u1*h^2 (in t6) and h^3 (in t5). - */ - MMUL(t7, t2, t2), - MMUL(t6, t1, t7), - MMUL(t5, t7, t2), - - /* - * Compute x3 = r^2 - h^3 - 2*u1*h^2. - * t1 and t7 can be used as scratch registers. - */ - MMUL(P1x, t4, t4), - MSUB(P1x, t5), - MSUB(P1x, t6), - MSUB(P1x, t6), - - /* - * Compute y3 = r*(u1*h^2 - x3) - s1*h^3. - */ - MSUB(t6, P1x), - MMUL(P1y, t4, t6), - MMUL(t1, t5, t3), - MSUB(P1y, t1), - - /* - * Compute z3 = h*z1*z2. - */ - MMUL(t1, P1z, P2z), - MMUL(P1z, t1, t2), - - ENDCODE -}; - -/* - * Check that the point is on the curve. This code snippet assumes the - * following conventions: - * -- Coordinates x and y have been freshly decoded in P1 (but not - * converted to Montgomery coordinates yet). - * -- P2x, P2y and P2z are set to, respectively, R^2, b*R and 1. - */ -static const uint16_t code_check[] = { - - /* Convert x and y to Montgomery representation. */ - MMUL(t1, P1x, P2x), - MMUL(t2, P1y, P2x), - MSET(P1x, t1), - MSET(P1y, t2), - - /* Compute x^3 in t1. */ - MMUL(t2, P1x, P1x), - MMUL(t1, P1x, t2), - - /* Subtract 3*x from t1. */ - MSUB(t1, P1x), - MSUB(t1, P1x), - MSUB(t1, P1x), - - /* Add b. */ - MADD(t1, P2y), - - /* Compute y^2 in t2. */ - MMUL(t2, P1y, P1y), - - /* Compare y^2 with x^3 - 3*x + b; they must match. */ - MSUB(t1, t2), - MTZ(t1), - - /* Set z to 1 (in Montgomery representation). */ - MMUL(P1z, P2x, P2z), - - ENDCODE -}; - -/* - * Conversion back to affine coordinates. This code snippet assumes that - * the z coordinate of P2 is set to 1 (not in Montgomery representation). - */ -static const uint16_t code_affine[] = { - - /* Save z*R in t1. */ - MSET(t1, P1z), - - /* Compute z^3 in t2. */ - MMUL(t2, P1z, P1z), - MMUL(t3, P1z, t2), - MMUL(t2, t3, P2z), - - /* Invert to (1/z^3) in t2. */ - MINV(t2, t3, t4), - - /* Compute y. */ - MSET(t3, P1y), - MMUL(P1y, t2, t3), - - /* Compute (1/z^2) in t3. */ - MMUL(t3, t2, t1), - - /* Compute x. */ - MSET(t2, P1x), - MMUL(P1x, t2, t3), - - ENDCODE -}; - -static uint32_t -run_code(jacobian *P1, const jacobian *P2, - const curve_params *cc, const uint16_t *code) -{ - uint32_t r; - uint32_t t[13][I31_LEN]; - size_t u; - - r = 1; - - /* - * Copy the two operands in the dedicated registers. - */ - memcpy(t[P1x], P1->c, 3 * I31_LEN * sizeof(uint32_t)); - memcpy(t[P2x], P2->c, 3 * I31_LEN * sizeof(uint32_t)); - - /* - * Run formulas. - */ - for (u = 0;; u ++) { - unsigned op, d, a, b; - - op = code[u]; - if (op == 0) { - break; - } - d = (op >> 8) & 0x0F; - a = (op >> 4) & 0x0F; - b = op & 0x0F; - op >>= 12; - switch (op) { - uint32_t ctl; - size_t plen; - unsigned char tp[(BR_MAX_EC_SIZE + 7) >> 3]; - - case 0: - memcpy(t[d], t[a], I31_LEN * sizeof(uint32_t)); - break; - case 1: - ctl = br_i31_add(t[d], t[a], 1); - ctl |= NOT(br_i31_sub(t[d], cc->p, 0)); - br_i31_sub(t[d], cc->p, ctl); - break; - case 2: - br_i31_add(t[d], cc->p, br_i31_sub(t[d], t[a], 1)); - break; - case 3: - br_i31_montymul(t[d], t[a], t[b], cc->p, cc->p0i); - break; - case 4: - plen = (cc->p[0] - (cc->p[0] >> 5) + 7) >> 3; - br_i31_encode(tp, plen, cc->p); - tp[plen - 1] -= 2; - br_i31_modpow(t[d], tp, plen, - cc->p, cc->p0i, t[a], t[b]); - break; - default: - r &= ~br_i31_iszero(t[d]); - break; - } - } - - /* - * Copy back result. - */ - memcpy(P1->c, t[P1x], 3 * I31_LEN * sizeof(uint32_t)); - return r; -} - -static void -set_one(uint32_t *x, const uint32_t *p) -{ - size_t plen; - - plen = (p[0] + 63) >> 5; - memset(x, 0, plen * sizeof *x); - x[0] = p[0]; - x[1] = 0x00000001; -} - -static void -point_zero(jacobian *P, const curve_params *cc) -{ - memset(P, 0, sizeof *P); - P->c[0][0] = P->c[1][0] = P->c[2][0] = cc->p[0]; -} - -static inline void -point_double(jacobian *P, const curve_params *cc) -{ - run_code(P, P, cc, code_double); -} - -static inline uint32_t -point_add(jacobian *P1, const jacobian *P2, const curve_params *cc) -{ - return run_code(P1, P2, cc, code_add); -} - -static void -point_mul(jacobian *P, const unsigned char *x, size_t xlen, - const curve_params *cc) -{ - /* - * We do a simple double-and-add ladder with a 2-bit window - * to make only one add every two doublings. We thus first - * precompute 2P and 3P in some local buffers. - * - * We always perform two doublings and one addition; the - * addition is with P, 2P and 3P and is done in a temporary - * array. - * - * The addition code cannot handle cases where one of the - * operands is infinity, which is the case at the start of the - * ladder. We therefore need to maintain a flag that controls - * this situation. - */ - uint32_t qz; - jacobian P2, P3, Q, T, U; - - memcpy(&P2, P, sizeof P2); - point_double(&P2, cc); - memcpy(&P3, P, sizeof P3); - point_add(&P3, &P2, cc); - - point_zero(&Q, cc); - qz = 1; - while (xlen -- > 0) { - int k; - - for (k = 6; k >= 0; k -= 2) { - uint32_t bits; - uint32_t bnz; - - point_double(&Q, cc); - point_double(&Q, cc); - memcpy(&T, P, sizeof T); - memcpy(&U, &Q, sizeof U); - bits = (*x >> k) & (uint32_t)3; - bnz = NEQ(bits, 0); - CCOPY(EQ(bits, 2), &T, &P2, sizeof T); - CCOPY(EQ(bits, 3), &T, &P3, sizeof T); - point_add(&U, &T, cc); - CCOPY(bnz & qz, &Q, &T, sizeof Q); - CCOPY(bnz & ~qz, &Q, &U, sizeof Q); - qz &= ~bnz; - } - x ++; - } - memcpy(P, &Q, sizeof Q); -} - -/* - * Decode point into Jacobian coordinates. This function does not support - * the point at infinity. If the point is invalid then this returns 0, but - * the coordinates are still set to properly formed field elements. - */ -static uint32_t -point_decode(jacobian *P, const void *src, size_t len, const curve_params *cc) -{ - /* - * Points must use uncompressed format: - * -- first byte is 0x04; - * -- coordinates X and Y use unsigned big-endian, with the same - * length as the field modulus. - * - * We don't support hybrid format (uncompressed, but first byte - * has value 0x06 or 0x07, depending on the least significant bit - * of Y) because it is rather useless, and explicitly forbidden - * by PKIX (RFC 5480, section 2.2). - * - * We don't support compressed format either, because it is not - * much used in practice (there are or were patent-related - * concerns about point compression, which explains the lack of - * generalised support). Also, point compression support would - * need a bit more code. - */ - const unsigned char *buf; - size_t plen, zlen; - uint32_t r; - jacobian Q; - - buf = src; - point_zero(P, cc); - plen = (cc->p[0] - (cc->p[0] >> 5) + 7) >> 3; - if (len != 1 + (plen << 1)) { - return 0; - } - r = br_i31_decode_mod(P->c[0], buf + 1, plen, cc->p); - r &= br_i31_decode_mod(P->c[1], buf + 1 + plen, plen, cc->p); - - /* - * Check first byte. - */ - r &= EQ(buf[0], 0x04); - /* obsolete - r &= EQ(buf[0], 0x04) | (EQ(buf[0] & 0xFE, 0x06) - & ~(uint32_t)(buf[0] ^ buf[plen << 1])); - */ - - /* - * Convert coordinates and check that the point is valid. - */ - zlen = ((cc->p[0] + 63) >> 5) * sizeof(uint32_t); - memcpy(Q.c[0], cc->R2, zlen); - memcpy(Q.c[1], cc->b, zlen); - set_one(Q.c[2], cc->p); - r &= ~run_code(P, &Q, cc, code_check); - return r; -} - -/* - * Encode a point. This method assumes that the point is correct and is - * not the point at infinity. Encoded size is always 1+2*plen, where - * plen is the field modulus length, in bytes. - */ -static void -point_encode(void *dst, const jacobian *P, const curve_params *cc) -{ - unsigned char *buf; - uint32_t xbl; - size_t plen; - jacobian Q, T; - - buf = dst; - xbl = cc->p[0]; - xbl -= (xbl >> 5); - plen = (xbl + 7) >> 3; - buf[0] = 0x04; - memcpy(&Q, P, sizeof *P); - set_one(T.c[2], cc->p); - run_code(&Q, &T, cc, code_affine); - br_i31_encode(buf + 1, plen, Q.c[0]); - br_i31_encode(buf + 1 + plen, plen, Q.c[1]); -} - -static const br_ec_curve_def * -id_to_curve_def(int curve) -{ - switch (curve) { - case BR_EC_secp256r1: - return &br_secp256r1; - case BR_EC_secp384r1: - return &br_secp384r1; - case BR_EC_secp521r1: - return &br_secp521r1; - } - return NULL; -} - -static const unsigned char * -api_generator(int curve, size_t *len) -{ - const br_ec_curve_def *cd; - - cd = id_to_curve_def(curve); - *len = cd->generator_len; - return cd->generator; -} - -static const unsigned char * -api_order(int curve, size_t *len) -{ - const br_ec_curve_def *cd; - - cd = id_to_curve_def(curve); - *len = cd->order_len; - return cd->order; -} - -static size_t -api_xoff(int curve, size_t *len) -{ - api_generator(curve, len); - *len >>= 1; - return 1; -} - -static uint32_t -api_mul(unsigned char *G, size_t Glen, - const unsigned char *x, size_t xlen, int curve) -{ - uint32_t r; - const curve_params *cc; - jacobian P; - - cc = id_to_curve(curve); - r = point_decode(&P, G, Glen, cc); - point_mul(&P, x, xlen, cc); - point_encode(G, &P, cc); - return r; -} - -static size_t -api_mulgen(unsigned char *R, - const unsigned char *x, size_t xlen, int curve) -{ - const unsigned char *G; - size_t Glen; - - G = api_generator(curve, &Glen); - memcpy(R, G, Glen); - api_mul(R, Glen, x, xlen, curve); - return Glen; -} - -static uint32_t -api_muladd(unsigned char *A, const unsigned char *B, size_t len, - const unsigned char *x, size_t xlen, - const unsigned char *y, size_t ylen, int curve) -{ - uint32_t r, t, z; - const curve_params *cc; - jacobian P, Q; - - /* - * TODO: see about merging the two ladders. Right now, we do - * two independent point multiplications, which is a bit - * wasteful of CPU resources (but yields short code). - */ - - cc = id_to_curve(curve); - r = point_decode(&P, A, len, cc); - if (B == NULL) { - size_t Glen; - - B = api_generator(curve, &Glen); - } - r &= point_decode(&Q, B, len, cc); - point_mul(&P, x, xlen, cc); - point_mul(&Q, y, ylen, cc); - - /* - * We want to compute P+Q. Since the base points A and B are distinct - * from infinity, and the multipliers are non-zero and lower than the - * curve order, then we know that P and Q are non-infinity. This - * leaves two special situations to test for: - * -- If P = Q then we must use point_double(). - * -- If P+Q = 0 then we must report an error. - */ - t = point_add(&P, &Q, cc); - point_double(&Q, cc); - z = br_i31_iszero(P.c[2]); - - /* - * If z is 1 then either P+Q = 0 (t = 1) or P = Q (t = 0). So we - * have the following: - * - * z = 0, t = 0 return P (normal addition) - * z = 0, t = 1 return P (normal addition) - * z = 1, t = 0 return Q (a 'double' case) - * z = 1, t = 1 report an error (P+Q = 0) - */ - CCOPY(z & ~t, &P, &Q, sizeof Q); - point_encode(A, &P, cc); - r &= ~(z & t); - - return r; -} - -/* see bearssl_ec.h */ -const br_ec_impl br_ec_prime_i31 = { - (uint32_t)0x03800000, - &api_generator, - &api_order, - &api_xoff, - &api_mul, - &api_mulgen, - &api_muladd -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ec_pubkey.c b/src/tls/bearssl/ec_pubkey.c deleted file mode 100644 index 2b886b381..000000000 --- a/src/tls/bearssl/ec_pubkey.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -static const unsigned char POINT_LEN[] = { - 0, /* 0: not a valid curve ID */ - 43, /* sect163k1 */ - 43, /* sect163r1 */ - 43, /* sect163r2 */ - 51, /* sect193r1 */ - 51, /* sect193r2 */ - 61, /* sect233k1 */ - 61, /* sect233r1 */ - 61, /* sect239k1 */ - 73, /* sect283k1 */ - 73, /* sect283r1 */ - 105, /* sect409k1 */ - 105, /* sect409r1 */ - 145, /* sect571k1 */ - 145, /* sect571r1 */ - 41, /* secp160k1 */ - 41, /* secp160r1 */ - 41, /* secp160r2 */ - 49, /* secp192k1 */ - 49, /* secp192r1 */ - 57, /* secp224k1 */ - 57, /* secp224r1 */ - 65, /* secp256k1 */ - 65, /* secp256r1 */ - 97, /* secp384r1 */ - 133, /* secp521r1 */ - 65, /* brainpoolP256r1 */ - 97, /* brainpoolP384r1 */ - 129, /* brainpoolP512r1 */ - 32, /* curve25519 */ - 56, /* curve448 */ -}; - -/* see bearssl_ec.h */ -size_t -br_ec_compute_pub(const br_ec_impl *impl, br_ec_public_key *pk, - void *kbuf, const br_ec_private_key *sk) -{ - int curve; - size_t len; - - curve = sk->curve; - if (curve < 0 || curve >= 32 || curve >= (int)(sizeof POINT_LEN) - || ((impl->supported_curves >> curve) & 1) == 0) - { - return 0; - } - if (kbuf == NULL) { - return POINT_LEN[curve]; - } - len = impl->mulgen(kbuf, sk->x, sk->xlen, curve); - if (pk != NULL) { - pk->curve = curve; - pk->q = kbuf; - pk->qlen = len; - } - return len; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ec_secp256r1.c b/src/tls/bearssl/ec_secp256r1.c deleted file mode 100644 index 39ba1c514..000000000 --- a/src/tls/bearssl/ec_secp256r1.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -static const unsigned char P256_N[] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84, - 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51 -}; - -static const unsigned char P256_G[] = { - 0x04, 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, - 0x47, 0xF8, 0xBC, 0xE6, 0xE5, 0x63, 0xA4, 0x40, - 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, - 0xA0, 0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, - 0x96, 0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, - 0x9B, 0x8E, 0xE7, 0xEB, 0x4A, 0x7C, 0x0F, 0x9E, - 0x16, 0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, - 0xCE, 0xCB, 0xB6, 0x40, 0x68, 0x37, 0xBF, 0x51, - 0xF5 -}; - -/* see inner.h */ -const br_ec_curve_def br_secp256r1 = { - BR_EC_secp256r1, - P256_N, sizeof P256_N, - P256_G, sizeof P256_G -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ec_secp384r1.c b/src/tls/bearssl/ec_secp384r1.c deleted file mode 100644 index 27c0d2df7..000000000 --- a/src/tls/bearssl/ec_secp384r1.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -static const unsigned char P384_N[] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, - 0x58, 0x1A, 0x0D, 0xB2, 0x48, 0xB0, 0xA7, 0x7A, - 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73 -}; - -static const unsigned char P384_G[] = { - 0x04, 0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, - 0x37, 0x8E, 0xB1, 0xC7, 0x1E, 0xF3, 0x20, 0xAD, - 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, - 0x98, 0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, - 0x38, 0x55, 0x02, 0xF2, 0x5D, 0xBF, 0x55, 0x29, - 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, - 0xB7, 0x36, 0x17, 0xDE, 0x4A, 0x96, 0x26, 0x2C, - 0x6F, 0x5D, 0x9E, 0x98, 0xBF, 0x92, 0x92, 0xDC, - 0x29, 0xF8, 0xF4, 0x1D, 0xBD, 0x28, 0x9A, 0x14, - 0x7C, 0xE9, 0xDA, 0x31, 0x13, 0xB5, 0xF0, 0xB8, - 0xC0, 0x0A, 0x60, 0xB1, 0xCE, 0x1D, 0x7E, 0x81, - 0x9D, 0x7A, 0x43, 0x1D, 0x7C, 0x90, 0xEA, 0x0E, - 0x5F -}; - -/* see inner.h */ -const br_ec_curve_def br_secp384r1 = { - BR_EC_secp384r1, - P384_N, sizeof P384_N, - P384_G, sizeof P384_G -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ec_secp521r1.c b/src/tls/bearssl/ec_secp521r1.c deleted file mode 100644 index 34bb842cf..000000000 --- a/src/tls/bearssl/ec_secp521r1.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -static const unsigned char P521_N[] = { - 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFA, 0x51, 0x86, 0x87, 0x83, 0xBF, 0x2F, - 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09, - 0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, - 0x47, 0xAE, 0xBB, 0x6F, 0xB7, 0x1E, 0x91, 0x38, - 0x64, 0x09 -}; - -static const unsigned char P521_G[] = { - 0x04, 0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, - 0x04, 0xE9, 0xCD, 0x9E, 0x3E, 0xCB, 0x66, 0x23, - 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, - 0x3F, 0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, - 0x4D, 0x3D, 0xBA, 0xA1, 0x4B, 0x5E, 0x77, 0xEF, - 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, - 0xFF, 0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, - 0x6A, 0x42, 0x9B, 0xF9, 0x7E, 0x7E, 0x31, 0xC2, - 0xE5, 0xBD, 0x66, 0x01, 0x18, 0x39, 0x29, 0x6A, - 0x78, 0x9A, 0x3B, 0xC0, 0x04, 0x5C, 0x8A, 0x5F, - 0xB4, 0x2C, 0x7D, 0x1B, 0xD9, 0x98, 0xF5, 0x44, - 0x49, 0x57, 0x9B, 0x44, 0x68, 0x17, 0xAF, 0xBD, - 0x17, 0x27, 0x3E, 0x66, 0x2C, 0x97, 0xEE, 0x72, - 0x99, 0x5E, 0xF4, 0x26, 0x40, 0xC5, 0x50, 0xB9, - 0x01, 0x3F, 0xAD, 0x07, 0x61, 0x35, 0x3C, 0x70, - 0x86, 0xA2, 0x72, 0xC2, 0x40, 0x88, 0xBE, 0x94, - 0x76, 0x9F, 0xD1, 0x66, 0x50 -}; - -/* see inner.h */ -const br_ec_curve_def br_secp521r1 = { - BR_EC_secp521r1, - P521_N, sizeof P521_N, - P521_G, sizeof P521_G -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ecdsa_atr.c b/src/tls/bearssl/ecdsa_atr.c deleted file mode 100644 index cd0153a3a..000000000 --- a/src/tls/bearssl/ecdsa_atr.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_ec.h */ -size_t -br_ecdsa_asn1_to_raw(void *sig, size_t sig_len) -{ - /* - * Note: this code is a bit lenient in that it accepts a few - * deviations to DER with regards to minimality of encoding of - * lengths and integer values. These deviations are still - * unambiguous. - * - * Signature format is a SEQUENCE of two INTEGER values. We - * support only integers of less than 127 bytes each (signed - * encoding) so the resulting raw signature will have length - * at most 254 bytes. - */ - - unsigned char *buf, *r, *s; - size_t zlen, rlen, slen, off; - unsigned char tmp[254]; - - buf = sig; - if (sig_len < 8) { - return 0; - } - - /* - * First byte is SEQUENCE tag. - */ - if (buf[0] != 0x30) { - return 0; - } - - /* - * The SEQUENCE length will be encoded over one or two bytes. We - * limit the total SEQUENCE contents to 255 bytes, because it - * makes things simpler; this is enough for subgroup orders up - * to 999 bits. - */ - zlen = buf[1]; - if (zlen > 0x80) { - if (zlen != 0x81) { - return 0; - } - zlen = buf[2]; - if (zlen != sig_len - 3) { - return 0; - } - off = 3; - } else { - if (zlen != sig_len - 2) { - return 0; - } - off = 2; - } - - /* - * First INTEGER (r). - */ - if (buf[off ++] != 0x02) { - return 0; - } - rlen = buf[off ++]; - if (rlen >= 0x80) { - return 0; - } - r = buf + off; - off += rlen; - - /* - * Second INTEGER (s). - */ - if (off + 2 > sig_len) { - return 0; - } - if (buf[off ++] != 0x02) { - return 0; - } - slen = buf[off ++]; - if (slen >= 0x80 || slen != sig_len - off) { - return 0; - } - s = buf + off; - - /* - * Removing leading zeros from r and s. - */ - while (rlen > 0 && *r == 0) { - rlen --; - r ++; - } - while (slen > 0 && *s == 0) { - slen --; - s ++; - } - - /* - * Compute common length for the two integers, then copy integers - * into the temporary buffer, and finally copy it back over the - * signature buffer. - */ - zlen = rlen > slen ? rlen : slen; - sig_len = zlen << 1; - memset(tmp, 0, sig_len); - memcpy(tmp + zlen - rlen, r, rlen); - memcpy(tmp + sig_len - slen, s, slen); - memcpy(sig, tmp, sig_len); - return sig_len; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ecdsa_default_sign_asn1.c b/src/tls/bearssl/ecdsa_default_sign_asn1.c deleted file mode 100644 index 09fc7a6a9..000000000 --- a/src/tls/bearssl/ecdsa_default_sign_asn1.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_ec.h */ -br_ecdsa_sign -br_ecdsa_sign_asn1_get_default(void) -{ -#if BR_LOMUL - return &br_ecdsa_i15_sign_asn1; -#else - return &br_ecdsa_i31_sign_asn1; -#endif -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ecdsa_default_sign_raw.c b/src/tls/bearssl/ecdsa_default_sign_raw.c deleted file mode 100644 index e1b243c8e..000000000 --- a/src/tls/bearssl/ecdsa_default_sign_raw.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_ec.h */ -br_ecdsa_sign -br_ecdsa_sign_raw_get_default(void) -{ -#if BR_LOMUL - return &br_ecdsa_i15_sign_raw; -#else - return &br_ecdsa_i31_sign_raw; -#endif -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ecdsa_default_vrfy_asn1.c b/src/tls/bearssl/ecdsa_default_vrfy_asn1.c deleted file mode 100644 index f4ce11698..000000000 --- a/src/tls/bearssl/ecdsa_default_vrfy_asn1.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_ec.h */ -br_ecdsa_vrfy -br_ecdsa_vrfy_asn1_get_default(void) -{ -#if BR_LOMUL - return &br_ecdsa_i15_vrfy_asn1; -#else - return &br_ecdsa_i31_vrfy_asn1; -#endif -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ecdsa_default_vrfy_raw.c b/src/tls/bearssl/ecdsa_default_vrfy_raw.c deleted file mode 100644 index db13f1b99..000000000 --- a/src/tls/bearssl/ecdsa_default_vrfy_raw.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_ec.h */ -br_ecdsa_vrfy -br_ecdsa_vrfy_raw_get_default(void) -{ -#if BR_LOMUL - return &br_ecdsa_i15_vrfy_raw; -#else - return &br_ecdsa_i31_vrfy_raw; -#endif -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ecdsa_i15_bits.c b/src/tls/bearssl/ecdsa_i15_bits.c deleted file mode 100644 index 21c939513..000000000 --- a/src/tls/bearssl/ecdsa_i15_bits.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_ecdsa_i15_bits2int(uint16_t *x, - const void *src, size_t len, uint32_t ebitlen) -{ - uint32_t bitlen, hbitlen; - int sc; - - bitlen = ebitlen - (ebitlen >> 4); - hbitlen = (uint32_t)len << 3; - if (hbitlen > bitlen) { - len = (bitlen + 7) >> 3; - sc = (int)((hbitlen - bitlen) & 7); - } else { - sc = 0; - } - br_i15_zero(x, ebitlen); - br_i15_decode(x, src, len); - br_i15_rshift(x, sc); - x[0] = ebitlen; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ecdsa_i15_sign_asn1.c b/src/tls/bearssl/ecdsa_i15_sign_asn1.c deleted file mode 100644 index ab6d30cca..000000000 --- a/src/tls/bearssl/ecdsa_i15_sign_asn1.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -#define ORDER_LEN ((BR_MAX_EC_SIZE + 7) >> 3) - -/* see bearssl_ec.h */ -size_t -br_ecdsa_i15_sign_asn1(const br_ec_impl *impl, - const br_hash_class *hf, const void *hash_value, - const br_ec_private_key *sk, void *sig) -{ - unsigned char rsig[(ORDER_LEN << 1) + 12]; - size_t sig_len; - - sig_len = br_ecdsa_i15_sign_raw(impl, hf, hash_value, sk, rsig); - if (sig_len == 0) { - return 0; - } - sig_len = br_ecdsa_raw_to_asn1(rsig, sig_len); - memcpy(sig, rsig, sig_len); - return sig_len; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ecdsa_i15_sign_raw.c b/src/tls/bearssl/ecdsa_i15_sign_raw.c deleted file mode 100644 index f88628670..000000000 --- a/src/tls/bearssl/ecdsa_i15_sign_raw.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -#define I15_LEN ((BR_MAX_EC_SIZE + 29) / 15) -#define POINT_LEN (1 + (((BR_MAX_EC_SIZE + 7) >> 3) << 1)) -#define ORDER_LEN ((BR_MAX_EC_SIZE + 7) >> 3) - -/* see bearssl_ec.h */ -size_t -br_ecdsa_i15_sign_raw(const br_ec_impl *impl, - const br_hash_class *hf, const void *hash_value, - const br_ec_private_key *sk, void *sig) -{ - /* - * IMPORTANT: this code is fit only for curves with a prime - * order. This is needed so that modular reduction of the X - * coordinate of a point can be done with a simple subtraction. - * We also rely on the last byte of the curve order to be distinct - * from 0 and 1. - */ - const br_ec_curve_def *cd; - uint16_t n[I15_LEN], r[I15_LEN], s[I15_LEN], x[I15_LEN]; - uint16_t m[I15_LEN], k[I15_LEN], t1[I15_LEN], t2[I15_LEN]; - unsigned char tt[ORDER_LEN << 1]; - unsigned char eU[POINT_LEN]; - size_t hash_len, nlen, ulen; - uint16_t n0i; - uint32_t ctl; - br_hmac_drbg_context drbg; - - /* - * If the curve is not supported, then exit with an error. - */ - if (((impl->supported_curves >> sk->curve) & 1) == 0) { - return 0; - } - - /* - * Get the curve parameters (generator and order). - */ - switch (sk->curve) { - case BR_EC_secp256r1: - cd = &br_secp256r1; - break; - case BR_EC_secp384r1: - cd = &br_secp384r1; - break; - case BR_EC_secp521r1: - cd = &br_secp521r1; - break; - default: - return 0; - } - - /* - * Get modulus. - */ - nlen = cd->order_len; - br_i15_decode(n, cd->order, nlen); - n0i = br_i15_ninv15(n[1]); - - /* - * Get private key as an i15 integer. This also checks that the - * private key is well-defined (not zero, and less than the - * curve order). - */ - if (!br_i15_decode_mod(x, sk->x, sk->xlen, n)) { - return 0; - } - if (br_i15_iszero(x)) { - return 0; - } - - /* - * Get hash length. - */ - hash_len = (hf->desc >> BR_HASHDESC_OUT_OFF) & BR_HASHDESC_OUT_MASK; - - /* - * Truncate and reduce the hash value modulo the curve order. - */ - br_ecdsa_i15_bits2int(m, hash_value, hash_len, n[0]); - br_i15_sub(m, n, br_i15_sub(m, n, 0) ^ 1); - - /* - * RFC 6979 generation of the "k" value. - * - * The process uses HMAC_DRBG (with the hash function used to - * process the message that is to be signed). The seed is the - * concatenation of the encodings of the private key and - * the hash value (after truncation and modular reduction). - */ - br_i15_encode(tt, nlen, x); - br_i15_encode(tt + nlen, nlen, m); - br_hmac_drbg_init(&drbg, hf, tt, nlen << 1); - for (;;) { - br_hmac_drbg_generate(&drbg, tt, nlen); - br_ecdsa_i15_bits2int(k, tt, nlen, n[0]); - if (br_i15_iszero(k)) { - continue; - } - if (br_i15_sub(k, n, 0)) { - break; - } - } - - /* - * Compute k*G and extract the X coordinate, then reduce it - * modulo the curve order. Since we support only curves with - * prime order, that reduction is only a matter of computing - * a subtraction. - */ - br_i15_encode(tt, nlen, k); - ulen = impl->mulgen(eU, tt, nlen, sk->curve); - br_i15_zero(r, n[0]); - br_i15_decode(r, &eU[1], ulen >> 1); - r[0] = n[0]; - br_i15_sub(r, n, br_i15_sub(r, n, 0) ^ 1); - - /* - * Compute 1/k in double-Montgomery representation. We do so by - * first converting _from_ Montgomery representation (twice), - * then using a modular exponentiation. - */ - br_i15_from_monty(k, n, n0i); - br_i15_from_monty(k, n, n0i); - memcpy(tt, cd->order, nlen); - tt[nlen - 1] -= 2; - br_i15_modpow(k, tt, nlen, n, n0i, t1, t2); - - /* - * Compute s = (m+xr)/k (mod n). - * The k[] array contains R^2/k (double-Montgomery representation); - * we thus can use direct Montgomery multiplications and conversions - * from Montgomery, avoiding any call to br_i15_to_monty() (which - * is slower). - */ - br_i15_from_monty(m, n, n0i); - br_i15_montymul(t1, x, r, n, n0i); - ctl = br_i15_add(t1, m, 1); - ctl |= br_i15_sub(t1, n, 0) ^ 1; - br_i15_sub(t1, n, ctl); - br_i15_montymul(s, t1, k, n, n0i); - - /* - * Encode r and s in the signature. - */ - br_i15_encode(sig, nlen, r); - br_i15_encode((unsigned char *)sig + nlen, nlen, s); - return nlen << 1; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ecdsa_i15_vrfy_asn1.c b/src/tls/bearssl/ecdsa_i15_vrfy_asn1.c deleted file mode 100644 index 5b93e436b..000000000 --- a/src/tls/bearssl/ecdsa_i15_vrfy_asn1.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -#define FIELD_LEN ((BR_MAX_EC_SIZE + 7) >> 3) - -/* see bearssl_ec.h */ -uint32_t -br_ecdsa_i15_vrfy_asn1(const br_ec_impl *impl, - const void *hash, size_t hash_len, - const br_ec_public_key *pk, - const void *sig, size_t sig_len) -{ - /* - * We use a double-sized buffer because a malformed ASN.1 signature - * may trigger a size expansion when converting to "raw" format. - */ - unsigned char rsig[(FIELD_LEN << 2) + 24]; - - if (sig_len > ((sizeof rsig) >> 1)) { - return 0; - } - memcpy(rsig, sig, sig_len); - sig_len = br_ecdsa_asn1_to_raw(rsig, sig_len); - return br_ecdsa_i15_vrfy_raw(impl, hash, hash_len, pk, rsig, sig_len); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ecdsa_i15_vrfy_raw.c b/src/tls/bearssl/ecdsa_i15_vrfy_raw.c deleted file mode 100644 index fc40b8645..000000000 --- a/src/tls/bearssl/ecdsa_i15_vrfy_raw.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -#define I15_LEN ((BR_MAX_EC_SIZE + 29) / 15) -#define POINT_LEN (1 + (((BR_MAX_EC_SIZE + 7) >> 3) << 1)) - -/* see bearssl_ec.h */ -uint32_t -br_ecdsa_i15_vrfy_raw(const br_ec_impl *impl, - const void *hash, size_t hash_len, - const br_ec_public_key *pk, - const void *sig, size_t sig_len) -{ - /* - * IMPORTANT: this code is fit only for curves with a prime - * order. This is needed so that modular reduction of the X - * coordinate of a point can be done with a simple subtraction. - */ - const br_ec_curve_def *cd; - uint16_t n[I15_LEN], r[I15_LEN], s[I15_LEN], t1[I15_LEN], t2[I15_LEN]; - unsigned char tx[(BR_MAX_EC_SIZE + 7) >> 3]; - unsigned char ty[(BR_MAX_EC_SIZE + 7) >> 3]; - unsigned char eU[POINT_LEN]; - size_t nlen, rlen, ulen; - uint16_t n0i; - uint32_t res; - - /* - * If the curve is not supported, then report an error. - */ - if (((impl->supported_curves >> pk->curve) & 1) == 0) { - return 0; - } - - /* - * Get the curve parameters (generator and order). - */ - switch (pk->curve) { - case BR_EC_secp256r1: - cd = &br_secp256r1; - break; - case BR_EC_secp384r1: - cd = &br_secp384r1; - break; - case BR_EC_secp521r1: - cd = &br_secp521r1; - break; - default: - return 0; - } - - /* - * Signature length must be even. - */ - if (sig_len & 1) { - return 0; - } - rlen = sig_len >> 1; - - /* - * Public key point must have the proper size for this curve. - */ - if (pk->qlen != cd->generator_len) { - return 0; - } - - /* - * Get modulus; then decode the r and s values. They must be - * lower than the modulus, and s must not be null. - */ - nlen = cd->order_len; - br_i15_decode(n, cd->order, nlen); - n0i = br_i15_ninv15(n[1]); - if (!br_i15_decode_mod(r, sig, rlen, n)) { - return 0; - } - if (!br_i15_decode_mod(s, (const unsigned char *)sig + rlen, rlen, n)) { - return 0; - } - if (br_i15_iszero(s)) { - return 0; - } - - /* - * Invert s. We do that with a modular exponentiation; we use - * the fact that for all the curves we support, the least - * significant byte is not 0 or 1, so we can subtract 2 without - * any carry to process. - * We also want 1/s in Montgomery representation, which can be - * done by converting _from_ Montgomery representation before - * the inversion (because (1/s)*R = 1/(s/R)). - */ - br_i15_from_monty(s, n, n0i); - memcpy(tx, cd->order, nlen); - tx[nlen - 1] -= 2; - br_i15_modpow(s, tx, nlen, n, n0i, t1, t2); - - /* - * Truncate the hash to the modulus length (in bits) and reduce - * it modulo the curve order. The modular reduction can be done - * with a subtraction since the truncation already reduced the - * value to the modulus bit length. - */ - br_ecdsa_i15_bits2int(t1, hash, hash_len, n[0]); - br_i15_sub(t1, n, br_i15_sub(t1, n, 0) ^ 1); - - /* - * Multiply the (truncated, reduced) hash value with 1/s, result in - * t2, encoded in ty. - */ - br_i15_montymul(t2, t1, s, n, n0i); - br_i15_encode(ty, nlen, t2); - - /* - * Multiply r with 1/s, result in t1, encoded in tx. - */ - br_i15_montymul(t1, r, s, n, n0i); - br_i15_encode(tx, nlen, t1); - - /* - * Compute the point x*Q + y*G. - */ - ulen = cd->generator_len; - memcpy(eU, pk->q, ulen); - res = impl->muladd(eU, NULL, ulen, - tx, nlen, ty, nlen, cd->curve); - - /* - * Get the X coordinate, reduce modulo the curve order, and - * compare with the 'r' value. - * - * The modular reduction can be done with subtractions because - * we work with curves of prime order, so the curve order is - * close to the field order (Hasse's theorem). - */ - br_i15_zero(t1, n[0]); - br_i15_decode(t1, &eU[1], ulen >> 1); - t1[0] = n[0]; - br_i15_sub(t1, n, br_i15_sub(t1, n, 0) ^ 1); - res &= ~br_i15_sub(t1, r, 1); - res &= br_i15_iszero(t1); - return res; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ecdsa_i31_bits.c b/src/tls/bearssl/ecdsa_i31_bits.c deleted file mode 100644 index 97ab7facd..000000000 --- a/src/tls/bearssl/ecdsa_i31_bits.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_ecdsa_i31_bits2int(uint32_t *x, - const void *src, size_t len, uint32_t ebitlen) -{ - uint32_t bitlen, hbitlen; - int sc; - - bitlen = ebitlen - (ebitlen >> 5); - hbitlen = (uint32_t)len << 3; - if (hbitlen > bitlen) { - len = (bitlen + 7) >> 3; - sc = (int)((hbitlen - bitlen) & 7); - } else { - sc = 0; - } - br_i31_zero(x, ebitlen); - br_i31_decode(x, src, len); - br_i31_rshift(x, sc); - x[0] = ebitlen; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ecdsa_i31_sign_asn1.c b/src/tls/bearssl/ecdsa_i31_sign_asn1.c deleted file mode 100644 index 6131bb328..000000000 --- a/src/tls/bearssl/ecdsa_i31_sign_asn1.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -#define ORDER_LEN ((BR_MAX_EC_SIZE + 7) >> 3) - -/* see bearssl_ec.h */ -size_t -br_ecdsa_i31_sign_asn1(const br_ec_impl *impl, - const br_hash_class *hf, const void *hash_value, - const br_ec_private_key *sk, void *sig) -{ - unsigned char rsig[(ORDER_LEN << 1) + 12]; - size_t sig_len; - - sig_len = br_ecdsa_i31_sign_raw(impl, hf, hash_value, sk, rsig); - if (sig_len == 0) { - return 0; - } - sig_len = br_ecdsa_raw_to_asn1(rsig, sig_len); - memcpy(sig, rsig, sig_len); - return sig_len; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ecdsa_i31_sign_raw.c b/src/tls/bearssl/ecdsa_i31_sign_raw.c deleted file mode 100644 index 6a1d8a2f5..000000000 --- a/src/tls/bearssl/ecdsa_i31_sign_raw.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -#define I31_LEN ((BR_MAX_EC_SIZE + 61) / 31) -#define POINT_LEN (1 + (((BR_MAX_EC_SIZE + 7) >> 3) << 1)) -#define ORDER_LEN ((BR_MAX_EC_SIZE + 7) >> 3) - -/* see bearssl_ec.h */ -size_t -br_ecdsa_i31_sign_raw(const br_ec_impl *impl, - const br_hash_class *hf, const void *hash_value, - const br_ec_private_key *sk, void *sig) -{ - /* - * IMPORTANT: this code is fit only for curves with a prime - * order. This is needed so that modular reduction of the X - * coordinate of a point can be done with a simple subtraction. - * We also rely on the last byte of the curve order to be distinct - * from 0 and 1. - */ - const br_ec_curve_def *cd; - uint32_t n[I31_LEN], r[I31_LEN], s[I31_LEN], x[I31_LEN]; - uint32_t m[I31_LEN], k[I31_LEN], t1[I31_LEN], t2[I31_LEN]; - unsigned char tt[ORDER_LEN << 1]; - unsigned char eU[POINT_LEN]; - size_t hash_len, nlen, ulen; - uint32_t n0i, ctl; - br_hmac_drbg_context drbg; - - /* - * If the curve is not supported, then exit with an error. - */ - if (((impl->supported_curves >> sk->curve) & 1) == 0) { - return 0; - } - - /* - * Get the curve parameters (generator and order). - */ - switch (sk->curve) { - case BR_EC_secp256r1: - cd = &br_secp256r1; - break; - case BR_EC_secp384r1: - cd = &br_secp384r1; - break; - case BR_EC_secp521r1: - cd = &br_secp521r1; - break; - default: - return 0; - } - - /* - * Get modulus. - */ - nlen = cd->order_len; - br_i31_decode(n, cd->order, nlen); - n0i = br_i31_ninv31(n[1]); - - /* - * Get private key as an i31 integer. This also checks that the - * private key is well-defined (not zero, and less than the - * curve order). - */ - if (!br_i31_decode_mod(x, sk->x, sk->xlen, n)) { - return 0; - } - if (br_i31_iszero(x)) { - return 0; - } - - /* - * Get hash length. - */ - hash_len = (hf->desc >> BR_HASHDESC_OUT_OFF) & BR_HASHDESC_OUT_MASK; - - /* - * Truncate and reduce the hash value modulo the curve order. - */ - br_ecdsa_i31_bits2int(m, hash_value, hash_len, n[0]); - br_i31_sub(m, n, br_i31_sub(m, n, 0) ^ 1); - - /* - * RFC 6979 generation of the "k" value. - * - * The process uses HMAC_DRBG (with the hash function used to - * process the message that is to be signed). The seed is the - * concatenation of the encodings of the private key and - * the hash value (after truncation and modular reduction). - */ - br_i31_encode(tt, nlen, x); - br_i31_encode(tt + nlen, nlen, m); - br_hmac_drbg_init(&drbg, hf, tt, nlen << 1); - for (;;) { - br_hmac_drbg_generate(&drbg, tt, nlen); - br_ecdsa_i31_bits2int(k, tt, nlen, n[0]); - if (br_i31_iszero(k)) { - continue; - } - if (br_i31_sub(k, n, 0)) { - break; - } - } - - /* - * Compute k*G and extract the X coordinate, then reduce it - * modulo the curve order. Since we support only curves with - * prime order, that reduction is only a matter of computing - * a subtraction. - */ - br_i31_encode(tt, nlen, k); - ulen = impl->mulgen(eU, tt, nlen, sk->curve); - br_i31_zero(r, n[0]); - br_i31_decode(r, &eU[1], ulen >> 1); - r[0] = n[0]; - br_i31_sub(r, n, br_i31_sub(r, n, 0) ^ 1); - - /* - * Compute 1/k in double-Montgomery representation. We do so by - * first converting _from_ Montgomery representation (twice), - * then using a modular exponentiation. - */ - br_i31_from_monty(k, n, n0i); - br_i31_from_monty(k, n, n0i); - memcpy(tt, cd->order, nlen); - tt[nlen - 1] -= 2; - br_i31_modpow(k, tt, nlen, n, n0i, t1, t2); - - /* - * Compute s = (m+xr)/k (mod n). - * The k[] array contains R^2/k (double-Montgomery representation); - * we thus can use direct Montgomery multiplications and conversions - * from Montgomery, avoiding any call to br_i31_to_monty() (which - * is slower). - */ - br_i31_from_monty(m, n, n0i); - br_i31_montymul(t1, x, r, n, n0i); - ctl = br_i31_add(t1, m, 1); - ctl |= br_i31_sub(t1, n, 0) ^ 1; - br_i31_sub(t1, n, ctl); - br_i31_montymul(s, t1, k, n, n0i); - - /* - * Encode r and s in the signature. - */ - br_i31_encode(sig, nlen, r); - br_i31_encode((unsigned char *)sig + nlen, nlen, s); - return nlen << 1; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ecdsa_i31_vrfy_asn1.c b/src/tls/bearssl/ecdsa_i31_vrfy_asn1.c deleted file mode 100644 index 91f1b68cd..000000000 --- a/src/tls/bearssl/ecdsa_i31_vrfy_asn1.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -#define FIELD_LEN ((BR_MAX_EC_SIZE + 7) >> 3) - -/* see bearssl_ec.h */ -uint32_t -br_ecdsa_i31_vrfy_asn1(const br_ec_impl *impl, - const void *hash, size_t hash_len, - const br_ec_public_key *pk, - const void *sig, size_t sig_len) -{ - /* - * We use a double-sized buffer because a malformed ASN.1 signature - * may trigger a size expansion when converting to "raw" format. - */ - unsigned char rsig[(FIELD_LEN << 2) + 24]; - - if (sig_len > ((sizeof rsig) >> 1)) { - return 0; - } - memcpy(rsig, sig, sig_len); - sig_len = br_ecdsa_asn1_to_raw(rsig, sig_len); - return br_ecdsa_i31_vrfy_raw(impl, hash, hash_len, pk, rsig, sig_len); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ecdsa_i31_vrfy_raw.c b/src/tls/bearssl/ecdsa_i31_vrfy_raw.c deleted file mode 100644 index d6e09f471..000000000 --- a/src/tls/bearssl/ecdsa_i31_vrfy_raw.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -#define I31_LEN ((BR_MAX_EC_SIZE + 61) / 31) -#define POINT_LEN (1 + (((BR_MAX_EC_SIZE + 7) >> 3) << 1)) - -/* see bearssl_ec.h */ -uint32_t -br_ecdsa_i31_vrfy_raw(const br_ec_impl *impl, - const void *hash, size_t hash_len, - const br_ec_public_key *pk, - const void *sig, size_t sig_len) -{ - /* - * IMPORTANT: this code is fit only for curves with a prime - * order. This is needed so that modular reduction of the X - * coordinate of a point can be done with a simple subtraction. - */ - const br_ec_curve_def *cd; - uint32_t n[I31_LEN], r[I31_LEN], s[I31_LEN], t1[I31_LEN], t2[I31_LEN]; - unsigned char tx[(BR_MAX_EC_SIZE + 7) >> 3]; - unsigned char ty[(BR_MAX_EC_SIZE + 7) >> 3]; - unsigned char eU[POINT_LEN]; - size_t nlen, rlen, ulen; - uint32_t n0i, res; - - /* - * If the curve is not supported, then report an error. - */ - if (((impl->supported_curves >> pk->curve) & 1) == 0) { - return 0; - } - - /* - * Get the curve parameters (generator and order). - */ - switch (pk->curve) { - case BR_EC_secp256r1: - cd = &br_secp256r1; - break; - case BR_EC_secp384r1: - cd = &br_secp384r1; - break; - case BR_EC_secp521r1: - cd = &br_secp521r1; - break; - default: - return 0; - } - - /* - * Signature length must be even. - */ - if (sig_len & 1) { - return 0; - } - rlen = sig_len >> 1; - - /* - * Public key point must have the proper size for this curve. - */ - if (pk->qlen != cd->generator_len) { - return 0; - } - - /* - * Get modulus; then decode the r and s values. They must be - * lower than the modulus, and s must not be null. - */ - nlen = cd->order_len; - br_i31_decode(n, cd->order, nlen); - n0i = br_i31_ninv31(n[1]); - if (!br_i31_decode_mod(r, sig, rlen, n)) { - return 0; - } - if (!br_i31_decode_mod(s, (const unsigned char *)sig + rlen, rlen, n)) { - return 0; - } - if (br_i31_iszero(s)) { - return 0; - } - - /* - * Invert s. We do that with a modular exponentiation; we use - * the fact that for all the curves we support, the least - * significant byte is not 0 or 1, so we can subtract 2 without - * any carry to process. - * We also want 1/s in Montgomery representation, which can be - * done by converting _from_ Montgomery representation before - * the inversion (because (1/s)*R = 1/(s/R)). - */ - br_i31_from_monty(s, n, n0i); - memcpy(tx, cd->order, nlen); - tx[nlen - 1] -= 2; - br_i31_modpow(s, tx, nlen, n, n0i, t1, t2); - - /* - * Truncate the hash to the modulus length (in bits) and reduce - * it modulo the curve order. The modular reduction can be done - * with a subtraction since the truncation already reduced the - * value to the modulus bit length. - */ - br_ecdsa_i31_bits2int(t1, hash, hash_len, n[0]); - br_i31_sub(t1, n, br_i31_sub(t1, n, 0) ^ 1); - - /* - * Multiply the (truncated, reduced) hash value with 1/s, result in - * t2, encoded in ty. - */ - br_i31_montymul(t2, t1, s, n, n0i); - br_i31_encode(ty, nlen, t2); - - /* - * Multiply r with 1/s, result in t1, encoded in tx. - */ - br_i31_montymul(t1, r, s, n, n0i); - br_i31_encode(tx, nlen, t1); - - /* - * Compute the point x*Q + y*G. - */ - ulen = cd->generator_len; - memcpy(eU, pk->q, ulen); - res = impl->muladd(eU, NULL, ulen, - tx, nlen, ty, nlen, cd->curve); - - /* - * Get the X coordinate, reduce modulo the curve order, and - * compare with the 'r' value. - * - * The modular reduction can be done with subtractions because - * we work with curves of prime order, so the curve order is - * close to the field order (Hasse's theorem). - */ - br_i31_zero(t1, n[0]); - br_i31_decode(t1, &eU[1], ulen >> 1); - t1[0] = n[0]; - br_i31_sub(t1, n, br_i31_sub(t1, n, 0) ^ 1); - res &= ~br_i31_sub(t1, r, 1); - res &= br_i31_iszero(t1); - return res; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ecdsa_rta.c b/src/tls/bearssl/ecdsa_rta.c deleted file mode 100644 index 921828fe6..000000000 --- a/src/tls/bearssl/ecdsa_rta.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * Compute ASN.1 encoded length for the provided integer. The ASN.1 - * encoding is signed, so its leading bit must have value 0; it must - * also be of minimal length (so leading bytes of value 0 must be - * removed, except if that would contradict the rule about the sign - * bit). - */ -static size_t -asn1_int_length(const unsigned char *x, size_t xlen) -{ - while (xlen > 0 && *x == 0) { - x ++; - xlen --; - } - if (xlen == 0 || *x >= 0x80) { - xlen ++; - } - return xlen; -} - -/* see bearssl_ec.h */ -size_t -br_ecdsa_raw_to_asn1(void *sig, size_t sig_len) -{ - /* - * Internal buffer is large enough to accommodate a signature - * such that r and s fit on 125 bytes each (signed encoding), - * meaning a curve order of up to 999 bits. This is the limit - * that ensures "simple" length encodings. - */ - unsigned char *buf; - size_t hlen, rlen, slen, zlen, off; - unsigned char tmp[257]; - - buf = sig; - if ((sig_len & 1) != 0) { - return 0; - } - - /* - * Compute lengths for the two integers. - */ - hlen = sig_len >> 1; - rlen = asn1_int_length(buf, hlen); - slen = asn1_int_length(buf + hlen, hlen); - if (rlen > 125 || slen > 125) { - return 0; - } - - /* - * SEQUENCE header. - */ - tmp[0] = 0x30; - zlen = rlen + slen + 4; - if (zlen >= 0x80) { - tmp[1] = 0x81; - tmp[2] = zlen; - off = 3; - } else { - tmp[1] = zlen; - off = 2; - } - - /* - * First INTEGER (r). - */ - tmp[off ++] = 0x02; - tmp[off ++] = rlen; - if (rlen > hlen) { - tmp[off] = 0x00; - memcpy(tmp + off + 1, buf, hlen); - } else { - memcpy(tmp + off, buf + hlen - rlen, rlen); - } - off += rlen; - - /* - * Second INTEGER (s). - */ - tmp[off ++] = 0x02; - tmp[off ++] = slen; - if (slen > hlen) { - tmp[off] = 0x00; - memcpy(tmp + off + 1, buf + hlen, hlen); - } else { - memcpy(tmp + off, buf + sig_len - slen, slen); - } - off += slen; - - /* - * Return ASN.1 signature. - */ - memcpy(sig, tmp, off); - return off; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/enc16be.c b/src/tls/bearssl/enc16be.c deleted file mode 100644 index 06e4cf35e..000000000 --- a/src/tls/bearssl/enc16be.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_range_enc16be(void *dst, const uint16_t *v, size_t num) -{ - unsigned char *buf; - - buf = dst; - while (num -- > 0) { - br_enc16be(buf, *v ++); - buf += 2; - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/enc16le.c b/src/tls/bearssl/enc16le.c deleted file mode 100644 index dcea1802b..000000000 --- a/src/tls/bearssl/enc16le.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_range_enc16le(void *dst, const uint16_t *v, size_t num) -{ - unsigned char *buf; - - buf = dst; - while (num -- > 0) { - br_enc16le(buf, *v ++); - buf += 2; - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/enc32be.c b/src/tls/bearssl/enc32be.c deleted file mode 100644 index 26fa3cee1..000000000 --- a/src/tls/bearssl/enc32be.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#if defined(BOARD_HAS_ECCX08) || defined(BOARD_HAS_OFFLOADED_ECCX08) || \ - defined(BOARD_HAS_SE050) || defined(ARDUINO_ARCH_ESP32) || \ - defined(ARDUINO_UNOR4_WIFI) - -#include "inner.h" - -/* see inner.h */ -void -br_range_enc32be(void *dst, const uint32_t *v, size_t num) -{ - unsigned char *buf; - - buf = dst; - while (num -- > 0) { - br_enc32be(buf, *v ++); - buf += 4; - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/enc32le.c b/src/tls/bearssl/enc32le.c deleted file mode 100644 index 740434df1..000000000 --- a/src/tls/bearssl/enc32le.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_range_enc32le(void *dst, const uint32_t *v, size_t num) -{ - unsigned char *buf; - - buf = dst; - while (num -- > 0) { - br_enc32le(buf, *v ++); - buf += 4; - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/enc64be.c b/src/tls/bearssl/enc64be.c deleted file mode 100644 index 0dea84c8a..000000000 --- a/src/tls/bearssl/enc64be.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_range_enc64be(void *dst, const uint64_t *v, size_t num) -{ - unsigned char *buf; - - buf = dst; - while (num -- > 0) { - br_enc64be(buf, *v ++); - buf += 8; - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/enc64le.c b/src/tls/bearssl/enc64le.c deleted file mode 100644 index 992da2ba4..000000000 --- a/src/tls/bearssl/enc64le.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_range_enc64le(void *dst, const uint64_t *v, size_t num) -{ - unsigned char *buf; - - buf = dst; - while (num -- > 0) { - br_enc64le(buf, *v ++); - buf += 8; - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/encode_ec_pk8der.c b/src/tls/bearssl/encode_ec_pk8der.c deleted file mode 100644 index 410c8b9b5..000000000 --- a/src/tls/bearssl/encode_ec_pk8der.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_x509.h */ -size_t -br_encode_ec_pkcs8_der(void *dest, - const br_ec_private_key *sk, const br_ec_public_key *pk) -{ - /* - * ASN.1 format: - * - * OneAsymmetricKey ::= SEQUENCE { - * version Version, - * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, - * privateKey PrivateKey, - * attributes [0] Attributes OPTIONAL, - * ..., - * [[2: publicKey [1] PublicKey OPTIONAL ]], - * ... - * } - * - * We don't include attributes or public key (the public key - * is included in the private key value instead). The - * 'version' field is an INTEGER that we will set to 0 - * (meaning 'v1', compatible with previous versions of PKCS#8). - * The 'privateKeyAlgorithm' structure is an AlgorithmIdentifier - * whose OID should be id-ecPublicKey, with, as parameters, the - * curve OID. The 'privateKey' is an OCTET STRING, whose value - * is the "raw DER" encoding of the key pair. - */ - - /* - * OID id-ecPublicKey (1.2.840.10045.2.1), DER-encoded (with - * the tag). - */ - static const unsigned char OID_ECPUBKEY[] = { - 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01 - }; - - size_t len_version, len_privateKeyAlgorithm, len_privateKeyValue; - size_t len_privateKey, len_seq; - const unsigned char *oid; - - oid = br_get_curve_OID(sk->curve); - if (oid == NULL) { - return 0; - } - len_version = 3; - len_privateKeyAlgorithm = 2 + sizeof OID_ECPUBKEY + 2 + oid[0]; - len_privateKeyValue = br_encode_ec_raw_der_inner(NULL, sk, pk, 0); - len_privateKey = 1 + len_of_len(len_privateKeyValue) - + len_privateKeyValue; - len_seq = len_version + len_privateKeyAlgorithm + len_privateKey; - - if (dest == NULL) { - return 1 + len_of_len(len_seq) + len_seq; - } else { - unsigned char *buf; - size_t lenlen; - - buf = dest; - *buf ++ = 0x30; /* SEQUENCE tag */ - lenlen = br_asn1_encode_length(buf, len_seq); - buf += lenlen; - - /* version */ - *buf ++ = 0x02; - *buf ++ = 0x01; - *buf ++ = 0x00; - - /* privateKeyAlgorithm */ - *buf ++ = 0x30; - *buf ++ = (sizeof OID_ECPUBKEY) + 2 + oid[0]; - memcpy(buf, OID_ECPUBKEY, sizeof OID_ECPUBKEY); - buf += sizeof OID_ECPUBKEY; - *buf ++ = 0x06; - memcpy(buf, oid, 1 + oid[0]); - buf += 1 + oid[0]; - - /* privateKey */ - *buf ++ = 0x04; - buf += br_asn1_encode_length(buf, len_privateKeyValue); - br_encode_ec_raw_der_inner(buf, sk, pk, 0); - - return 1 + lenlen + len_seq; - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/encode_ec_rawder.c b/src/tls/bearssl/encode_ec_rawder.c deleted file mode 100644 index 305411dc0..000000000 --- a/src/tls/bearssl/encode_ec_rawder.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -const unsigned char * -br_get_curve_OID(int curve) -{ - static const unsigned char OID_secp256r1[] = { - 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07 - }; - static const unsigned char OID_secp384r1[] = { - 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22 - }; - static const unsigned char OID_secp521r1[] = { - 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23 - }; - - switch (curve) { - case BR_EC_secp256r1: return OID_secp256r1; - case BR_EC_secp384r1: return OID_secp384r1; - case BR_EC_secp521r1: return OID_secp521r1; - default: - return NULL; - } -} - -/* see inner.h */ -size_t -br_encode_ec_raw_der_inner(void *dest, - const br_ec_private_key *sk, const br_ec_public_key *pk, - int include_curve_oid) -{ - /* - * ASN.1 format: - * - * ECPrivateKey ::= SEQUENCE { - * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), - * privateKey OCTET STRING, - * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, - * publicKey [1] BIT STRING OPTIONAL - * } - * - * The tages '[0]' and '[1]' are explicit. The 'ECParameters' - * is a CHOICE; in our case, it will always be an OBJECT IDENTIFIER - * that identifies the curve. - * - * The value of the 'privateKey' field is the raw unsigned big-endian - * encoding of the private key (integer modulo the curve subgroup - * order); there is no INTEGER tag, and the leading bit may be 1. - * Also, leading bytes of value 0x00 are _not_ removed. - * - * The 'publicKey' contents are the raw encoded public key point, - * normally uncompressed (leading byte of value 0x04, followed - * by the unsigned big-endian encodings of the X and Y coordinates, - * padded to the full field length if necessary). - */ - - size_t len_version, len_privateKey, len_parameters, len_publicKey; - size_t len_publicKey_bits, len_seq; - const unsigned char *oid; - - if (include_curve_oid) { - oid = br_get_curve_OID(sk->curve); - if (oid == NULL) { - return 0; - } - } else { - oid = NULL; - } - len_version = 3; - len_privateKey = 1 + len_of_len(sk->xlen) + sk->xlen; - if (include_curve_oid) { - len_parameters = 4 + oid[0]; - } else { - len_parameters = 0; - } - if (pk == NULL) { - len_publicKey = 0; - len_publicKey_bits = 0; - } else { - len_publicKey_bits = 2 + len_of_len(pk->qlen) + pk->qlen; - len_publicKey = 1 + len_of_len(len_publicKey_bits) - + len_publicKey_bits; - } - len_seq = len_version + len_privateKey + len_parameters + len_publicKey; - if (dest == NULL) { - return 1 + len_of_len(len_seq) + len_seq; - } else { - unsigned char *buf; - size_t lenlen; - - buf = dest; - *buf ++ = 0x30; /* SEQUENCE tag */ - lenlen = br_asn1_encode_length(buf, len_seq); - buf += lenlen; - - /* version */ - *buf ++ = 0x02; - *buf ++ = 0x01; - *buf ++ = 0x01; - - /* privateKey */ - *buf ++ = 0x04; - buf += br_asn1_encode_length(buf, sk->xlen); - memcpy(buf, sk->x, sk->xlen); - buf += sk->xlen; - - /* parameters */ - if (include_curve_oid) { - *buf ++ = 0xA0; - *buf ++ = oid[0] + 2; - *buf ++ = 0x06; - memcpy(buf, oid, oid[0] + 1); - buf += oid[0] + 1; - } - - /* publicKey */ - if (pk != NULL) { - *buf ++ = 0xA1; - buf += br_asn1_encode_length(buf, len_publicKey_bits); - *buf ++ = 0x03; - buf += br_asn1_encode_length(buf, pk->qlen + 1); - *buf ++ = 0x00; - memcpy(buf, pk->q, pk->qlen); - /* buf += pk->qlen; */ - } - - return 1 + lenlen + len_seq; - } -} - -/* see bearssl_x509.h */ -size_t -br_encode_ec_raw_der(void *dest, - const br_ec_private_key *sk, const br_ec_public_key *pk) -{ - return br_encode_ec_raw_der_inner(dest, sk, pk, 1); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/encode_rsa_pk8der.c b/src/tls/bearssl/encode_rsa_pk8der.c deleted file mode 100644 index a8f9ef78c..000000000 --- a/src/tls/bearssl/encode_rsa_pk8der.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_x509.h */ -size_t -br_encode_rsa_pkcs8_der(void *dest, const br_rsa_private_key *sk, - const br_rsa_public_key *pk, const void *d, size_t dlen) -{ - /* - * ASN.1 format: - * - * OneAsymmetricKey ::= SEQUENCE { - * version Version, - * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, - * privateKey PrivateKey, - * attributes [0] Attributes OPTIONAL, - * ..., - * [[2: publicKey [1] PublicKey OPTIONAL ]], - * ... - * } - * - * We don't include attributes or public key. The 'version' field - * is an INTEGER that we will set to 0 (meaning 'v1', compatible - * with previous versions of PKCS#8). The 'privateKeyAlgorithm' - * structure is an AlgorithmIdentifier whose OID should be - * rsaEncryption, with NULL parameters. The 'privateKey' is an - * OCTET STRING, whose value is the "raw DER" encoding of the - * key pair. - * - * Since the private key value comes last, this function really - * adds a header, which is mostly fixed (only some lengths have - * to be modified. - */ - - /* - * Concatenation of: - * - DER encoding of an INTEGER of value 0 (the 'version' field) - * - DER encoding of a PrivateKeyAlgorithmIdentifier that uses - * the rsaEncryption OID, and NULL parameters - * - An OCTET STRING tag - */ - static const unsigned char PK8_HEAD[] = { - 0x02, 0x01, 0x00, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, - 0x04 - }; - - size_t len_raw, len_seq; - - len_raw = br_encode_rsa_raw_der(NULL, sk, pk, d, dlen); - len_seq = (sizeof PK8_HEAD) + len_of_len(len_raw) + len_raw; - if (dest == NULL) { - return 1 + len_of_len(len_seq) + len_seq; - } else { - unsigned char *buf; - size_t lenlen; - - buf = dest; - *buf ++ = 0x30; /* SEQUENCE tag */ - lenlen = br_asn1_encode_length(buf, len_seq); - buf += lenlen; - - /* version, privateKeyAlgorithm, privateKey tag */ - memcpy(buf, PK8_HEAD, sizeof PK8_HEAD); - buf += sizeof PK8_HEAD; - - /* privateKey */ - buf += br_asn1_encode_length(buf, len_raw); - br_encode_rsa_raw_der(buf, sk, pk, d, dlen); - - return 1 + lenlen + len_seq; - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/encode_rsa_rawder.c b/src/tls/bearssl/encode_rsa_rawder.c deleted file mode 100644 index 5e63f4db4..000000000 --- a/src/tls/bearssl/encode_rsa_rawder.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_x509.h */ -size_t -br_encode_rsa_raw_der(void *dest, const br_rsa_private_key *sk, - const br_rsa_public_key *pk, const void *d, size_t dlen) -{ - /* - * ASN.1 format: - * - * RSAPrivateKey ::= SEQUENCE { - * version Version, - * modulus INTEGER, -- n - * publicExponent INTEGER, -- e - * privateExponent INTEGER, -- d - * prime1 INTEGER, -- p - * prime2 INTEGER, -- q - * exponent1 INTEGER, -- d mod (p-1) - * exponent2 INTEGER, -- d mod (q-1) - * coefficient INTEGER, -- (inverse of q) mod p - * otherPrimeInfos OtherPrimeInfos OPTIONAL - * } - * - * The 'version' field is an INTEGER of value 0 (meaning: there - * are exactly two prime factors), and 'otherPrimeInfos' will - * be absent (because there are exactly two prime factors). - */ - - br_asn1_uint num[9]; - size_t u, slen; - - /* - * For all INTEGER values, get the pointer and length for the - * data bytes. - */ - num[0] = br_asn1_uint_prepare(NULL, 0); - num[1] = br_asn1_uint_prepare(pk->n, pk->nlen); - num[2] = br_asn1_uint_prepare(pk->e, pk->elen); - num[3] = br_asn1_uint_prepare(d, dlen); - num[4] = br_asn1_uint_prepare(sk->p, sk->plen); - num[5] = br_asn1_uint_prepare(sk->q, sk->qlen); - num[6] = br_asn1_uint_prepare(sk->dp, sk->dplen); - num[7] = br_asn1_uint_prepare(sk->dq, sk->dqlen); - num[8] = br_asn1_uint_prepare(sk->iq, sk->iqlen); - - /* - * Get the length of the SEQUENCE contents. - */ - slen = 0; - for (u = 0; u < 9; u ++) { - uint32_t ilen; - - ilen = num[u].asn1len; - slen += 1 + len_of_len(ilen) + ilen; - } - - if (dest == NULL) { - return 1 + len_of_len(slen) + slen; - } else { - unsigned char *buf; - size_t lenlen; - - buf = dest; - *buf ++ = 0x30; /* SEQUENCE tag */ - lenlen = br_asn1_encode_length(buf, slen); - buf += lenlen; - for (u = 0; u < 9; u ++) { - buf += br_asn1_encode_uint(buf, num[u]); - } - return 1 + lenlen + slen; - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/gcm.c b/src/tls/bearssl/gcm.c deleted file mode 100644 index 7bbfaeab8..000000000 --- a/src/tls/bearssl/gcm.c +++ /dev/null @@ -1,323 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * Implementation Notes - * ==================== - * - * Since CTR and GHASH implementations can handle only full blocks, a - * 16-byte buffer (buf[]) is maintained in the context: - * - * - When processing AAD, buf[] contains the 0-15 unprocessed bytes. - * - * - When doing CTR encryption / decryption, buf[] contains the AES output - * for the last partial block, to be used with the next few bytes of - * data, as well as the already encrypted bytes. For instance, if the - * processed data length so far is 21 bytes, then buf[0..4] contains - * the five last encrypted bytes, and buf[5..15] contains the next 11 - * AES output bytes to be XORed with the next 11 bytes of input. - * - * The recorded AES output bytes are used to complete the block when - * the corresponding bytes are obtained. Note that buf[] always - * contains the _encrypted_ bytes, whether we apply encryption or - * decryption: these bytes are used as input to GHASH when the block - * is complete. - * - * In both cases, the low bits of the data length counters (count_aad, - * count_ctr) are used to work out the current situation. - */ - -/* see bearssl_aead.h */ -void -br_gcm_init(br_gcm_context *ctx, const br_block_ctr_class **bctx, br_ghash gh) -{ - unsigned char iv[12]; - - ctx->vtable = &br_gcm_vtable; - ctx->bctx = bctx; - ctx->gh = gh; - - /* - * The GHASH key h[] is the raw encryption of the all-zero - * block. Since we only have a CTR implementation, we use it - * with an all-zero IV and a zero counter, to CTR-encrypt an - * all-zero block. - */ - memset(ctx->h, 0, sizeof ctx->h); - memset(iv, 0, sizeof iv); - (*bctx)->run(bctx, iv, 0, ctx->h, sizeof ctx->h); -} - -/* see bearssl_aead.h */ -void -br_gcm_reset(br_gcm_context *ctx, const void *iv, size_t len) -{ - /* - * If the provided nonce is 12 bytes, then this is the initial - * IV for CTR mode; it will be used with a counter that starts - * at 2 (value 1 is for encrypting the GHASH output into the tag). - * - * If the provided nonce has any other length, then it is hashed - * (with GHASH) into a 16-byte value that will be the IV for CTR - * (both 12-byte IV and 32-bit counter). - */ - if (len == 12) { - memcpy(ctx->j0_1, iv, 12); - ctx->j0_2 = 1; - } else { - unsigned char ty[16], tmp[16]; - - memset(ty, 0, sizeof ty); - ctx->gh(ty, ctx->h, iv, len); - memset(tmp, 0, 8); - br_enc64be(tmp + 8, (uint64_t)len << 3); - ctx->gh(ty, ctx->h, tmp, 16); - memcpy(ctx->j0_1, ty, 12); - ctx->j0_2 = br_dec32be(ty + 12); - } - ctx->jc = ctx->j0_2 + 1; - memset(ctx->y, 0, sizeof ctx->y); - ctx->count_aad = 0; - ctx->count_ctr = 0; -} - -/* see bearssl_aead.h */ -void -br_gcm_aad_inject(br_gcm_context *ctx, const void *data, size_t len) -{ - size_t ptr, dlen; - - ptr = (size_t)ctx->count_aad & (size_t)15; - if (ptr != 0) { - /* - * If there is a partial block, then we first try to - * complete it. - */ - size_t clen; - - clen = 16 - ptr; - if (len < clen) { - memcpy(ctx->buf + ptr, data, len); - ctx->count_aad += (uint64_t)len; - return; - } - memcpy(ctx->buf + ptr, data, clen); - ctx->gh(ctx->y, ctx->h, ctx->buf, 16); - data = (const unsigned char *)data + clen; - len -= clen; - ctx->count_aad += (uint64_t)clen; - } - - /* - * Now AAD is aligned on a 16-byte block (with regards to GHASH). - * We process all complete blocks, and save the last partial - * block. - */ - dlen = len & ~(size_t)15; - ctx->gh(ctx->y, ctx->h, data, dlen); - memcpy(ctx->buf, (const unsigned char *)data + dlen, len - dlen); - ctx->count_aad += (uint64_t)len; -} - -/* see bearssl_aead.h */ -void -br_gcm_flip(br_gcm_context *ctx) -{ - /* - * We complete the GHASH computation if there is a partial block. - * The GHASH implementation automatically applies padding with - * zeros. - */ - size_t ptr; - - ptr = (size_t)ctx->count_aad & (size_t)15; - if (ptr != 0) { - ctx->gh(ctx->y, ctx->h, ctx->buf, ptr); - } -} - -/* see bearssl_aead.h */ -void -br_gcm_run(br_gcm_context *ctx, int encrypt, void *data, size_t len) -{ - unsigned char *buf; - size_t ptr, dlen; - - buf = data; - ptr = (size_t)ctx->count_ctr & (size_t)15; - if (ptr != 0) { - /* - * If we have a partial block, then we try to complete it. - */ - size_t u, clen; - - clen = 16 - ptr; - if (len < clen) { - clen = len; - } - for (u = 0; u < clen; u ++) { - unsigned x, y; - - x = buf[u]; - y = x ^ ctx->buf[ptr + u]; - ctx->buf[ptr + u] = encrypt ? y : x; - buf[u] = y; - } - ctx->count_ctr += (uint64_t)clen; - buf += clen; - len -= clen; - if (ptr + clen < 16) { - return; - } - ctx->gh(ctx->y, ctx->h, ctx->buf, 16); - } - - /* - * Process full blocks. - */ - dlen = len & ~(size_t)15; - if (!encrypt) { - ctx->gh(ctx->y, ctx->h, buf, dlen); - } - ctx->jc = (*ctx->bctx)->run(ctx->bctx, ctx->j0_1, ctx->jc, buf, dlen); - if (encrypt) { - ctx->gh(ctx->y, ctx->h, buf, dlen); - } - buf += dlen; - len -= dlen; - ctx->count_ctr += (uint64_t)dlen; - - if (len > 0) { - /* - * There is a partial block. - */ - size_t u; - - memset(ctx->buf, 0, sizeof ctx->buf); - ctx->jc = (*ctx->bctx)->run(ctx->bctx, ctx->j0_1, - ctx->jc, ctx->buf, 16); - for (u = 0; u < len; u ++) { - unsigned x, y; - - x = buf[u]; - y = x ^ ctx->buf[u]; - ctx->buf[u] = encrypt ? y : x; - buf[u] = y; - } - ctx->count_ctr += (uint64_t)len; - } -} - -/* see bearssl_aead.h */ -void -br_gcm_get_tag(br_gcm_context *ctx, void *tag) -{ - size_t ptr; - unsigned char tmp[16]; - - ptr = (size_t)ctx->count_ctr & (size_t)15; - if (ptr > 0) { - /* - * There is a partial block: encrypted/decrypted data has - * been produced, but the encrypted bytes must still be - * processed by GHASH. - */ - ctx->gh(ctx->y, ctx->h, ctx->buf, ptr); - } - - /* - * Final block for GHASH: the AAD and plaintext lengths (in bits). - */ - br_enc64be(tmp, ctx->count_aad << 3); - br_enc64be(tmp + 8, ctx->count_ctr << 3); - ctx->gh(ctx->y, ctx->h, tmp, 16); - - /* - * Tag is the GHASH output XORed with the encryption of the - * nonce with the initial counter value. - */ - memcpy(tag, ctx->y, 16); - (*ctx->bctx)->run(ctx->bctx, ctx->j0_1, ctx->j0_2, tag, 16); -} - -/* see bearssl_aead.h */ -void -br_gcm_get_tag_trunc(br_gcm_context *ctx, void *tag, size_t len) -{ - unsigned char tmp[16]; - - br_gcm_get_tag(ctx, tmp); - memcpy(tag, tmp, len); -} - -/* see bearssl_aead.h */ -uint32_t -br_gcm_check_tag_trunc(br_gcm_context *ctx, const void *tag, size_t len) -{ - unsigned char tmp[16]; - size_t u; - int x; - - br_gcm_get_tag(ctx, tmp); - x = 0; - for (u = 0; u < len; u ++) { - x |= tmp[u] ^ ((const unsigned char *)tag)[u]; - } - return EQ0(x); -} - -/* see bearssl_aead.h */ -uint32_t -br_gcm_check_tag(br_gcm_context *ctx, const void *tag) -{ - return br_gcm_check_tag_trunc(ctx, tag, 16); -} - -/* see bearssl_aead.h */ -const br_aead_class br_gcm_vtable = { - 16, - (void (*)(const br_aead_class **, const void *, size_t)) - &br_gcm_reset, - (void (*)(const br_aead_class **, const void *, size_t)) - &br_gcm_aad_inject, - (void (*)(const br_aead_class **)) - &br_gcm_flip, - (void (*)(const br_aead_class **, int, void *, size_t)) - &br_gcm_run, - (void (*)(const br_aead_class **, void *)) - &br_gcm_get_tag, - (uint32_t (*)(const br_aead_class **, const void *)) - &br_gcm_check_tag, - (void (*)(const br_aead_class **, void *, size_t)) - &br_gcm_get_tag_trunc, - (uint32_t (*)(const br_aead_class **, const void *, size_t)) - &br_gcm_check_tag_trunc -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ghash_ctmul.c b/src/tls/bearssl/ghash_ctmul.c deleted file mode 100644 index ddb8300a6..000000000 --- a/src/tls/bearssl/ghash_ctmul.c +++ /dev/null @@ -1,350 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * We compute "carryless multiplications" through normal integer - * multiplications, masking out enough bits to create "holes" in which - * carries may expand without altering our bits; we really use 8 data - * bits per 32-bit word, spaced every fourth bit. Accumulated carries - * may not exceed 8 in total, which fits in 4 bits. - * - * It would be possible to use a 3-bit spacing, allowing two operands, - * one with 7 non-zero data bits, the other one with 10 or 11 non-zero - * data bits; this asymmetric splitting makes the overall code more - * complex with thresholds and exceptions, and does not appear to be - * worth the effort. - */ - -/* - * We cannot really autodetect whether multiplications are "slow" or - * not. A typical example is the ARM Cortex M0+, which exists in two - * versions: one with a 1-cycle multiplication opcode, the other with - * a 32-cycle multiplication opcode. They both use exactly the same - * architecture and ABI, and cannot be distinguished from each other - * at compile-time. - * - * Since most modern CPU (even embedded CPU) still have fast - * multiplications, we use the "fast mul" code by default. - */ - -#if BR_SLOW_MUL - -/* - * This implementation uses Karatsuba-like reduction to make fewer - * integer multiplications (9 instead of 16), at the expense of extra - * logical operations (XOR, shifts...). On modern x86 CPU that offer - * fast, pipelined multiplications, this code is about twice slower than - * the simpler code with 16 multiplications. This tendency may be - * reversed on low-end platforms with expensive multiplications. - */ - -#define MUL32(h, l, x, y) do { \ - uint64_t mul32tmp = MUL(x, y); \ - (h) = (uint32_t)(mul32tmp >> 32); \ - (l) = (uint32_t)mul32tmp; \ - } while (0) - -static inline void -bmul(uint32_t *hi, uint32_t *lo, uint32_t x, uint32_t y) -{ - uint32_t x0, x1, x2, x3; - uint32_t y0, y1, y2, y3; - uint32_t a0, a1, a2, a3, a4, a5, a6, a7, a8; - uint32_t b0, b1, b2, b3, b4, b5, b6, b7, b8; - - x0 = x & (uint32_t)0x11111111; - x1 = x & (uint32_t)0x22222222; - x2 = x & (uint32_t)0x44444444; - x3 = x & (uint32_t)0x88888888; - y0 = y & (uint32_t)0x11111111; - y1 = y & (uint32_t)0x22222222; - y2 = y & (uint32_t)0x44444444; - y3 = y & (uint32_t)0x88888888; - - /* - * (x0+W*x1)*(y0+W*y1) -> a0:b0 - * (x2+W*x3)*(y2+W*y3) -> a3:b3 - * ((x0+x2)+W*(x1+x3))*((y0+y2)+W*(y1+y3)) -> a6:b6 - */ - a0 = x0; - b0 = y0; - a1 = x1 >> 1; - b1 = y1 >> 1; - a2 = a0 ^ a1; - b2 = b0 ^ b1; - a3 = x2 >> 2; - b3 = y2 >> 2; - a4 = x3 >> 3; - b4 = y3 >> 3; - a5 = a3 ^ a4; - b5 = b3 ^ b4; - a6 = a0 ^ a3; - b6 = b0 ^ b3; - a7 = a1 ^ a4; - b7 = b1 ^ b4; - a8 = a6 ^ a7; - b8 = b6 ^ b7; - - MUL32(b0, a0, b0, a0); - MUL32(b1, a1, b1, a1); - MUL32(b2, a2, b2, a2); - MUL32(b3, a3, b3, a3); - MUL32(b4, a4, b4, a4); - MUL32(b5, a5, b5, a5); - MUL32(b6, a6, b6, a6); - MUL32(b7, a7, b7, a7); - MUL32(b8, a8, b8, a8); - - a0 &= (uint32_t)0x11111111; - a1 &= (uint32_t)0x11111111; - a2 &= (uint32_t)0x11111111; - a3 &= (uint32_t)0x11111111; - a4 &= (uint32_t)0x11111111; - a5 &= (uint32_t)0x11111111; - a6 &= (uint32_t)0x11111111; - a7 &= (uint32_t)0x11111111; - a8 &= (uint32_t)0x11111111; - b0 &= (uint32_t)0x11111111; - b1 &= (uint32_t)0x11111111; - b2 &= (uint32_t)0x11111111; - b3 &= (uint32_t)0x11111111; - b4 &= (uint32_t)0x11111111; - b5 &= (uint32_t)0x11111111; - b6 &= (uint32_t)0x11111111; - b7 &= (uint32_t)0x11111111; - b8 &= (uint32_t)0x11111111; - - a2 ^= a0 ^ a1; - b2 ^= b0 ^ b1; - a0 ^= (a2 << 1) ^ (a1 << 2); - b0 ^= (b2 << 1) ^ (b1 << 2); - a5 ^= a3 ^ a4; - b5 ^= b3 ^ b4; - a3 ^= (a5 << 1) ^ (a4 << 2); - b3 ^= (b5 << 1) ^ (b4 << 2); - a8 ^= a6 ^ a7; - b8 ^= b6 ^ b7; - a6 ^= (a8 << 1) ^ (a7 << 2); - b6 ^= (b8 << 1) ^ (b7 << 2); - a6 ^= a0 ^ a3; - b6 ^= b0 ^ b3; - *lo = a0 ^ (a6 << 2) ^ (a3 << 4); - *hi = b0 ^ (b6 << 2) ^ (b3 << 4) ^ (a6 >> 30) ^ (a3 >> 28); -} - -#else - -/* - * Simple multiplication in GF(2)[X], using 16 integer multiplications. - */ - -static inline void -bmul(uint32_t *hi, uint32_t *lo, uint32_t x, uint32_t y) -{ - uint32_t x0, x1, x2, x3; - uint32_t y0, y1, y2, y3; - uint64_t z0, z1, z2, z3; - uint64_t z; - - x0 = x & (uint32_t)0x11111111; - x1 = x & (uint32_t)0x22222222; - x2 = x & (uint32_t)0x44444444; - x3 = x & (uint32_t)0x88888888; - y0 = y & (uint32_t)0x11111111; - y1 = y & (uint32_t)0x22222222; - y2 = y & (uint32_t)0x44444444; - y3 = y & (uint32_t)0x88888888; - z0 = MUL(x0, y0) ^ MUL(x1, y3) ^ MUL(x2, y2) ^ MUL(x3, y1); - z1 = MUL(x0, y1) ^ MUL(x1, y0) ^ MUL(x2, y3) ^ MUL(x3, y2); - z2 = MUL(x0, y2) ^ MUL(x1, y1) ^ MUL(x2, y0) ^ MUL(x3, y3); - z3 = MUL(x0, y3) ^ MUL(x1, y2) ^ MUL(x2, y1) ^ MUL(x3, y0); - z0 &= (uint64_t)0x1111111111111111; - z1 &= (uint64_t)0x2222222222222222; - z2 &= (uint64_t)0x4444444444444444; - z3 &= (uint64_t)0x8888888888888888; - z = z0 | z1 | z2 | z3; - *lo = (uint32_t)z; - *hi = (uint32_t)(z >> 32); -} - -#endif - -/* see bearssl_hash.h */ -void -br_ghash_ctmul(void *y, const void *h, const void *data, size_t len) -{ - const unsigned char *buf, *hb; - unsigned char *yb; - uint32_t yw[4]; - uint32_t hw[4]; - - /* - * Throughout the loop we handle the y and h values as arrays - * of 32-bit words. - */ - buf = data; - yb = y; - hb = h; - yw[3] = br_dec32be(yb); - yw[2] = br_dec32be(yb + 4); - yw[1] = br_dec32be(yb + 8); - yw[0] = br_dec32be(yb + 12); - hw[3] = br_dec32be(hb); - hw[2] = br_dec32be(hb + 4); - hw[1] = br_dec32be(hb + 8); - hw[0] = br_dec32be(hb + 12); - while (len > 0) { - const unsigned char *src; - unsigned char tmp[16]; - int i; - uint32_t a[9], b[9], zw[8]; - uint32_t c0, c1, c2, c3, d0, d1, d2, d3, e0, e1, e2, e3; - - /* - * Get the next 16-byte block (using zero-padding if - * necessary). - */ - if (len >= 16) { - src = buf; - buf += 16; - len -= 16; - } else { - memcpy(tmp, buf, len); - memset(tmp + len, 0, (sizeof tmp) - len); - src = tmp; - len = 0; - } - - /* - * Decode the block. The GHASH standard mandates - * big-endian encoding. - */ - yw[3] ^= br_dec32be(src); - yw[2] ^= br_dec32be(src + 4); - yw[1] ^= br_dec32be(src + 8); - yw[0] ^= br_dec32be(src + 12); - - /* - * We multiply two 128-bit field elements. We use - * Karatsuba to turn that into three 64-bit - * multiplications, which are themselves done with a - * total of nine 32-bit multiplications. - */ - - /* - * y[0,1]*h[0,1] -> 0..2 - * y[2,3]*h[2,3] -> 3..5 - * (y[0,1]+y[2,3])*(h[0,1]+h[2,3]) -> 6..8 - */ - a[0] = yw[0]; - b[0] = hw[0]; - a[1] = yw[1]; - b[1] = hw[1]; - a[2] = a[0] ^ a[1]; - b[2] = b[0] ^ b[1]; - - a[3] = yw[2]; - b[3] = hw[2]; - a[4] = yw[3]; - b[4] = hw[3]; - a[5] = a[3] ^ a[4]; - b[5] = b[3] ^ b[4]; - - a[6] = a[0] ^ a[3]; - b[6] = b[0] ^ b[3]; - a[7] = a[1] ^ a[4]; - b[7] = b[1] ^ b[4]; - a[8] = a[6] ^ a[7]; - b[8] = b[6] ^ b[7]; - - for (i = 0; i < 9; i ++) { - bmul(&b[i], &a[i], b[i], a[i]); - } - - c0 = a[0]; - c1 = b[0] ^ a[2] ^ a[0] ^ a[1]; - c2 = a[1] ^ b[2] ^ b[0] ^ b[1]; - c3 = b[1]; - d0 = a[3]; - d1 = b[3] ^ a[5] ^ a[3] ^ a[4]; - d2 = a[4] ^ b[5] ^ b[3] ^ b[4]; - d3 = b[4]; - e0 = a[6]; - e1 = b[6] ^ a[8] ^ a[6] ^ a[7]; - e2 = a[7] ^ b[8] ^ b[6] ^ b[7]; - e3 = b[7]; - - e0 ^= c0 ^ d0; - e1 ^= c1 ^ d1; - e2 ^= c2 ^ d2; - e3 ^= c3 ^ d3; - c2 ^= e0; - c3 ^= e1; - d0 ^= e2; - d1 ^= e3; - - /* - * GHASH specification has the bits "reversed" (most - * significant is in fact least significant), which does - * not matter for a carryless multiplication, except that - * the 255-bit result must be shifted by 1 bit. - */ - zw[0] = c0 << 1; - zw[1] = (c1 << 1) | (c0 >> 31); - zw[2] = (c2 << 1) | (c1 >> 31); - zw[3] = (c3 << 1) | (c2 >> 31); - zw[4] = (d0 << 1) | (c3 >> 31); - zw[5] = (d1 << 1) | (d0 >> 31); - zw[6] = (d2 << 1) | (d1 >> 31); - zw[7] = (d3 << 1) | (d2 >> 31); - - /* - * We now do the reduction modulo the field polynomial - * to get back to 128 bits. - */ - for (i = 0; i < 4; i ++) { - uint32_t lw; - - lw = zw[i]; - zw[i + 4] ^= lw ^ (lw >> 1) ^ (lw >> 2) ^ (lw >> 7); - zw[i + 3] ^= (lw << 31) ^ (lw << 30) ^ (lw << 25); - } - memcpy(yw, zw + 4, sizeof yw); - } - - /* - * Encode back the result. - */ - br_enc32be(yb, yw[3]); - br_enc32be(yb + 4, yw[2]); - br_enc32be(yb + 8, yw[1]); - br_enc32be(yb + 12, yw[0]); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ghash_ctmul32.c b/src/tls/bearssl/ghash_ctmul32.c deleted file mode 100644 index 638c5aa5a..000000000 --- a/src/tls/bearssl/ghash_ctmul32.c +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * This implementation uses 32-bit multiplications, and only the low - * 32 bits for each multiplication result. This is meant primarily for - * the ARM Cortex M0 and M0+, whose multiplication opcode does not yield - * the upper 32 bits; but it might also be useful on architectures where - * access to the upper 32 bits requires use of specific registers that - * create contention (e.g. on i386, "mul" necessarily outputs the result - * in edx:eax, while "imul" can use any registers but is limited to the - * low 32 bits). - * - * The implementation trick that is used here is bit-reversing (bit 0 - * is swapped with bit 31, bit 1 with bit 30, and so on). In GF(2)[X], - * for all values x and y, we have: - * rev32(x) * rev32(y) = rev64(x * y) - * In other words, if we bit-reverse (over 32 bits) the operands, then we - * bit-reverse (over 64 bits) the result. - */ - -/* - * Multiplication in GF(2)[X], truncated to its low 32 bits. - */ -static inline uint32_t -bmul32(uint32_t x, uint32_t y) -{ - uint32_t x0, x1, x2, x3; - uint32_t y0, y1, y2, y3; - uint32_t z0, z1, z2, z3; - - x0 = x & (uint32_t)0x11111111; - x1 = x & (uint32_t)0x22222222; - x2 = x & (uint32_t)0x44444444; - x3 = x & (uint32_t)0x88888888; - y0 = y & (uint32_t)0x11111111; - y1 = y & (uint32_t)0x22222222; - y2 = y & (uint32_t)0x44444444; - y3 = y & (uint32_t)0x88888888; - z0 = (x0 * y0) ^ (x1 * y3) ^ (x2 * y2) ^ (x3 * y1); - z1 = (x0 * y1) ^ (x1 * y0) ^ (x2 * y3) ^ (x3 * y2); - z2 = (x0 * y2) ^ (x1 * y1) ^ (x2 * y0) ^ (x3 * y3); - z3 = (x0 * y3) ^ (x1 * y2) ^ (x2 * y1) ^ (x3 * y0); - z0 &= (uint32_t)0x11111111; - z1 &= (uint32_t)0x22222222; - z2 &= (uint32_t)0x44444444; - z3 &= (uint32_t)0x88888888; - return z0 | z1 | z2 | z3; -} - -/* - * Bit-reverse a 32-bit word. - */ -static uint32_t -rev32(uint32_t x) -{ -#define RMS(m, s) do { \ - x = ((x & (uint32_t)(m)) << (s)) \ - | ((x >> (s)) & (uint32_t)(m)); \ - } while (0) - - RMS(0x55555555, 1); - RMS(0x33333333, 2); - RMS(0x0F0F0F0F, 4); - RMS(0x00FF00FF, 8); - return (x << 16) | (x >> 16); - -#undef RMS -} - -/* see bearssl_hash.h */ -void -br_ghash_ctmul32(void *y, const void *h, const void *data, size_t len) -{ - /* - * This implementation is similar to br_ghash_ctmul() except - * that we have to do the multiplication twice, with the - * "normal" and "bit reversed" operands. Hence we end up with - * eighteen 32-bit multiplications instead of nine. - */ - - const unsigned char *buf, *hb; - unsigned char *yb; - uint32_t yw[4]; - uint32_t hw[4], hwr[4]; - - buf = data; - yb = y; - hb = h; - yw[3] = br_dec32be(yb); - yw[2] = br_dec32be(yb + 4); - yw[1] = br_dec32be(yb + 8); - yw[0] = br_dec32be(yb + 12); - hw[3] = br_dec32be(hb); - hw[2] = br_dec32be(hb + 4); - hw[1] = br_dec32be(hb + 8); - hw[0] = br_dec32be(hb + 12); - hwr[3] = rev32(hw[3]); - hwr[2] = rev32(hw[2]); - hwr[1] = rev32(hw[1]); - hwr[0] = rev32(hw[0]); - while (len > 0) { - const unsigned char *src; - unsigned char tmp[16]; - int i; - uint32_t a[18], b[18], c[18]; - uint32_t d0, d1, d2, d3, d4, d5, d6, d7; - uint32_t zw[8]; - - if (len >= 16) { - src = buf; - buf += 16; - len -= 16; - } else { - memcpy(tmp, buf, len); - memset(tmp + len, 0, (sizeof tmp) - len); - src = tmp; - len = 0; - } - yw[3] ^= br_dec32be(src); - yw[2] ^= br_dec32be(src + 4); - yw[1] ^= br_dec32be(src + 8); - yw[0] ^= br_dec32be(src + 12); - - /* - * We are using Karatsuba: the 128x128 multiplication is - * reduced to three 64x64 multiplications, hence nine - * 32x32 multiplications. With the bit-reversal trick, - * we have to perform 18 32x32 multiplications. - */ - - /* - * y[0,1]*h[0,1] -> 0,1,4 - * y[2,3]*h[2,3] -> 2,3,5 - * (y[0,1]+y[2,3])*(h[0,1]+h[2,3]) -> 6,7,8 - */ - - a[0] = yw[0]; - a[1] = yw[1]; - a[2] = yw[2]; - a[3] = yw[3]; - a[4] = a[0] ^ a[1]; - a[5] = a[2] ^ a[3]; - a[6] = a[0] ^ a[2]; - a[7] = a[1] ^ a[3]; - a[8] = a[6] ^ a[7]; - - a[ 9] = rev32(yw[0]); - a[10] = rev32(yw[1]); - a[11] = rev32(yw[2]); - a[12] = rev32(yw[3]); - a[13] = a[ 9] ^ a[10]; - a[14] = a[11] ^ a[12]; - a[15] = a[ 9] ^ a[11]; - a[16] = a[10] ^ a[12]; - a[17] = a[15] ^ a[16]; - - b[0] = hw[0]; - b[1] = hw[1]; - b[2] = hw[2]; - b[3] = hw[3]; - b[4] = b[0] ^ b[1]; - b[5] = b[2] ^ b[3]; - b[6] = b[0] ^ b[2]; - b[7] = b[1] ^ b[3]; - b[8] = b[6] ^ b[7]; - - b[ 9] = hwr[0]; - b[10] = hwr[1]; - b[11] = hwr[2]; - b[12] = hwr[3]; - b[13] = b[ 9] ^ b[10]; - b[14] = b[11] ^ b[12]; - b[15] = b[ 9] ^ b[11]; - b[16] = b[10] ^ b[12]; - b[17] = b[15] ^ b[16]; - - for (i = 0; i < 18; i ++) { - c[i] = bmul32(a[i], b[i]); - } - - c[4] ^= c[0] ^ c[1]; - c[5] ^= c[2] ^ c[3]; - c[8] ^= c[6] ^ c[7]; - - c[13] ^= c[ 9] ^ c[10]; - c[14] ^= c[11] ^ c[12]; - c[17] ^= c[15] ^ c[16]; - - /* - * y[0,1]*h[0,1] -> 0,9^4,1^13,10 - * y[2,3]*h[2,3] -> 2,11^5,3^14,12 - * (y[0,1]+y[2,3])*(h[0,1]+h[2,3]) -> 6,15^8,7^17,16 - */ - d0 = c[0]; - d1 = c[4] ^ (rev32(c[9]) >> 1); - d2 = c[1] ^ c[0] ^ c[2] ^ c[6] ^ (rev32(c[13]) >> 1); - d3 = c[4] ^ c[5] ^ c[8] - ^ (rev32(c[10] ^ c[9] ^ c[11] ^ c[15]) >> 1); - d4 = c[2] ^ c[1] ^ c[3] ^ c[7] - ^ (rev32(c[13] ^ c[14] ^ c[17]) >> 1); - d5 = c[5] ^ (rev32(c[11] ^ c[10] ^ c[12] ^ c[16]) >> 1); - d6 = c[3] ^ (rev32(c[14]) >> 1); - d7 = rev32(c[12]) >> 1; - - zw[0] = d0 << 1; - zw[1] = (d1 << 1) | (d0 >> 31); - zw[2] = (d2 << 1) | (d1 >> 31); - zw[3] = (d3 << 1) | (d2 >> 31); - zw[4] = (d4 << 1) | (d3 >> 31); - zw[5] = (d5 << 1) | (d4 >> 31); - zw[6] = (d6 << 1) | (d5 >> 31); - zw[7] = (d7 << 1) | (d6 >> 31); - - for (i = 0; i < 4; i ++) { - uint32_t lw; - - lw = zw[i]; - zw[i + 4] ^= lw ^ (lw >> 1) ^ (lw >> 2) ^ (lw >> 7); - zw[i + 3] ^= (lw << 31) ^ (lw << 30) ^ (lw << 25); - } - memcpy(yw, zw + 4, sizeof yw); - } - br_enc32be(yb, yw[3]); - br_enc32be(yb + 4, yw[2]); - br_enc32be(yb + 8, yw[1]); - br_enc32be(yb + 12, yw[0]); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ghash_ctmul64.c b/src/tls/bearssl/ghash_ctmul64.c deleted file mode 100644 index b3902d10a..000000000 --- a/src/tls/bearssl/ghash_ctmul64.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * This is the 64-bit variant of br_ghash_ctmul32(), with 64-bit operands - * and bit reversal of 64-bit words. - */ - -static inline uint64_t -bmul64(uint64_t x, uint64_t y) -{ - uint64_t x0, x1, x2, x3; - uint64_t y0, y1, y2, y3; - uint64_t z0, z1, z2, z3; - - x0 = x & (uint64_t)0x1111111111111111; - x1 = x & (uint64_t)0x2222222222222222; - x2 = x & (uint64_t)0x4444444444444444; - x3 = x & (uint64_t)0x8888888888888888; - y0 = y & (uint64_t)0x1111111111111111; - y1 = y & (uint64_t)0x2222222222222222; - y2 = y & (uint64_t)0x4444444444444444; - y3 = y & (uint64_t)0x8888888888888888; - z0 = (x0 * y0) ^ (x1 * y3) ^ (x2 * y2) ^ (x3 * y1); - z1 = (x0 * y1) ^ (x1 * y0) ^ (x2 * y3) ^ (x3 * y2); - z2 = (x0 * y2) ^ (x1 * y1) ^ (x2 * y0) ^ (x3 * y3); - z3 = (x0 * y3) ^ (x1 * y2) ^ (x2 * y1) ^ (x3 * y0); - z0 &= (uint64_t)0x1111111111111111; - z1 &= (uint64_t)0x2222222222222222; - z2 &= (uint64_t)0x4444444444444444; - z3 &= (uint64_t)0x8888888888888888; - return z0 | z1 | z2 | z3; -} - -static uint64_t -rev64(uint64_t x) -{ -#define RMS(m, s) do { \ - x = ((x & (uint64_t)(m)) << (s)) \ - | ((x >> (s)) & (uint64_t)(m)); \ - } while (0) - - RMS(0x5555555555555555, 1); - RMS(0x3333333333333333, 2); - RMS(0x0F0F0F0F0F0F0F0F, 4); - RMS(0x00FF00FF00FF00FF, 8); - RMS(0x0000FFFF0000FFFF, 16); - return (x << 32) | (x >> 32); - -#undef RMS -} - -/* see bearssl_ghash.h */ -void -br_ghash_ctmul64(void *y, const void *h, const void *data, size_t len) -{ - const unsigned char *buf, *hb; - unsigned char *yb; - uint64_t y0, y1; - uint64_t h0, h1, h2, h0r, h1r, h2r; - - buf = data; - yb = y; - hb = h; - y1 = br_dec64be(yb); - y0 = br_dec64be(yb + 8); - h1 = br_dec64be(hb); - h0 = br_dec64be(hb + 8); - h0r = rev64(h0); - h1r = rev64(h1); - h2 = h0 ^ h1; - h2r = h0r ^ h1r; - while (len > 0) { - const unsigned char *src; - unsigned char tmp[16]; - uint64_t y0r, y1r, y2, y2r; - uint64_t z0, z1, z2, z0h, z1h, z2h; - uint64_t v0, v1, v2, v3; - - if (len >= 16) { - src = buf; - buf += 16; - len -= 16; - } else { - memcpy(tmp, buf, len); - memset(tmp + len, 0, (sizeof tmp) - len); - src = tmp; - len = 0; - } - y1 ^= br_dec64be(src); - y0 ^= br_dec64be(src + 8); - - y0r = rev64(y0); - y1r = rev64(y1); - y2 = y0 ^ y1; - y2r = y0r ^ y1r; - - z0 = bmul64(y0, h0); - z1 = bmul64(y1, h1); - z2 = bmul64(y2, h2); - z0h = bmul64(y0r, h0r); - z1h = bmul64(y1r, h1r); - z2h = bmul64(y2r, h2r); - z2 ^= z0 ^ z1; - z2h ^= z0h ^ z1h; - z0h = rev64(z0h) >> 1; - z1h = rev64(z1h) >> 1; - z2h = rev64(z2h) >> 1; - - v0 = z0; - v1 = z0h ^ z2; - v2 = z1 ^ z2h; - v3 = z1h; - - v3 = (v3 << 1) | (v2 >> 63); - v2 = (v2 << 1) | (v1 >> 63); - v1 = (v1 << 1) | (v0 >> 63); - v0 = (v0 << 1); - - v2 ^= v0 ^ (v0 >> 1) ^ (v0 >> 2) ^ (v0 >> 7); - v1 ^= (v0 << 63) ^ (v0 << 62) ^ (v0 << 57); - v3 ^= v1 ^ (v1 >> 1) ^ (v1 >> 2) ^ (v1 >> 7); - v2 ^= (v1 << 63) ^ (v1 << 62) ^ (v1 << 57); - - y0 = v2; - y1 = v3; - } - - br_enc64be(yb, y1); - br_enc64be(yb + 8, y0); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ghash_pclmul.c b/src/tls/bearssl/ghash_pclmul.c deleted file mode 100644 index f8a7077f8..000000000 --- a/src/tls/bearssl/ghash_pclmul.c +++ /dev/null @@ -1,394 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#define BR_ENABLE_INTRINSICS 1 -#include "inner.h" - -/* - * This is the GHASH implementation that leverages the pclmulqdq opcode - * (from the AES-NI instructions). - */ - -#if BR_AES_X86NI - -/* - * Test CPU support for PCLMULQDQ. - */ -static inline int -pclmul_supported(void) -{ - /* - * Bit mask for features in ECX: - * 1 PCLMULQDQ support - */ - return br_cpuid(0, 0, 0x00000002, 0); -} - -/* see bearssl_hash.h */ -br_ghash -br_ghash_pclmul_get(void) -{ - return pclmul_supported() ? &br_ghash_pclmul : 0; -} - -BR_TARGETS_X86_UP - -/* - * GHASH is defined over elements of GF(2^128) with "full little-endian" - * representation: leftmost byte is least significant, and, within each - * byte, leftmost _bit_ is least significant. The natural ordering in - * x86 is "mixed little-endian": bytes are ordered from least to most - * significant, but bits within a byte are in most-to-least significant - * order. Going to full little-endian representation would require - * reversing bits within each byte, which is doable but expensive. - * - * Instead, we go to full big-endian representation, by swapping bytes - * around, which is done with a single _mm_shuffle_epi8() opcode (it - * comes with SSSE3; all CPU that offer pclmulqdq also have SSSE3). We - * can use a full big-endian representation because in a carryless - * multiplication, we have a nice bit reversal property: - * - * rev_128(x) * rev_128(y) = rev_255(x * y) - * - * So by using full big-endian, we still get the right result, except - * that it is right-shifted by 1 bit. The left-shift is relatively - * inexpensive, and it can be mutualised. - * - * - * Since SSE2 opcodes do not have facilities for shitfting full 128-bit - * values with bit precision, we have to break down values into 64-bit - * chunks. We number chunks from 0 to 3 in left to right order. - */ - -/* - * Byte-swap a complete 128-bit value. This normally uses - * _mm_shuffle_epi8(), which gets translated to pshufb (an SSSE3 opcode). - * However, this crashes old Clang versions, so, for Clang before 3.8, - * we use an alternate (and less efficient) version. - */ -#if BR_CLANG && !BR_CLANG_3_8 -#define BYTESWAP_DECL -#define BYTESWAP_PREP (void)0 -#define BYTESWAP(x) do { \ - __m128i byteswap1, byteswap2; \ - byteswap1 = (x); \ - byteswap2 = _mm_srli_epi16(byteswap1, 8); \ - byteswap1 = _mm_slli_epi16(byteswap1, 8); \ - byteswap1 = _mm_or_si128(byteswap1, byteswap2); \ - byteswap1 = _mm_shufflelo_epi16(byteswap1, 0x1B); \ - byteswap1 = _mm_shufflehi_epi16(byteswap1, 0x1B); \ - (x) = _mm_shuffle_epi32(byteswap1, 0x4E); \ - } while (0) -#else -#define BYTESWAP_DECL __m128i byteswap_index; -#define BYTESWAP_PREP do { \ - byteswap_index = _mm_set_epi8( \ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); \ - } while (0) -#define BYTESWAP(x) do { \ - (x) = _mm_shuffle_epi8((x), byteswap_index); \ - } while (0) -#endif - -/* - * Call pclmulqdq. Clang appears to have trouble with the intrinsic, so, - * for that compiler, we use inline assembly. Inline assembly is - * potentially a bit slower because the compiler does not understand - * what the opcode does, and thus cannot optimize instruction - * scheduling. - * - * We use a target of "sse2" only, so that Clang may still handle the - * '__m128i' type and allocate SSE2 registers. - */ -#if BR_CLANG -BR_TARGET("sse2") -static inline __m128i -pclmulqdq00(__m128i x, __m128i y) -{ - __asm__ ("pclmulqdq $0x00, %1, %0" : "+x" (x) : "x" (y)); - return x; -} -BR_TARGET("sse2") -static inline __m128i -pclmulqdq11(__m128i x, __m128i y) -{ - __asm__ ("pclmulqdq $0x11, %1, %0" : "+x" (x) : "x" (y)); - return x; -} -#else -#define pclmulqdq00(x, y) _mm_clmulepi64_si128(x, y, 0x00) -#define pclmulqdq11(x, y) _mm_clmulepi64_si128(x, y, 0x11) -#endif - -/* - * From a 128-bit value kw, compute kx as the XOR of the two 64-bit - * halves of kw (into the right half of kx; left half is unspecified). - */ -#define BK(kw, kx) do { \ - kx = _mm_xor_si128(kw, _mm_shuffle_epi32(kw, 0x0E)); \ - } while (0) - -/* - * Combine two 64-bit values (k0:k1) into a 128-bit (kw) value and - * the XOR of the two values (kx). - */ -#define PBK(k0, k1, kw, kx) do { \ - kw = _mm_unpacklo_epi64(k1, k0); \ - kx = _mm_xor_si128(k0, k1); \ - } while (0) - -/* - * Left-shift by 1 bit a 256-bit value (in four 64-bit words). - */ -#define SL_256(x0, x1, x2, x3) do { \ - x0 = _mm_or_si128( \ - _mm_slli_epi64(x0, 1), \ - _mm_srli_epi64(x1, 63)); \ - x1 = _mm_or_si128( \ - _mm_slli_epi64(x1, 1), \ - _mm_srli_epi64(x2, 63)); \ - x2 = _mm_or_si128( \ - _mm_slli_epi64(x2, 1), \ - _mm_srli_epi64(x3, 63)); \ - x3 = _mm_slli_epi64(x3, 1); \ - } while (0) - -/* - * Perform reduction in GF(2^128). The 256-bit value is in x0..x3; - * result is written in x0..x1. - */ -#define REDUCE_F128(x0, x1, x2, x3) do { \ - x1 = _mm_xor_si128( \ - x1, \ - _mm_xor_si128( \ - _mm_xor_si128( \ - x3, \ - _mm_srli_epi64(x3, 1)), \ - _mm_xor_si128( \ - _mm_srli_epi64(x3, 2), \ - _mm_srli_epi64(x3, 7)))); \ - x2 = _mm_xor_si128( \ - _mm_xor_si128( \ - x2, \ - _mm_slli_epi64(x3, 63)), \ - _mm_xor_si128( \ - _mm_slli_epi64(x3, 62), \ - _mm_slli_epi64(x3, 57))); \ - x0 = _mm_xor_si128( \ - x0, \ - _mm_xor_si128( \ - _mm_xor_si128( \ - x2, \ - _mm_srli_epi64(x2, 1)), \ - _mm_xor_si128( \ - _mm_srli_epi64(x2, 2), \ - _mm_srli_epi64(x2, 7)))); \ - x1 = _mm_xor_si128( \ - _mm_xor_si128( \ - x1, \ - _mm_slli_epi64(x2, 63)), \ - _mm_xor_si128( \ - _mm_slli_epi64(x2, 62), \ - _mm_slli_epi64(x2, 57))); \ - } while (0) - -/* - * Square value kw into (dw,dx). - */ -#define SQUARE_F128(kw, dw, dx) do { \ - __m128i z0, z1, z2, z3; \ - z1 = pclmulqdq11(kw, kw); \ - z3 = pclmulqdq00(kw, kw); \ - z0 = _mm_shuffle_epi32(z1, 0x0E); \ - z2 = _mm_shuffle_epi32(z3, 0x0E); \ - SL_256(z0, z1, z2, z3); \ - REDUCE_F128(z0, z1, z2, z3); \ - PBK(z0, z1, dw, dx); \ - } while (0) - -/* see bearssl_hash.h */ -BR_TARGET("ssse3,pclmul") -void -br_ghash_pclmul(void *y, const void *h, const void *data, size_t len) -{ - const unsigned char *buf1, *buf2; - unsigned char tmp[64]; - size_t num4, num1; - __m128i yw, h1w, h1x; - BYTESWAP_DECL - - /* - * We split data into two chunks. First chunk starts at buf1 - * and contains num4 blocks of 64-byte values. Second chunk - * starts at buf2 and contains num1 blocks of 16-byte values. - * We want the first chunk to be as large as possible. - */ - buf1 = data; - num4 = len >> 6; - len &= 63; - buf2 = buf1 + (num4 << 6); - num1 = (len + 15) >> 4; - if ((len & 15) != 0) { - memcpy(tmp, buf2, len); - memset(tmp + len, 0, (num1 << 4) - len); - buf2 = tmp; - } - - /* - * Preparatory step for endian conversions. - */ - BYTESWAP_PREP; - - /* - * Load y and h. - */ - yw = _mm_loadu_si128(y); - h1w = _mm_loadu_si128(h); - BYTESWAP(yw); - BYTESWAP(h1w); - BK(h1w, h1x); - - if (num4 > 0) { - __m128i h2w, h2x, h3w, h3x, h4w, h4x; - __m128i t0, t1, t2, t3; - - /* - * Compute h2 = h^2. - */ - SQUARE_F128(h1w, h2w, h2x); - - /* - * Compute h3 = h^3 = h*(h^2). - */ - t1 = pclmulqdq11(h1w, h2w); - t3 = pclmulqdq00(h1w, h2w); - t2 = _mm_xor_si128(pclmulqdq00(h1x, h2x), - _mm_xor_si128(t1, t3)); - t0 = _mm_shuffle_epi32(t1, 0x0E); - t1 = _mm_xor_si128(t1, _mm_shuffle_epi32(t2, 0x0E)); - t2 = _mm_xor_si128(t2, _mm_shuffle_epi32(t3, 0x0E)); - SL_256(t0, t1, t2, t3); - REDUCE_F128(t0, t1, t2, t3); - PBK(t0, t1, h3w, h3x); - - /* - * Compute h4 = h^4 = (h^2)^2. - */ - SQUARE_F128(h2w, h4w, h4x); - - while (num4 -- > 0) { - __m128i aw0, aw1, aw2, aw3; - __m128i ax0, ax1, ax2, ax3; - - aw0 = _mm_loadu_si128((void *)(buf1 + 0)); - aw1 = _mm_loadu_si128((void *)(buf1 + 16)); - aw2 = _mm_loadu_si128((void *)(buf1 + 32)); - aw3 = _mm_loadu_si128((void *)(buf1 + 48)); - BYTESWAP(aw0); - BYTESWAP(aw1); - BYTESWAP(aw2); - BYTESWAP(aw3); - buf1 += 64; - - aw0 = _mm_xor_si128(aw0, yw); - BK(aw1, ax1); - BK(aw2, ax2); - BK(aw3, ax3); - BK(aw0, ax0); - - t1 = _mm_xor_si128( - _mm_xor_si128( - pclmulqdq11(aw0, h4w), - pclmulqdq11(aw1, h3w)), - _mm_xor_si128( - pclmulqdq11(aw2, h2w), - pclmulqdq11(aw3, h1w))); - t3 = _mm_xor_si128( - _mm_xor_si128( - pclmulqdq00(aw0, h4w), - pclmulqdq00(aw1, h3w)), - _mm_xor_si128( - pclmulqdq00(aw2, h2w), - pclmulqdq00(aw3, h1w))); - t2 = _mm_xor_si128( - _mm_xor_si128( - pclmulqdq00(ax0, h4x), - pclmulqdq00(ax1, h3x)), - _mm_xor_si128( - pclmulqdq00(ax2, h2x), - pclmulqdq00(ax3, h1x))); - t2 = _mm_xor_si128(t2, _mm_xor_si128(t1, t3)); - t0 = _mm_shuffle_epi32(t1, 0x0E); - t1 = _mm_xor_si128(t1, _mm_shuffle_epi32(t2, 0x0E)); - t2 = _mm_xor_si128(t2, _mm_shuffle_epi32(t3, 0x0E)); - SL_256(t0, t1, t2, t3); - REDUCE_F128(t0, t1, t2, t3); - yw = _mm_unpacklo_epi64(t1, t0); - } - } - - while (num1 -- > 0) { - __m128i aw, ax; - __m128i t0, t1, t2, t3; - - aw = _mm_loadu_si128((void *)buf2); - BYTESWAP(aw); - buf2 += 16; - - aw = _mm_xor_si128(aw, yw); - BK(aw, ax); - - t1 = pclmulqdq11(aw, h1w); - t3 = pclmulqdq00(aw, h1w); - t2 = pclmulqdq00(ax, h1x); - t2 = _mm_xor_si128(t2, _mm_xor_si128(t1, t3)); - t0 = _mm_shuffle_epi32(t1, 0x0E); - t1 = _mm_xor_si128(t1, _mm_shuffle_epi32(t2, 0x0E)); - t2 = _mm_xor_si128(t2, _mm_shuffle_epi32(t3, 0x0E)); - SL_256(t0, t1, t2, t3); - REDUCE_F128(t0, t1, t2, t3); - yw = _mm_unpacklo_epi64(t1, t0); - } - - BYTESWAP(yw); - _mm_storeu_si128(y, yw); -} - -BR_TARGETS_X86_DOWN - -#else - -/* see bearssl_hash.h */ -br_ghash -br_ghash_pclmul_get(void) -{ - return 0; -} - -#endif - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ghash_pwr8.c b/src/tls/bearssl/ghash_pwr8.c deleted file mode 100644 index 9d07ded21..000000000 --- a/src/tls/bearssl/ghash_pwr8.c +++ /dev/null @@ -1,416 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#define BR_POWER_ASM_MACROS 1 -#include "inner.h" - -/* - * This is the GHASH implementation that leverages the POWER8 opcodes. - */ - -#if BR_POWER8 - -/* - * Some symbolic names for registers. - * HB0 = 16 bytes of value 0 - * HB1 = 16 bytes of value 1 - * HB2 = 16 bytes of value 2 - * HB6 = 16 bytes of value 6 - * HB7 = 16 bytes of value 7 - * TT0, TT1 and TT2 are temporaries - * - * BSW holds the pattern for byteswapping 32-bit words; this is set only - * on little-endian systems. XBSW is the same register with the +32 offset - * for access with the VSX opcodes. - */ -#define HB0 0 -#define HB1 1 -#define HB2 2 -#define HB6 3 -#define HB7 4 -#define TT0 5 -#define TT1 6 -#define TT2 7 - -#define BSW 8 -#define XBSW 40 - -/* - * Macro to initialise the constants. - */ -#define INIT \ - vxor(HB0, HB0, HB0) \ - vspltisb(HB1, 1) \ - vspltisb(HB2, 2) \ - vspltisb(HB6, 6) \ - vspltisb(HB7, 7) \ - INIT_BSW - -/* - * Fix endianness of a value after reading it or before writing it, if - * necessary. - */ -#if BR_POWER8_LE -#define INIT_BSW lxvw4x(XBSW, 0, %[idx2be]) -#define FIX_ENDIAN(xx) vperm(xx, xx, xx, BSW) -#else -#define INIT_BSW -#define FIX_ENDIAN(xx) -#endif - -/* - * Left-shift x0:x1 by one bit to the left. This is a corrective action - * needed because GHASH is defined in full little-endian specification, - * while the opcodes use full big-endian convention, so the 255-bit product - * ends up one bit to the right. - */ -#define SL_256(x0, x1) \ - vsldoi(TT0, HB0, x1, 1) \ - vsl(x0, x0, HB1) \ - vsr(TT0, TT0, HB7) \ - vsl(x1, x1, HB1) \ - vxor(x0, x0, TT0) - -/* - * Reduce x0:x1 in GF(2^128), result in xd (register xd may be the same as - * x0 or x1, or a different register). x0 and x1 are modified. - */ -#define REDUCE_F128(xd, x0, x1) \ - vxor(x0, x0, x1) \ - vsr(TT0, x1, HB1) \ - vsr(TT1, x1, HB2) \ - vsr(TT2, x1, HB7) \ - vxor(x0, x0, TT0) \ - vxor(TT1, TT1, TT2) \ - vxor(x0, x0, TT1) \ - vsldoi(x1, x1, HB0, 15) \ - vsl(TT1, x1, HB6) \ - vsl(TT2, x1, HB1) \ - vxor(x1, TT1, TT2) \ - vsr(TT0, x1, HB1) \ - vsr(TT1, x1, HB2) \ - vsr(TT2, x1, HB7) \ - vxor(x0, x0, x1) \ - vxor(x0, x0, TT0) \ - vxor(TT1, TT1, TT2) \ - vxor(xd, x0, TT1) - -/* see bearssl_hash.h */ -void -br_ghash_pwr8(void *y, const void *h, const void *data, size_t len) -{ - const unsigned char *buf1, *buf2; - size_t num4, num1; - unsigned char tmp[64]; - long cc0, cc1, cc2, cc3; - -#if BR_POWER8_LE - static const uint32_t idx2be[] = { - 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C - }; -#endif - - buf1 = data; - - /* - * Assembly code requires data into two chunks; first chunk - * must contain a number of blocks which is a multiple of 4. - * Since the processing for the first chunk is faster, we want - * to make it as big as possible. - * - * For the remainder, there are two possibilities: - * -- if the remainder size is a multiple of 16, then use it - * in place; - * -- otherwise, copy it to the tmp[] array and pad it with - * zeros. - */ - num4 = len >> 6; - buf2 = buf1 + (num4 << 6); - len &= 63; - num1 = (len + 15) >> 4; - if ((len & 15) != 0) { - memcpy(tmp, buf2, len); - memset(tmp + len, 0, (num1 << 4) - len); - buf2 = tmp; - } - - cc0 = 0; - cc1 = 16; - cc2 = 32; - cc3 = 48; - asm volatile ( - INIT - - /* - * Load current h (denoted hereafter h1) in v9. - */ - lxvw4x(41, 0, %[h]) - FIX_ENDIAN(9) - - /* - * Load current y into v28. - */ - lxvw4x(60, 0, %[y]) - FIX_ENDIAN(28) - - /* - * Split h1 into three registers: - * v17 = h1_1:h1_0 - * v18 = 0:h1_0 - * v19 = h1_1:0 - */ - xxpermdi(49, 41, 41, 2) - vsldoi(18, HB0, 9, 8) - vsldoi(19, 9, HB0, 8) - - /* - * If num4 is 0, skip directly to the second chunk. - */ - cmpldi(%[num4], 0) - beq(chunk1) - - /* - * Compute h2 = h*h in v10. - */ - vpmsumd(10, 18, 18) - vpmsumd(11, 19, 19) - SL_256(10, 11) - REDUCE_F128(10, 10, 11) - - /* - * Compute h3 = h*h*h in v11. - * We first split h2 into: - * v10 = h2_0:h2_1 - * v11 = 0:h2_0 - * v12 = h2_1:0 - * Then we do the product with h1, and reduce into v11. - */ - vsldoi(11, HB0, 10, 8) - vsldoi(12, 10, HB0, 8) - vpmsumd(13, 10, 17) - vpmsumd(11, 11, 18) - vpmsumd(12, 12, 19) - vsldoi(14, HB0, 13, 8) - vsldoi(15, 13, HB0, 8) - vxor(11, 11, 14) - vxor(12, 12, 15) - SL_256(11, 12) - REDUCE_F128(11, 11, 12) - - /* - * Compute h4 = h*h*h*h in v12. This is done by squaring h2. - */ - vsldoi(12, HB0, 10, 8) - vsldoi(13, 10, HB0, 8) - vpmsumd(12, 12, 12) - vpmsumd(13, 13, 13) - SL_256(12, 13) - REDUCE_F128(12, 12, 13) - - /* - * Repack h1, h2, h3 and h4: - * v13 = h4_0:h3_0 - * v14 = h4_1:h3_1 - * v15 = h2_0:h1_0 - * v16 = h2_1:h1_1 - */ - xxpermdi(45, 44, 43, 0) - xxpermdi(46, 44, 43, 3) - xxpermdi(47, 42, 41, 0) - xxpermdi(48, 42, 41, 3) - - /* - * Loop for each group of four blocks. - */ - mtctr(%[num4]) - label(loop4) - /* - * Read the four next blocks. - * v20 = y + a0 = b0 - * v21 = a1 = b1 - * v22 = a2 = b2 - * v23 = a3 = b3 - */ - lxvw4x(52, %[cc0], %[buf1]) - lxvw4x(53, %[cc1], %[buf1]) - lxvw4x(54, %[cc2], %[buf1]) - lxvw4x(55, %[cc3], %[buf1]) - FIX_ENDIAN(20) - FIX_ENDIAN(21) - FIX_ENDIAN(22) - FIX_ENDIAN(23) - addi(%[buf1], %[buf1], 64) - vxor(20, 20, 28) - - /* - * Repack the blocks into v9, v10, v11 and v12. - * v9 = b0_0:b1_0 - * v10 = b0_1:b1_1 - * v11 = b2_0:b3_0 - * v12 = b2_1:b3_1 - */ - xxpermdi(41, 52, 53, 0) - xxpermdi(42, 52, 53, 3) - xxpermdi(43, 54, 55, 0) - xxpermdi(44, 54, 55, 3) - - /* - * Compute the products. - * v20 = b0_0*h4_0 + b1_0*h3_0 - * v21 = b0_1*h4_0 + b1_1*h3_0 - * v22 = b0_0*h4_1 + b1_0*h3_1 - * v23 = b0_1*h4_1 + b1_1*h3_1 - * v24 = b2_0*h2_0 + b3_0*h1_0 - * v25 = b2_1*h2_0 + b3_1*h1_0 - * v26 = b2_0*h2_1 + b3_0*h1_1 - * v27 = b2_1*h2_1 + b3_1*h1_1 - */ - vpmsumd(20, 13, 9) - vpmsumd(21, 13, 10) - vpmsumd(22, 14, 9) - vpmsumd(23, 14, 10) - vpmsumd(24, 15, 11) - vpmsumd(25, 15, 12) - vpmsumd(26, 16, 11) - vpmsumd(27, 16, 12) - - /* - * Sum products into a single 256-bit result in v11:v12. - */ - vxor(11, 20, 24) - vxor(12, 23, 27) - vxor( 9, 21, 22) - vxor(10, 25, 26) - vxor(20, 9, 10) - vsldoi( 9, HB0, 20, 8) - vsldoi(10, 20, HB0, 8) - vxor(11, 11, 9) - vxor(12, 12, 10) - - /* - * Fix and reduce in GF(2^128); this is the new y (in v28). - */ - SL_256(11, 12) - REDUCE_F128(28, 11, 12) - - /* - * Loop for next group of four blocks. - */ - bdnz(loop4) - - /* - * Process second chunk, one block at a time. - */ - label(chunk1) - cmpldi(%[num1], 0) - beq(done) - - mtctr(%[num1]) - label(loop1) - /* - * Load next data block and XOR it into y. - */ - lxvw4x(41, 0, %[buf2]) -#if BR_POWER8_LE - FIX_ENDIAN(9) -#endif - addi(%[buf2], %[buf2], 16) - vxor(9, 28, 9) - - /* - * Split y into doublewords: - * v9 = y_0:y_1 - * v10 = 0:y_0 - * v11 = y_1:0 - */ - vsldoi(10, HB0, 9, 8) - vsldoi(11, 9, HB0, 8) - - /* - * Compute products with h: - * v12 = y_0 * h_0 - * v13 = y_1 * h_1 - * v14 = y_1 * h_0 + y_0 * h_1 - */ - vpmsumd(14, 9, 17) - vpmsumd(12, 10, 18) - vpmsumd(13, 11, 19) - - /* - * Propagate v14 into v12:v13 to finalise product. - */ - vsldoi(10, HB0, 14, 8) - vsldoi(11, 14, HB0, 8) - vxor(12, 12, 10) - vxor(13, 13, 11) - - /* - * Fix result and reduce into v28 (next value for y). - */ - SL_256(12, 13) - REDUCE_F128(28, 12, 13) - bdnz(loop1) - - label(done) - /* - * Write back the new y. - */ - FIX_ENDIAN(28) - stxvw4x(60, 0, %[y]) - -: [buf1] "+b" (buf1), [buf2] "+b" (buf2) -: [y] "b" (y), [h] "b" (h), [num4] "b" (num4), [num1] "b" (num1), - [cc0] "b" (cc0), [cc1] "b" (cc1), [cc2] "b" (cc2), [cc3] "b" (cc3) -#if BR_POWER8_LE - , [idx2be] "b" (idx2be) -#endif -: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", - "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", - "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", - "ctr", "memory" - ); -} - -/* see bearssl_hash.h */ -br_ghash -br_ghash_pwr8_get(void) -{ - return &br_ghash_pwr8; -} - -#else - -/* see bearssl_hash.h */ -br_ghash -br_ghash_pwr8_get(void) -{ - return 0; -} - -#endif - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/hkdf.c b/src/tls/bearssl/hkdf.c deleted file mode 100644 index d89d660a3..000000000 --- a/src/tls/bearssl/hkdf.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -const unsigned char br_hkdf_no_salt = 0; - -/* see bearssl_kdf.h */ -void -br_hkdf_init(br_hkdf_context *hc, const br_hash_class *digest_vtable, - const void *salt, size_t salt_len) -{ - br_hmac_key_context kc; - unsigned char tmp[64]; - - if (salt == BR_HKDF_NO_SALT) { - salt = tmp; - salt_len = br_digest_size(digest_vtable); - memset(tmp, 0, salt_len); - } - br_hmac_key_init(&kc, digest_vtable, salt, salt_len); - br_hmac_init(&hc->u.hmac_ctx, &kc, 0); - hc->dig_len = br_hmac_size(&hc->u.hmac_ctx); -} - -/* see bearssl_kdf.h */ -void -br_hkdf_inject(br_hkdf_context *hc, const void *ikm, size_t ikm_len) -{ - br_hmac_update(&hc->u.hmac_ctx, ikm, ikm_len); -} - -/* see bearssl_kdf.h */ -void -br_hkdf_flip(br_hkdf_context *hc) -{ - unsigned char tmp[64]; - - br_hmac_out(&hc->u.hmac_ctx, tmp); - br_hmac_key_init(&hc->u.prk_ctx, - br_hmac_get_digest(&hc->u.hmac_ctx), tmp, hc->dig_len); - hc->ptr = hc->dig_len; - hc->chunk_num = 0; -} - -/* see bearssl_kdf.h */ -size_t -br_hkdf_produce(br_hkdf_context *hc, - const void *info, size_t info_len, void *out, size_t out_len) -{ - size_t tlen; - - tlen = 0; - while (out_len > 0) { - size_t clen; - - if (hc->ptr == hc->dig_len) { - br_hmac_context hmac_ctx; - unsigned char x; - - hc->chunk_num ++; - if (hc->chunk_num == 256) { - return tlen; - } - x = hc->chunk_num; - br_hmac_init(&hmac_ctx, &hc->u.prk_ctx, 0); - if (x != 1) { - br_hmac_update(&hmac_ctx, hc->buf, hc->dig_len); - } - br_hmac_update(&hmac_ctx, info, info_len); - br_hmac_update(&hmac_ctx, &x, 1); - br_hmac_out(&hmac_ctx, hc->buf); - hc->ptr = 0; - } - clen = hc->dig_len - hc->ptr; - if (clen > out_len) { - clen = out_len; - } - memcpy(out, hc->buf + hc->ptr, clen); - out = (unsigned char *)out + clen; - out_len -= clen; - hc->ptr += clen; - tlen += clen; - } - return tlen; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/hmac.c b/src/tls/bearssl/hmac.c deleted file mode 100644 index 3e0cd7247..000000000 --- a/src/tls/bearssl/hmac.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -static inline size_t -block_size(const br_hash_class *dig) -{ - unsigned ls; - - ls = (unsigned)(dig->desc >> BR_HASHDESC_LBLEN_OFF) - & BR_HASHDESC_LBLEN_MASK; - return (size_t)1 << ls; -} - -static void -process_key(const br_hash_class **hc, void *ks, - const void *key, size_t key_len, unsigned bb) -{ - unsigned char tmp[256]; - size_t blen, u; - - blen = block_size(*hc); - memcpy(tmp, key, key_len); - for (u = 0; u < key_len; u ++) { - tmp[u] ^= (unsigned char)bb; - } - memset(tmp + key_len, bb, blen - key_len); - (*hc)->init(hc); - (*hc)->update(hc, tmp, blen); - (*hc)->state(hc, ks); -} - -/* see bearssl.h */ -void -br_hmac_key_init(br_hmac_key_context *kc, - const br_hash_class *dig, const void *key, size_t key_len) -{ - br_hash_compat_context hc; - unsigned char kbuf[64]; - - kc->dig_vtable = dig; - hc.vtable = dig; - if (key_len > block_size(dig)) { - dig->init(&hc.vtable); - dig->update(&hc.vtable, key, key_len); - dig->out(&hc.vtable, kbuf); - key = kbuf; - key_len = br_digest_size(dig); - } - process_key(&hc.vtable, kc->ksi, key, key_len, 0x36); - process_key(&hc.vtable, kc->kso, key, key_len, 0x5C); -} - -/* see bearssl.h */ -void -br_hmac_init(br_hmac_context *ctx, - const br_hmac_key_context *kc, size_t out_len) -{ - const br_hash_class *dig; - size_t blen, hlen; - - dig = kc->dig_vtable; - blen = block_size(dig); - dig->init(&ctx->dig.vtable); - dig->set_state(&ctx->dig.vtable, kc->ksi, (uint64_t)blen); - memcpy(ctx->kso, kc->kso, sizeof kc->kso); - hlen = br_digest_size(dig); - if (out_len > 0 && out_len < hlen) { - hlen = out_len; - } - ctx->out_len = hlen; -} - -/* see bearssl.h */ -void -br_hmac_update(br_hmac_context *ctx, const void *data, size_t len) -{ - ctx->dig.vtable->update(&ctx->dig.vtable, data, len); -} - -/* see bearssl.h */ -size_t -br_hmac_out(const br_hmac_context *ctx, void *out) -{ - const br_hash_class *dig; - br_hash_compat_context hc; - unsigned char tmp[64]; - size_t blen, hlen; - - dig = ctx->dig.vtable; - dig->out(&ctx->dig.vtable, tmp); - blen = block_size(dig); - dig->init(&hc.vtable); - dig->set_state(&hc.vtable, ctx->kso, (uint64_t)blen); - hlen = br_digest_size(dig); - dig->update(&hc.vtable, tmp, hlen); - dig->out(&hc.vtable, tmp); - memcpy(out, tmp, ctx->out_len); - return ctx->out_len; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/hmac_ct.c b/src/tls/bearssl/hmac_ct.c deleted file mode 100644 index 51560ab1d..000000000 --- a/src/tls/bearssl/hmac_ct.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -static inline size_t -hash_size(const br_hash_class *dig) -{ - return (unsigned)(dig->desc >> BR_HASHDESC_OUT_OFF) - & BR_HASHDESC_OUT_MASK; -} - -static inline size_t -block_size(const br_hash_class *dig) -{ - unsigned ls; - - ls = (unsigned)(dig->desc >> BR_HASHDESC_LBLEN_OFF) - & BR_HASHDESC_LBLEN_MASK; - return (size_t)1 << ls; -} - -/* see bearssl.h */ -size_t -br_hmac_outCT(const br_hmac_context *ctx, - const void *data, size_t len, size_t min_len, size_t max_len, - void *out) -{ - /* - * Method implemented here is inspired from the descriptions on: - * https://www.imperialviolet.org/2013/02/04/luckythirteen.html - * - * Principle: we input bytes one by one. We use a MUX to push - * padding bytes instead of data bytes when appropriate. At each - * block limit, we get the current hash function state: this is - * a potential output, since we handle MD padding ourselves. - * - * be 1 for big-endian, 0 for little-endian - * po minimal MD padding length - * bs block size (always a power of 2) - * hlen hash output size - */ - - const br_hash_class *dig; - br_hash_compat_context hc; - int be; - uint32_t po, bs; - uint32_t kr, km, kl, kz, u; - uint64_t count, ncount, bit_len; - unsigned char tmp1[64], tmp2[64]; - size_t hlen; - - /* - * Copy the current hash context. - */ - hc = ctx->dig; - - /* - * Get function-specific information. - */ - dig = hc.vtable; - be = (dig->desc & BR_HASHDESC_MD_PADDING_BE) != 0; - po = 9; - if (dig->desc & BR_HASHDESC_MD_PADDING_128) { - po += 8; - } - bs = block_size(dig); - hlen = hash_size(dig); - - /* - * Get current input length and compute total bit length. - */ - count = dig->state(&hc.vtable, tmp1); - bit_len = (count + (uint64_t)len) << 3; - - /* - * We can input the blocks that we are sure we will use. - * This offers better performance (no MUX for these blocks) - * and also ensures that the remaining lengths fit on 32 bits. - */ - ncount = (count + (uint64_t)min_len) & ~(uint64_t)(bs - 1); - if (ncount > count) { - size_t zlen; - - zlen = (size_t)(ncount - count); - dig->update(&hc.vtable, data, zlen); - data = (const unsigned char *)data + zlen; - len -= zlen; - max_len -= zlen; - count = ncount; - } - - /* - * At that point: - * -- 'count' contains the number of bytes already processed - * (in total). - * -- We must input 'len' bytes. 'min_len' is unimportant: we - * used it to know how many full blocks we could process - * directly. Now only len and max_len matter. - * - * We compute kr, kl, kz and km. - * kr number of input bytes already in the current block - * km index of the first byte after the end of the last padding - * block, if length is max_len - * kz index of the last byte of the actual last padding block - * kl index of the start of the encoded length - * - * km, kz and kl are counted from the current offset in the - * input data. - */ - kr = (uint32_t)count & (bs - 1); - kz = ((kr + (uint32_t)len + po + bs - 1) & ~(bs - 1)) - 1 - kr; - kl = kz - 7; - km = ((kr + (uint32_t)max_len + po + bs - 1) & ~(bs - 1)) - kr; - - /* - * We must now process km bytes. For index u from 0 to km-1: - * d is from data[] if u < max_len, 0x00 otherwise - * e is an encoded length byte or 0x00, depending on u - * The tests for d and e need not be constant-time, since - * they relate only to u and max_len, not to the actual length. - * - * Actual input length is then: - * d if u < len - * 0x80 if u == len - * 0x00 if u > len and u < kl - * e if u >= kl - * - * Hash state is obtained whenever we reach a full block. This - * is the result we want if and only if u == kz. - */ - memset(tmp2, 0, sizeof tmp2); - for (u = 0; u < km; u ++) { - uint32_t v; - uint32_t d, e, x0, x1; - unsigned char x[1]; - - d = (u < max_len) ? ((const unsigned char *)data)[u] : 0x00; - v = (kr + u) & (bs - 1); - if (v >= (bs - 8)) { - unsigned j; - - j = (v - (bs - 8)) << 3; - if (be) { - e = (uint32_t)(bit_len >> (56 - j)); - } else { - e = (uint32_t)(bit_len >> j); - } - e &= 0xFF; - } else { - e = 0x00; - } - x0 = MUX(EQ(u, (uint32_t)len), 0x80, d); - x1 = MUX(LT(u, kl), 0x00, e); - x[0] = MUX(LE(u, (uint32_t)len), x0, x1); - dig->update(&hc.vtable, x, 1); - if (v == (bs - 1)) { - dig->state(&hc.vtable, tmp1); - CCOPY(EQ(u, kz), tmp2, tmp1, hlen); - } - } - - /* - * Inner hash output is in tmp2[]; we finish processing. - */ - dig->init(&hc.vtable); - dig->set_state(&hc.vtable, ctx->kso, (uint64_t)bs); - dig->update(&hc.vtable, tmp2, hlen); - dig->out(&hc.vtable, tmp2); - memcpy(out, tmp2, ctx->out_len); - return ctx->out_len; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/hmac_drbg.c b/src/tls/bearssl/hmac_drbg.c deleted file mode 100644 index 787c96e71..000000000 --- a/src/tls/bearssl/hmac_drbg.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl.h */ -void -br_hmac_drbg_init(br_hmac_drbg_context *ctx, - const br_hash_class *digest_class, const void *seed, size_t len) -{ - size_t hlen; - - ctx->vtable = &br_hmac_drbg_vtable; - hlen = br_digest_size(digest_class); - memset(ctx->K, 0x00, hlen); - memset(ctx->V, 0x01, hlen); - ctx->digest_class = digest_class; - br_hmac_drbg_update(ctx, seed, len); -} - -/* see bearssl.h */ -void -br_hmac_drbg_generate(br_hmac_drbg_context *ctx, void *out, size_t len) -{ - const br_hash_class *dig; - br_hmac_key_context kc; - br_hmac_context hc; - size_t hlen; - unsigned char *buf; - unsigned char x; - - dig = ctx->digest_class; - hlen = br_digest_size(dig); - br_hmac_key_init(&kc, dig, ctx->K, hlen); - buf = out; - while (len > 0) { - size_t clen; - - br_hmac_init(&hc, &kc, 0); - br_hmac_update(&hc, ctx->V, hlen); - br_hmac_out(&hc, ctx->V); - clen = hlen; - if (clen > len) { - clen = len; - } - memcpy(buf, ctx->V, clen); - buf += clen; - len -= clen; - } - - /* - * To prepare the state for the next request, we should call - * br_hmac_drbg_update() with an empty additional seed. However, - * we already have an initialized HMAC context with the right - * initial key, and we don't want to push another one on the - * stack, so we inline that update() call here. - */ - br_hmac_init(&hc, &kc, 0); - br_hmac_update(&hc, ctx->V, hlen); - x = 0x00; - br_hmac_update(&hc, &x, 1); - br_hmac_out(&hc, ctx->K); - br_hmac_key_init(&kc, dig, ctx->K, hlen); - br_hmac_init(&hc, &kc, 0); - br_hmac_update(&hc, ctx->V, hlen); - br_hmac_out(&hc, ctx->V); -} - -/* see bearssl.h */ -void -br_hmac_drbg_update(br_hmac_drbg_context *ctx, const void *seed, size_t len) -{ - const br_hash_class *dig; - br_hmac_key_context kc; - br_hmac_context hc; - size_t hlen; - unsigned char x; - - dig = ctx->digest_class; - hlen = br_digest_size(dig); - - /* - * 1. K = HMAC(K, V || 0x00 || seed) - */ - br_hmac_key_init(&kc, dig, ctx->K, hlen); - br_hmac_init(&hc, &kc, 0); - br_hmac_update(&hc, ctx->V, hlen); - x = 0x00; - br_hmac_update(&hc, &x, 1); - br_hmac_update(&hc, seed, len); - br_hmac_out(&hc, ctx->K); - br_hmac_key_init(&kc, dig, ctx->K, hlen); - - /* - * 2. V = HMAC(K, V) - */ - br_hmac_init(&hc, &kc, 0); - br_hmac_update(&hc, ctx->V, hlen); - br_hmac_out(&hc, ctx->V); - - /* - * 3. If the additional seed is empty, then stop here. - */ - if (len == 0) { - return; - } - - /* - * 4. K = HMAC(K, V || 0x01 || seed) - */ - br_hmac_init(&hc, &kc, 0); - br_hmac_update(&hc, ctx->V, hlen); - x = 0x01; - br_hmac_update(&hc, &x, 1); - br_hmac_update(&hc, seed, len); - br_hmac_out(&hc, ctx->K); - br_hmac_key_init(&kc, dig, ctx->K, hlen); - - /* - * 5. V = HMAC(K, V) - */ - br_hmac_init(&hc, &kc, 0); - br_hmac_update(&hc, ctx->V, hlen); - br_hmac_out(&hc, ctx->V); -} - -/* see bearssl.h */ -const br_prng_class br_hmac_drbg_vtable = { - sizeof(br_hmac_drbg_context), - (void (*)(const br_prng_class **, const void *, const void *, size_t)) - &br_hmac_drbg_init, - (void (*)(const br_prng_class **, void *, size_t)) - &br_hmac_drbg_generate, - (void (*)(const br_prng_class **, const void *, size_t)) - &br_hmac_drbg_update -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i15_add.c b/src/tls/bearssl/i15_add.c deleted file mode 100644 index 720cb7348..000000000 --- a/src/tls/bearssl/i15_add.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -uint32_t -br_i15_add(uint16_t *a, const uint16_t *b, uint32_t ctl) -{ - uint32_t cc; - size_t u, m; - - cc = 0; - m = (a[0] + 31) >> 4; - for (u = 1; u < m; u ++) { - uint32_t aw, bw, naw; - - aw = a[u]; - bw = b[u]; - naw = aw + bw + cc; - cc = naw >> 15; - a[u] = MUX(ctl, naw & 0x7FFF, aw); - } - return cc; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i15_bitlen.c b/src/tls/bearssl/i15_bitlen.c deleted file mode 100644 index 7acaafbb5..000000000 --- a/src/tls/bearssl/i15_bitlen.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -uint32_t -br_i15_bit_length(uint16_t *x, size_t xlen) -{ - uint32_t tw, twk; - - tw = 0; - twk = 0; - while (xlen -- > 0) { - uint32_t w, c; - - c = EQ(tw, 0); - w = x[xlen]; - tw = MUX(c, w, tw); - twk = MUX(c, (uint32_t)xlen, twk); - } - return (twk << 4) + BIT_LENGTH(tw); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i15_decmod.c b/src/tls/bearssl/i15_decmod.c deleted file mode 100644 index bed19c8a9..000000000 --- a/src/tls/bearssl/i15_decmod.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -uint32_t -br_i15_decode_mod(uint16_t *x, const void *src, size_t len, const uint16_t *m) -{ - /* - * Two-pass algorithm: in the first pass, we determine whether the - * value fits; in the second pass, we do the actual write. - * - * During the first pass, 'r' contains the comparison result so - * far: - * 0x00000000 value is equal to the modulus - * 0x00000001 value is greater than the modulus - * 0xFFFFFFFF value is lower than the modulus - * - * Since we iterate starting with the least significant bytes (at - * the end of src[]), each new comparison overrides the previous - * except when the comparison yields 0 (equal). - * - * During the second pass, 'r' is either 0xFFFFFFFF (value fits) - * or 0x00000000 (value does not fit). - * - * We must iterate over all bytes of the source, _and_ possibly - * some extra virtual bytes (with value 0) so as to cover the - * complete modulus as well. We also add 4 such extra bytes beyond - * the modulus length because it then guarantees that no accumulated - * partial word remains to be processed. - */ - const unsigned char *buf; - size_t mlen, tlen; - int pass; - uint32_t r; - - buf = src; - mlen = (m[0] + 15) >> 4; - tlen = (mlen << 1); - if (tlen < len) { - tlen = len; - } - tlen += 4; - r = 0; - for (pass = 0; pass < 2; pass ++) { - size_t u, v; - uint32_t acc; - int acc_len; - - v = 1; - acc = 0; - acc_len = 0; - for (u = 0; u < tlen; u ++) { - uint32_t b; - - if (u < len) { - b = buf[len - 1 - u]; - } else { - b = 0; - } - acc |= (b << acc_len); - acc_len += 8; - if (acc_len >= 15) { - uint32_t xw; - - xw = acc & (uint32_t)0x7FFF; - acc_len -= 15; - acc = b >> (8 - acc_len); - if (v <= mlen) { - if (pass) { - x[v] = r & xw; - } else { - uint32_t cc; - - cc = (uint32_t)CMP(xw, m[v]); - r = MUX(EQ(cc, 0), r, cc); - } - } else { - if (!pass) { - r = MUX(EQ(xw, 0), r, 1); - } - } - v ++; - } - } - - /* - * When we reach this point at the end of the first pass: - * r is either 0, 1 or -1; we want to set r to 0 if it - * is equal to 0 or 1, and leave it to -1 otherwise. - * - * When we reach this point at the end of the second pass: - * r is either 0 or -1; we want to leave that value - * untouched. This is a subcase of the previous. - */ - r >>= 1; - r |= (r << 1); - } - - x[0] = m[0]; - return r & (uint32_t)1; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i15_decode.c b/src/tls/bearssl/i15_decode.c deleted file mode 100644 index 1d0239838..000000000 --- a/src/tls/bearssl/i15_decode.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_i15_decode(uint16_t *x, const void *src, size_t len) -{ - const unsigned char *buf; - size_t v; - uint32_t acc; - int acc_len; - - buf = src; - v = 1; - acc = 0; - acc_len = 0; - while (len -- > 0) { - uint32_t b; - - b = buf[len]; - acc |= (b << acc_len); - acc_len += 8; - if (acc_len >= 15) { - x[v ++] = acc & 0x7FFF; - acc_len -= 15; - acc >>= 15; - } - } - if (acc_len != 0) { - x[v ++] = acc; - } - x[0] = br_i15_bit_length(x + 1, v - 1); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i15_decred.c b/src/tls/bearssl/i15_decred.c deleted file mode 100644 index 266c93d8e..000000000 --- a/src/tls/bearssl/i15_decred.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_i15_decode_reduce(uint16_t *x, - const void *src, size_t len, const uint16_t *m) -{ - uint32_t m_ebitlen, m_rbitlen; - size_t mblen, k; - const unsigned char *buf; - uint32_t acc; - int acc_len; - - /* - * Get the encoded bit length. - */ - m_ebitlen = m[0]; - - /* - * Special case for an invalid (null) modulus. - */ - if (m_ebitlen == 0) { - x[0] = 0; - return; - } - - /* - * Clear the destination. - */ - br_i15_zero(x, m_ebitlen); - - /* - * First decode directly as many bytes as possible. This requires - * computing the actual bit length. - */ - m_rbitlen = m_ebitlen >> 4; - m_rbitlen = (m_ebitlen & 15) + (m_rbitlen << 4) - m_rbitlen; - mblen = (m_rbitlen + 7) >> 3; - k = mblen - 1; - if (k >= len) { - br_i15_decode(x, src, len); - x[0] = m_ebitlen; - return; - } - buf = src; - br_i15_decode(x, buf, k); - x[0] = m_ebitlen; - - /* - * Input remaining bytes, using 15-bit words. - */ - acc = 0; - acc_len = 0; - while (k < len) { - uint32_t v; - - v = buf[k ++]; - acc = (acc << 8) | v; - acc_len += 8; - if (acc_len >= 15) { - br_i15_muladd_small(x, acc >> (acc_len - 15), m); - acc_len -= 15; - acc &= ~((uint32_t)-1 << acc_len); - } - } - - /* - * We may have some bits accumulated. We then perform a shift to - * be able to inject these bits as a full 15-bit word. - */ - if (acc_len != 0) { - acc = (acc | (x[1] << acc_len)) & 0x7FFF; - br_i15_rshift(x, 15 - acc_len); - br_i15_muladd_small(x, acc, m); - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i15_encode.c b/src/tls/bearssl/i15_encode.c deleted file mode 100644 index 262492737..000000000 --- a/src/tls/bearssl/i15_encode.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_i15_encode(void *dst, size_t len, const uint16_t *x) -{ - unsigned char *buf; - size_t u, xlen; - uint32_t acc; - int acc_len; - - xlen = (x[0] + 15) >> 4; - if (xlen == 0) { - memset(dst, 0, len); - return; - } - u = 1; - acc = 0; - acc_len = 0; - buf = dst; - while (len -- > 0) { - if (acc_len < 8) { - if (u <= xlen) { - acc += (uint32_t)x[u ++] << acc_len; - } - acc_len += 15; - } - buf[len] = (unsigned char)acc; - acc >>= 8; - acc_len -= 8; - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i15_fmont.c b/src/tls/bearssl/i15_fmont.c deleted file mode 100644 index 7de8132a0..000000000 --- a/src/tls/bearssl/i15_fmont.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_i15_from_monty(uint16_t *x, const uint16_t *m, uint16_t m0i) -{ - size_t len, u, v; - - len = (m[0] + 15) >> 4; - for (u = 0; u < len; u ++) { - uint32_t f, cc; - - f = MUL15(x[1], m0i) & 0x7FFF; - cc = 0; - for (v = 0; v < len; v ++) { - uint32_t z; - - z = (uint32_t)x[v + 1] + MUL15(f, m[v + 1]) + cc; - cc = z >> 15; - if (v != 0) { - x[v] = z & 0x7FFF; - } - } - x[len] = cc; - } - - /* - * We may have to do an extra subtraction, but only if the - * value in x[] is indeed greater than or equal to that of m[], - * which is why we must do two calls (first call computes the - * carry, second call performs the subtraction only if the carry - * is 0). - */ - br_i15_sub(x, m, NOT(br_i15_sub(x, m, 0))); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i15_iszero.c b/src/tls/bearssl/i15_iszero.c deleted file mode 100644 index f6cd1b60c..000000000 --- a/src/tls/bearssl/i15_iszero.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -uint32_t -br_i15_iszero(const uint16_t *x) -{ - uint32_t z; - size_t u; - - z = 0; - for (u = (x[0] + 15) >> 4; u > 0; u --) { - z |= x[u]; - } - return ~(z | -z) >> 31; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i15_moddiv.c b/src/tls/bearssl/i15_moddiv.c deleted file mode 100644 index 18fdcbd5e..000000000 --- a/src/tls/bearssl/i15_moddiv.c +++ /dev/null @@ -1,470 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * In this file, we handle big integers with a custom format, i.e. - * without the usual one-word header. Value is split into 15-bit words, - * each stored in a 16-bit slot (top bit is zero) in little-endian - * order. The length (in words) is provided explicitly. In some cases, - * the value can be negative (using two's complement representation). In - * some cases, the top word is allowed to have a 16th bit. - */ - -/* - * Negate big integer conditionally. The value consists of 'len' words, - * with 15 bits in each word (the top bit of each word should be 0, - * except possibly for the last word). If 'ctl' is 1, the negation is - * computed; otherwise, if 'ctl' is 0, then the value is unchanged. - */ -static void -cond_negate(uint16_t *a, size_t len, uint32_t ctl) -{ - size_t k; - uint32_t cc, xm; - - cc = ctl; - xm = 0x7FFF & -ctl; - for (k = 0; k < len; k ++) { - uint32_t aw; - - aw = a[k]; - aw = (aw ^ xm) + cc; - a[k] = aw & 0x7FFF; - cc = (aw >> 15) & 1; - } -} - -/* - * Finish modular reduction. Rules on input parameters: - * - * if neg = 1, then -m <= a < 0 - * if neg = 0, then 0 <= a < 2*m - * - * If neg = 0, then the top word of a[] may use 16 bits. - * - * Also, modulus m must be odd. - */ -static void -finish_mod(uint16_t *a, size_t len, const uint16_t *m, uint32_t neg) -{ - size_t k; - uint32_t cc, xm, ym; - - /* - * First pass: compare a (assumed nonnegative) with m. - */ - cc = 0; - for (k = 0; k < len; k ++) { - uint32_t aw, mw; - - aw = a[k]; - mw = m[k]; - cc = (aw - mw - cc) >> 31; - } - - /* - * At this point: - * if neg = 1, then we must add m (regardless of cc) - * if neg = 0 and cc = 0, then we must subtract m - * if neg = 0 and cc = 1, then we must do nothing - */ - xm = 0x7FFF & -neg; - ym = -(neg | (1 - cc)); - cc = neg; - for (k = 0; k < len; k ++) { - uint32_t aw, mw; - - aw = a[k]; - mw = (m[k] ^ xm) & ym; - aw = aw - mw - cc; - a[k] = aw & 0x7FFF; - cc = aw >> 31; - } -} - -/* - * Compute: - * a <- (a*pa+b*pb)/(2^15) - * b <- (a*qa+b*qb)/(2^15) - * The division is assumed to be exact (i.e. the low word is dropped). - * If the final a is negative, then it is negated. Similarly for b. - * Returned value is the combination of two bits: - * bit 0: 1 if a had to be negated, 0 otherwise - * bit 1: 1 if b had to be negated, 0 otherwise - * - * Factors pa, pb, qa and qb must be at most 2^15 in absolute value. - * Source integers a and b must be nonnegative; top word is not allowed - * to contain an extra 16th bit. - */ -static uint32_t -co_reduce(uint16_t *a, uint16_t *b, size_t len, - int32_t pa, int32_t pb, int32_t qa, int32_t qb) -{ - size_t k; - int32_t cca, ccb; - uint32_t nega, negb; - - cca = 0; - ccb = 0; - for (k = 0; k < len; k ++) { - uint32_t wa, wb, za, zb; - uint16_t tta, ttb; - - /* - * Since: - * |pa| <= 2^15 - * |pb| <= 2^15 - * 0 <= wa <= 2^15 - 1 - * 0 <= wb <= 2^15 - 1 - * |cca| <= 2^16 - 1 - * Then: - * |za| <= (2^15-1)*(2^16) + (2^16-1) = 2^31 - 1 - * - * Thus, the new value of cca is such that |cca| <= 2^16 - 1. - * The same applies to ccb. - */ - wa = a[k]; - wb = b[k]; - za = wa * (uint32_t)pa + wb * (uint32_t)pb + (uint32_t)cca; - zb = wa * (uint32_t)qa + wb * (uint32_t)qb + (uint32_t)ccb; - if (k > 0) { - a[k - 1] = za & 0x7FFF; - b[k - 1] = zb & 0x7FFF; - } - tta = za >> 15; - ttb = zb >> 15; - cca = *(int16_t *)&tta; - ccb = *(int16_t *)&ttb; - } - a[len - 1] = (uint16_t)cca; - b[len - 1] = (uint16_t)ccb; - nega = (uint32_t)cca >> 31; - negb = (uint32_t)ccb >> 31; - cond_negate(a, len, nega); - cond_negate(b, len, negb); - return nega | (negb << 1); -} - -/* - * Compute: - * a <- (a*pa+b*pb)/(2^15) mod m - * b <- (a*qa+b*qb)/(2^15) mod m - * - * m0i is equal to -1/m[0] mod 2^15. - * - * Factors pa, pb, qa and qb must be at most 2^15 in absolute value. - * Source integers a and b must be nonnegative; top word is not allowed - * to contain an extra 16th bit. - */ -static void -co_reduce_mod(uint16_t *a, uint16_t *b, size_t len, - int32_t pa, int32_t pb, int32_t qa, int32_t qb, - const uint16_t *m, uint16_t m0i) -{ - size_t k; - int32_t cca, ccb, fa, fb; - - cca = 0; - ccb = 0; - fa = ((a[0] * (uint32_t)pa + b[0] * (uint32_t)pb) * m0i) & 0x7FFF; - fb = ((a[0] * (uint32_t)qa + b[0] * (uint32_t)qb) * m0i) & 0x7FFF; - for (k = 0; k < len; k ++) { - uint32_t wa, wb, za, zb; - uint32_t tta, ttb; - - /* - * In this loop, carries 'cca' and 'ccb' always fit on - * 17 bits (in absolute value). - */ - wa = a[k]; - wb = b[k]; - za = wa * (uint32_t)pa + wb * (uint32_t)pb - + m[k] * (uint32_t)fa + (uint32_t)cca; - zb = wa * (uint32_t)qa + wb * (uint32_t)qb - + m[k] * (uint32_t)fb + (uint32_t)ccb; - if (k > 0) { - a[k - 1] = za & 0x7FFF; - b[k - 1] = zb & 0x7FFF; - } - - /* - * The XOR-and-sub construction below does an arithmetic - * right shift in a portable way (technically, right-shifting - * a negative signed value is implementation-defined in C). - */ -#define M ((uint32_t)1 << 16) - tta = za >> 15; - ttb = zb >> 15; - tta = (tta ^ M) - M; - ttb = (ttb ^ M) - M; - cca = *(int32_t *)&tta; - ccb = *(int32_t *)&ttb; -#undef M - } - a[len - 1] = (uint32_t)cca; - b[len - 1] = (uint32_t)ccb; - - /* - * At this point: - * -m <= a < 2*m - * -m <= b < 2*m - * (this is a case of Montgomery reduction) - * The top word of 'a' and 'b' may have a 16-th bit set. - * We may have to add or subtract the modulus. - */ - finish_mod(a, len, m, (uint32_t)cca >> 31); - finish_mod(b, len, m, (uint32_t)ccb >> 31); -} - -/* see inner.h */ -uint32_t -br_i15_moddiv(uint16_t *x, const uint16_t *y, const uint16_t *m, uint16_t m0i, - uint16_t *t) -{ - /* - * Algorithm is an extended binary GCD. We maintain four values - * a, b, u and v, with the following invariants: - * - * a * x = y * u mod m - * b * x = y * v mod m - * - * Starting values are: - * - * a = y - * b = m - * u = x - * v = 0 - * - * The formal definition of the algorithm is a sequence of steps: - * - * - If a is even, then a <- a/2 and u <- u/2 mod m. - * - Otherwise, if b is even, then b <- b/2 and v <- v/2 mod m. - * - Otherwise, if a > b, then a <- (a-b)/2 and u <- (u-v)/2 mod m. - * - Otherwise, b <- (b-a)/2 and v <- (v-u)/2 mod m. - * - * Algorithm stops when a = b. At that point, they both are equal - * to GCD(y,m); the modular division succeeds if that value is 1. - * The result of the modular division is then u (or v: both are - * equal at that point). - * - * Each step makes either a or b shrink by at least one bit; hence, - * if m has bit length k bits, then 2k-2 steps are sufficient. - * - * - * Though complexity is quadratic in the size of m, the bit-by-bit - * processing is not very efficient. We can speed up processing by - * remarking that the decisions are taken based only on observation - * of the top and low bits of a and b. - * - * In the loop below, at each iteration, we use the two top words - * of a and b, and the low words of a and b, to compute reduction - * parameters pa, pb, qa and qb such that the new values for a - * and b are: - * - * a' = (a*pa + b*pb) / (2^15) - * b' = (a*qa + b*qb) / (2^15) - * - * the division being exact. - * - * Since the choices are based on the top words, they may be slightly - * off, requiring an optional correction: if a' < 0, then we replace - * pa with -pa, and pb with -pb. The total length of a and b is - * thus reduced by at least 14 bits at each iteration. - * - * The stopping conditions are still the same, though: when a - * and b become equal, they must be both odd (since m is odd, - * the GCD cannot be even), therefore the next operation is a - * subtraction, and one of the values becomes 0. At that point, - * nothing else happens, i.e. one value is stuck at 0, and the - * other one is the GCD. - */ - size_t len, k; - uint16_t *a, *b, *u, *v; - uint32_t num, r; - - len = (m[0] + 15) >> 4; - a = t; - b = a + len; - u = x + 1; - v = b + len; - memcpy(a, y + 1, len * sizeof *y); - memcpy(b, m + 1, len * sizeof *m); - memset(v, 0, len * sizeof *v); - - /* - * Loop below ensures that a and b are reduced by some bits each, - * for a total of at least 14 bits. - */ - for (num = ((m[0] - (m[0] >> 4)) << 1) + 14; num >= 14; num -= 14) { - size_t j; - uint32_t c0, c1; - uint32_t a0, a1, b0, b1; - uint32_t a_hi, b_hi, a_lo, b_lo; - int32_t pa, pb, qa, qb; - int i; - - /* - * Extract top words of a and b. If j is the highest - * index >= 1 such that a[j] != 0 or b[j] != 0, then we want - * (a[j] << 15) + a[j - 1], and (b[j] << 15) + b[j - 1]. - * If a and b are down to one word each, then we use a[0] - * and b[0]. - */ - c0 = (uint32_t)-1; - c1 = (uint32_t)-1; - a0 = 0; - a1 = 0; - b0 = 0; - b1 = 0; - j = len; - while (j -- > 0) { - uint32_t aw, bw; - - aw = a[j]; - bw = b[j]; - a0 ^= (a0 ^ aw) & c0; - a1 ^= (a1 ^ aw) & c1; - b0 ^= (b0 ^ bw) & c0; - b1 ^= (b1 ^ bw) & c1; - c1 = c0; - c0 &= (((aw | bw) + 0xFFFF) >> 16) - (uint32_t)1; - } - - /* - * If c1 = 0, then we grabbed two words for a and b. - * If c1 != 0 but c0 = 0, then we grabbed one word. It - * is not possible that c1 != 0 and c0 != 0, because that - * would mean that both integers are zero. - */ - a1 |= a0 & c1; - a0 &= ~c1; - b1 |= b0 & c1; - b0 &= ~c1; - a_hi = (a0 << 15) + a1; - b_hi = (b0 << 15) + b1; - a_lo = a[0]; - b_lo = b[0]; - - /* - * Compute reduction factors: - * - * a' = a*pa + b*pb - * b' = a*qa + b*qb - * - * such that a' and b' are both multiple of 2^15, but are - * only marginally larger than a and b. - */ - pa = 1; - pb = 0; - qa = 0; - qb = 1; - for (i = 0; i < 15; i ++) { - /* - * At each iteration: - * - * a <- (a-b)/2 if: a is odd, b is odd, a_hi > b_hi - * b <- (b-a)/2 if: a is odd, b is odd, a_hi <= b_hi - * a <- a/2 if: a is even - * b <- b/2 if: a is odd, b is even - * - * We multiply a_lo and b_lo by 2 at each - * iteration, thus a division by 2 really is a - * non-multiplication by 2. - */ - uint32_t r, oa, ob, cAB, cBA, cA; - - /* - * cAB = 1 if b must be subtracted from a - * cBA = 1 if a must be subtracted from b - * cA = 1 if a is divided by 2, 0 otherwise - * - * Rules: - * - * cAB and cBA cannot be both 1. - * if a is not divided by 2, b is. - */ - r = GT(a_hi, b_hi); - oa = (a_lo >> i) & 1; - ob = (b_lo >> i) & 1; - cAB = oa & ob & r; - cBA = oa & ob & NOT(r); - cA = cAB | NOT(oa); - - /* - * Conditional subtractions. - */ - a_lo -= b_lo & -cAB; - a_hi -= b_hi & -cAB; - pa -= qa & -(int32_t)cAB; - pb -= qb & -(int32_t)cAB; - b_lo -= a_lo & -cBA; - b_hi -= a_hi & -cBA; - qa -= pa & -(int32_t)cBA; - qb -= pb & -(int32_t)cBA; - - /* - * Shifting. - */ - a_lo += a_lo & (cA - 1); - pa += pa & ((int32_t)cA - 1); - pb += pb & ((int32_t)cA - 1); - a_hi ^= (a_hi ^ (a_hi >> 1)) & -cA; - b_lo += b_lo & -cA; - qa += qa & -(int32_t)cA; - qb += qb & -(int32_t)cA; - b_hi ^= (b_hi ^ (b_hi >> 1)) & (cA - 1); - } - - /* - * Replace a and b with new values a' and b'. - */ - r = co_reduce(a, b, len, pa, pb, qa, qb); - pa -= pa * ((r & 1) << 1); - pb -= pb * ((r & 1) << 1); - qa -= qa * (r & 2); - qb -= qb * (r & 2); - co_reduce_mod(u, v, len, pa, pb, qa, qb, m + 1, m0i); - } - - /* - * Now one of the arrays should be 0, and the other contains - * the GCD. If a is 0, then u is 0 as well, and v contains - * the division result. - * Result is correct if and only if GCD is 1. - */ - r = (a[0] | b[0]) ^ 1; - u[0] |= v[0]; - for (k = 1; k < len; k ++) { - r |= a[k] | b[k]; - u[k] |= v[k]; - } - return EQ0(r); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i15_modpow.c b/src/tls/bearssl/i15_modpow.c deleted file mode 100644 index 14d694968..000000000 --- a/src/tls/bearssl/i15_modpow.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_i15_modpow(uint16_t *x, - const unsigned char *e, size_t elen, - const uint16_t *m, uint16_t m0i, uint16_t *t1, uint16_t *t2) -{ - size_t mlen; - unsigned k; - - mlen = ((m[0] + 31) >> 4) * sizeof m[0]; - memcpy(t1, x, mlen); - br_i15_to_monty(t1, m); - br_i15_zero(x, m[0]); - x[1] = 1; - for (k = 0; k < ((unsigned)elen << 3); k ++) { - uint32_t ctl; - - ctl = (e[elen - 1 - (k >> 3)] >> (k & 7)) & 1; - br_i15_montymul(t2, x, t1, m, m0i); - CCOPY(ctl, x, t2, mlen); - br_i15_montymul(t2, t1, t1, m, m0i); - memcpy(t1, t2, mlen); - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i15_modpow2.c b/src/tls/bearssl/i15_modpow2.c deleted file mode 100644 index d10817830..000000000 --- a/src/tls/bearssl/i15_modpow2.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -uint32_t -br_i15_modpow_opt(uint16_t *x, - const unsigned char *e, size_t elen, - const uint16_t *m, uint16_t m0i, uint16_t *tmp, size_t twlen) -{ - size_t mlen, mwlen; - uint16_t *t1, *t2, *base; - size_t u, v; - uint32_t acc; - int acc_len, win_len; - - /* - * Get modulus size. - */ - mwlen = (m[0] + 31) >> 4; - mlen = mwlen * sizeof m[0]; - mwlen += (mwlen & 1); - t1 = tmp; - t2 = tmp + mwlen; - - /* - * Compute possible window size, with a maximum of 5 bits. - * When the window has size 1 bit, we use a specific code - * that requires only two temporaries. Otherwise, for a - * window of k bits, we need 2^k+1 temporaries. - */ - if (twlen < (mwlen << 1)) { - return 0; - } - for (win_len = 5; win_len > 1; win_len --) { - if ((((uint32_t)1 << win_len) + 1) * mwlen <= twlen) { - break; - } - } - - /* - * Everything is done in Montgomery representation. - */ - br_i15_to_monty(x, m); - - /* - * Compute window contents. If the window has size one bit only, - * then t2 is set to x; otherwise, t2[0] is left untouched, and - * t2[k] is set to x^k (for k >= 1). - */ - if (win_len == 1) { - memcpy(t2, x, mlen); - } else { - memcpy(t2 + mwlen, x, mlen); - base = t2 + mwlen; - for (u = 2; u < ((unsigned)1 << win_len); u ++) { - br_i15_montymul(base + mwlen, base, x, m, m0i); - base += mwlen; - } - } - - /* - * We need to set x to 1, in Montgomery representation. This can - * be done efficiently by setting the high word to 1, then doing - * one word-sized shift. - */ - br_i15_zero(x, m[0]); - x[(m[0] + 15) >> 4] = 1; - br_i15_muladd_small(x, 0, m); - - /* - * We process bits from most to least significant. At each - * loop iteration, we have acc_len bits in acc. - */ - acc = 0; - acc_len = 0; - while (acc_len > 0 || elen > 0) { - int i, k; - uint32_t bits; - - /* - * Get the next bits. - */ - k = win_len; - if (acc_len < win_len) { - if (elen > 0) { - acc = (acc << 8) | *e ++; - elen --; - acc_len += 8; - } else { - k = acc_len; - } - } - bits = (acc >> (acc_len - k)) & (((uint32_t)1 << k) - 1); - acc_len -= k; - - /* - * We could get exactly k bits. Compute k squarings. - */ - for (i = 0; i < k; i ++) { - br_i15_montymul(t1, x, x, m, m0i); - memcpy(x, t1, mlen); - } - - /* - * Window lookup: we want to set t2 to the window - * lookup value, assuming the bits are non-zero. If - * the window length is 1 bit only, then t2 is - * already set; otherwise, we do a constant-time lookup. - */ - if (win_len > 1) { - br_i15_zero(t2, m[0]); - base = t2 + mwlen; - for (u = 1; u < ((uint32_t)1 << k); u ++) { - uint32_t mask; - - mask = -EQ(u, bits); - for (v = 1; v < mwlen; v ++) { - t2[v] |= mask & base[v]; - } - base += mwlen; - } - } - - /* - * Multiply with the looked-up value. We keep the - * product only if the exponent bits are not all-zero. - */ - br_i15_montymul(t1, x, t2, m, m0i); - CCOPY(NEQ(bits, 0), x, t1, mlen); - } - - /* - * Convert back from Montgomery representation, and exit. - */ - br_i15_from_monty(x, m, m0i); - return 1; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i15_montmul.c b/src/tls/bearssl/i15_montmul.c deleted file mode 100644 index e7313ae80..000000000 --- a/src/tls/bearssl/i15_montmul.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_i15_montymul(uint16_t *d, const uint16_t *x, const uint16_t *y, - const uint16_t *m, uint16_t m0i) -{ - size_t len, len4, u, v; - uint32_t dh; - - len = (m[0] + 15) >> 4; - len4 = len & ~(size_t)3; - br_i15_zero(d, m[0]); - dh = 0; - for (u = 0; u < len; u ++) { - uint32_t f, xu, r, zh; - - xu = x[u + 1]; - f = MUL15((d[1] + MUL15(x[u + 1], y[1])) & 0x7FFF, m0i) - & 0x7FFF; -#if BR_ARMEL_CORTEXM_GCC - if (len4 != 0) { - uint16_t *limit; - - limit = d + len4; - asm volatile ( -"\n\ - @ carry: r=r2 \n\ - @ multipliers: xu=r3 f=r4 \n\ - @ base registers: d+v=r5 y+v=r6 m+v=r7 \n\ - @ r8 contains 0x7FFF \n\ - @ r9 contains d+len4 \n\ - ldr r0, %[limit] \n\ - ldr r3, %[xu] \n\ - mov r9, r0 \n\ - ldr r4, %[f] \n\ - eor r2, r2 \n\ - ldr r5, %[d] \n\ - sub r1, r2, #1 \n\ - ldr r6, %[y] \n\ - lsr r1, r1, #17 \n\ - ldr r7, %[m] \n\ - mov r8, r1 \n\ -loop%=: \n\ - ldrh r0, [r6, #2] \n\ - ldrh r1, [r7, #2] \n\ - mul r0, r3 \n\ - mul r1, r4 \n\ - add r2, r0, r2 \n\ - ldrh r0, [r5, #2] \n\ - add r2, r1, r2 \n\ - mov r1, r8 \n\ - add r2, r0, r2 \n\ - and r1, r2 \n\ - lsr r2, r2, #15 \n\ - strh r1, [r5, #0] \n\ - \n\ - ldrh r0, [r6, #4] \n\ - ldrh r1, [r7, #4] \n\ - mul r0, r3 \n\ - mul r1, r4 \n\ - add r2, r0, r2 \n\ - ldrh r0, [r5, #4] \n\ - add r2, r1, r2 \n\ - mov r1, r8 \n\ - add r2, r0, r2 \n\ - and r1, r2 \n\ - lsr r2, r2, #15 \n\ - strh r1, [r5, #2] \n\ - \n\ - ldrh r0, [r6, #6] \n\ - ldrh r1, [r7, #6] \n\ - mul r0, r3 \n\ - mul r1, r4 \n\ - add r2, r0, r2 \n\ - ldrh r0, [r5, #6] \n\ - add r2, r1, r2 \n\ - mov r1, r8 \n\ - add r2, r0, r2 \n\ - and r1, r2 \n\ - lsr r2, r2, #15 \n\ - strh r1, [r5, #4] \n\ - \n\ - ldrh r0, [r6, #8] \n\ - ldrh r1, [r7, #8] \n\ - mul r0, r3 \n\ - mul r1, r4 \n\ - add r2, r0, r2 \n\ - ldrh r0, [r5, #8] \n\ - add r2, r1, r2 \n\ - mov r1, r8 \n\ - add r2, r0, r2 \n\ - and r1, r2 \n\ - lsr r2, r2, #15 \n\ - strh r1, [r5, #6] \n\ - \n\ - add r5, r5, #8 \n\ - add r6, r6, #8 \n\ - add r7, r7, #8 \n\ - cmp r5, r9 \n\ - bne loop%= \n\ - \n\ - str r2, %[carry] \n\ -" -: [carry] "=m" (r) -: [xu] "m" (xu), [f] "m" (f), [d] "m" (d), [y] "m" (y), - [m] "m" (m), [limit] "m" (limit) -: "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); - } else { - r = 0; - } - v = len4; -#else - r = 0; - for (v = 0; v < len4; v += 4) { - uint32_t z; - - z = d[v + 1] + MUL15(xu, y[v + 1]) - + MUL15(f, m[v + 1]) + r; - r = z >> 15; - d[v + 0] = z & 0x7FFF; - z = d[v + 2] + MUL15(xu, y[v + 2]) - + MUL15(f, m[v + 2]) + r; - r = z >> 15; - d[v + 1] = z & 0x7FFF; - z = d[v + 3] + MUL15(xu, y[v + 3]) - + MUL15(f, m[v + 3]) + r; - r = z >> 15; - d[v + 2] = z & 0x7FFF; - z = d[v + 4] + MUL15(xu, y[v + 4]) - + MUL15(f, m[v + 4]) + r; - r = z >> 15; - d[v + 3] = z & 0x7FFF; - } -#endif - for (; v < len; v ++) { - uint32_t z; - - z = d[v + 1] + MUL15(xu, y[v + 1]) - + MUL15(f, m[v + 1]) + r; - r = z >> 15; - d[v + 0] = z & 0x7FFF; - } - - zh = dh + r; - d[len] = zh & 0x7FFF; - dh = zh >> 15; - } - - /* - * Restore the bit length (it was overwritten in the loop above). - */ - d[0] = m[0]; - - /* - * d[] may be greater than m[], but it is still lower than twice - * the modulus. - */ - br_i15_sub(d, m, NEQ(dh, 0) | NOT(br_i15_sub(d, m, 0))); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i15_mulacc.c b/src/tls/bearssl/i15_mulacc.c deleted file mode 100644 index 9a48a180c..000000000 --- a/src/tls/bearssl/i15_mulacc.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_i15_mulacc(uint16_t *d, const uint16_t *a, const uint16_t *b) -{ - size_t alen, blen, u; - unsigned dl, dh; - - alen = (a[0] + 15) >> 4; - blen = (b[0] + 15) >> 4; - - /* - * Announced bit length of d[] will be the sum of the announced - * bit lengths of a[] and b[]; but the lengths are encoded. - */ - dl = (a[0] & 15) + (b[0] & 15); - dh = (a[0] >> 4) + (b[0] >> 4); - d[0] = (dh << 4) + dl + (~(uint32_t)(dl - 15) >> 31); - - for (u = 0; u < blen; u ++) { - uint32_t f; - size_t v; - uint32_t cc; - - f = b[1 + u]; - cc = 0; - for (v = 0; v < alen; v ++) { - uint32_t z; - - z = (uint32_t)d[1 + u + v] + MUL15(f, a[1 + v]) + cc; - cc = z >> 15; - d[1 + u + v] = z & 0x7FFF; - } - d[1 + u + alen] = cc; - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i15_muladd.c b/src/tls/bearssl/i15_muladd.c deleted file mode 100644 index 4c68cf73a..000000000 --- a/src/tls/bearssl/i15_muladd.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * Constant-time division. The divisor must not be larger than 16 bits, - * and the quotient must fit on 17 bits. - */ -static uint32_t -divrem16(uint32_t x, uint32_t d, uint32_t *r) -{ - int i; - uint32_t q; - - q = 0; - d <<= 16; - for (i = 16; i >= 0; i --) { - uint32_t ctl; - - ctl = LE(d, x); - q |= ctl << i; - x -= (-ctl) & d; - d >>= 1; - } - if (r != NULL) { - *r = x; - } - return q; -} - -/* see inner.h */ -void -br_i15_muladd_small(uint16_t *x, uint16_t z, const uint16_t *m) -{ - /* - * Constant-time: we accept to leak the exact bit length of the - * modulus m. - */ - unsigned m_bitlen, mblr; - size_t u, mlen; - uint32_t hi, a0, a, b, q; - uint32_t cc, tb, over, under; - - /* - * Simple case: the modulus fits on one word. - */ - m_bitlen = m[0]; - if (m_bitlen == 0) { - return; - } - if (m_bitlen <= 15) { - uint32_t rem; - - divrem16(((uint32_t)x[1] << 15) | z, m[1], &rem); - x[1] = rem; - return; - } - mlen = (m_bitlen + 15) >> 4; - mblr = m_bitlen & 15; - - /* - * Principle: we estimate the quotient (x*2^15+z)/m by - * doing a 30/15 division with the high words. - * - * Let: - * w = 2^15 - * a = (w*a0 + a1) * w^N + a2 - * b = b0 * w^N + b2 - * such that: - * 0 <= a0 < w - * 0 <= a1 < w - * 0 <= a2 < w^N - * w/2 <= b0 < w - * 0 <= b2 < w^N - * a < w*b - * I.e. the two top words of a are a0:a1, the top word of b is - * b0, we ensured that b0 is "full" (high bit set), and a is - * such that the quotient q = a/b fits on one word (0 <= q < w). - * - * If a = b*q + r (with 0 <= r < q), then we can estimate q by - * using a division on the top words: - * a0*w + a1 = b0*u + v (with 0 <= v < b0) - * Then the following holds: - * 0 <= u <= w - * u-2 <= q <= u - */ - hi = x[mlen]; - if (mblr == 0) { - a0 = x[mlen]; - memmove(x + 2, x + 1, (mlen - 1) * sizeof *x); - x[1] = z; - a = (a0 << 15) + x[mlen]; - b = m[mlen]; - } else { - a0 = (x[mlen] << (15 - mblr)) | (x[mlen - 1] >> mblr); - memmove(x + 2, x + 1, (mlen - 1) * sizeof *x); - x[1] = z; - a = (a0 << 15) | (((x[mlen] << (15 - mblr)) - | (x[mlen - 1] >> mblr)) & 0x7FFF); - b = (m[mlen] << (15 - mblr)) | (m[mlen - 1] >> mblr); - } - q = divrem16(a, b, NULL); - - /* - * We computed an estimate for q, but the real one may be q, - * q-1 or q-2; moreover, the division may have returned a value - * 8000 or even 8001 if the two high words were identical, and - * we want to avoid values beyond 7FFF. We thus adjust q so - * that the "true" multiplier will be q+1, q or q-1, and q is - * in the 0000..7FFF range. - */ - q = MUX(EQ(b, a0), 0x7FFF, q - 1 + ((q - 1) >> 31)); - - /* - * We subtract q*m from x (x has an extra high word of value 'hi'). - * Since q may be off by 1 (in either direction), we may have to - * add or subtract m afterwards. - * - * The 'tb' flag will be true (1) at the end of the loop if the - * result is greater than or equal to the modulus (not counting - * 'hi' or the carry). - */ - cc = 0; - tb = 1; - for (u = 1; u <= mlen; u ++) { - uint32_t mw, zl, xw, nxw; - - mw = m[u]; - zl = MUL15(mw, q) + cc; - cc = zl >> 15; - zl &= 0x7FFF; - xw = x[u]; - nxw = xw - zl; - cc += nxw >> 31; - nxw &= 0x7FFF; - x[u] = nxw; - tb = MUX(EQ(nxw, mw), tb, GT(nxw, mw)); - } - - /* - * If we underestimated q, then either cc < hi (one extra bit - * beyond the top array word), or cc == hi and tb is true (no - * extra bit, but the result is not lower than the modulus). - * - * If we overestimated q, then cc > hi. - */ - over = GT(cc, hi); - under = ~over & (tb | LT(cc, hi)); - br_i15_add(x, m, over); - br_i15_sub(x, m, under); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i15_ninv15.c b/src/tls/bearssl/i15_ninv15.c deleted file mode 100644 index 6c178ee79..000000000 --- a/src/tls/bearssl/i15_ninv15.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -uint16_t -br_i15_ninv15(uint16_t x) -{ - uint32_t y; - - y = 2 - x; - y = MUL15(y, 2 - MUL15(x, y)); - y = MUL15(y, 2 - MUL15(x, y)); - y = MUL15(y, 2 - MUL15(x, y)); - return MUX(x & 1, -y, 0) & 0x7FFF; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i15_reduce.c b/src/tls/bearssl/i15_reduce.c deleted file mode 100644 index 87c1cb7a2..000000000 --- a/src/tls/bearssl/i15_reduce.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_i15_reduce(uint16_t *x, const uint16_t *a, const uint16_t *m) -{ - uint32_t m_bitlen, a_bitlen; - size_t mlen, alen, u; - - m_bitlen = m[0]; - mlen = (m_bitlen + 15) >> 4; - - x[0] = m_bitlen; - if (m_bitlen == 0) { - return; - } - - /* - * If the source is shorter, then simply copy all words from a[] - * and zero out the upper words. - */ - a_bitlen = a[0]; - alen = (a_bitlen + 15) >> 4; - if (a_bitlen < m_bitlen) { - memcpy(x + 1, a + 1, alen * sizeof *a); - for (u = alen; u < mlen; u ++) { - x[u + 1] = 0; - } - return; - } - - /* - * The source length is at least equal to that of the modulus. - * We must thus copy N-1 words, and input the remaining words - * one by one. - */ - memcpy(x + 1, a + 2 + (alen - mlen), (mlen - 1) * sizeof *a); - x[mlen] = 0; - for (u = 1 + alen - mlen; u > 0; u --) { - br_i15_muladd_small(x, a[u], m); - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i15_rshift.c b/src/tls/bearssl/i15_rshift.c deleted file mode 100644 index 2240ce63c..000000000 --- a/src/tls/bearssl/i15_rshift.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_i15_rshift(uint16_t *x, int count) -{ - size_t u, len; - unsigned r; - - len = (x[0] + 15) >> 4; - if (len == 0) { - return; - } - r = x[1] >> count; - for (u = 2; u <= len; u ++) { - unsigned w; - - w = x[u]; - x[u - 1] = ((w << (15 - count)) | r) & 0x7FFF; - r = w >> count; - } - x[len] = r; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i15_sub.c b/src/tls/bearssl/i15_sub.c deleted file mode 100644 index 1270c3b02..000000000 --- a/src/tls/bearssl/i15_sub.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -uint32_t -br_i15_sub(uint16_t *a, const uint16_t *b, uint32_t ctl) -{ - uint32_t cc; - size_t u, m; - - cc = 0; - m = (a[0] + 31) >> 4; - for (u = 1; u < m; u ++) { - uint32_t aw, bw, naw; - - aw = a[u]; - bw = b[u]; - naw = aw - bw - cc; - cc = naw >> 31; - a[u] = MUX(ctl, naw & 0x7FFF, aw); - } - return cc; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i15_tmont.c b/src/tls/bearssl/i15_tmont.c deleted file mode 100644 index e182b9e21..000000000 --- a/src/tls/bearssl/i15_tmont.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_i15_to_monty(uint16_t *x, const uint16_t *m) -{ - unsigned k; - - for (k = (m[0] + 15) >> 4; k > 0; k --) { - br_i15_muladd_small(x, 0, m); - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i31_add.c b/src/tls/bearssl/i31_add.c deleted file mode 100644 index d66e948a7..000000000 --- a/src/tls/bearssl/i31_add.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -uint32_t -br_i31_add(uint32_t *a, const uint32_t *b, uint32_t ctl) -{ - uint32_t cc; - size_t u, m; - - cc = 0; - m = (a[0] + 63) >> 5; - for (u = 1; u < m; u ++) { - uint32_t aw, bw, naw; - - aw = a[u]; - bw = b[u]; - naw = aw + bw + cc; - cc = naw >> 31; - a[u] = MUX(ctl, naw & (uint32_t)0x7FFFFFFF, aw); - } - return cc; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i31_bitlen.c b/src/tls/bearssl/i31_bitlen.c deleted file mode 100644 index 2bfb0e3fc..000000000 --- a/src/tls/bearssl/i31_bitlen.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -uint32_t -br_i31_bit_length(uint32_t *x, size_t xlen) -{ - uint32_t tw, twk; - - tw = 0; - twk = 0; - while (xlen -- > 0) { - uint32_t w, c; - - c = EQ(tw, 0); - w = x[xlen]; - tw = MUX(c, w, tw); - twk = MUX(c, (uint32_t)xlen, twk); - } - return (twk << 5) + BIT_LENGTH(tw); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i31_decmod.c b/src/tls/bearssl/i31_decmod.c deleted file mode 100644 index 9b085e964..000000000 --- a/src/tls/bearssl/i31_decmod.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -uint32_t -br_i31_decode_mod(uint32_t *x, const void *src, size_t len, const uint32_t *m) -{ - /* - * Two-pass algorithm: in the first pass, we determine whether the - * value fits; in the second pass, we do the actual write. - * - * During the first pass, 'r' contains the comparison result so - * far: - * 0x00000000 value is equal to the modulus - * 0x00000001 value is greater than the modulus - * 0xFFFFFFFF value is lower than the modulus - * - * Since we iterate starting with the least significant bytes (at - * the end of src[]), each new comparison overrides the previous - * except when the comparison yields 0 (equal). - * - * During the second pass, 'r' is either 0xFFFFFFFF (value fits) - * or 0x00000000 (value does not fit). - * - * We must iterate over all bytes of the source, _and_ possibly - * some extra virtual bytes (with value 0) so as to cover the - * complete modulus as well. We also add 4 such extra bytes beyond - * the modulus length because it then guarantees that no accumulated - * partial word remains to be processed. - */ - const unsigned char *buf; - size_t mlen, tlen; - int pass; - uint32_t r; - - buf = src; - mlen = (m[0] + 31) >> 5; - tlen = (mlen << 2); - if (tlen < len) { - tlen = len; - } - tlen += 4; - r = 0; - for (pass = 0; pass < 2; pass ++) { - size_t u, v; - uint32_t acc; - int acc_len; - - v = 1; - acc = 0; - acc_len = 0; - for (u = 0; u < tlen; u ++) { - uint32_t b; - - if (u < len) { - b = buf[len - 1 - u]; - } else { - b = 0; - } - acc |= (b << acc_len); - acc_len += 8; - if (acc_len >= 31) { - uint32_t xw; - - xw = acc & (uint32_t)0x7FFFFFFF; - acc_len -= 31; - acc = b >> (8 - acc_len); - if (v <= mlen) { - if (pass) { - x[v] = r & xw; - } else { - uint32_t cc; - - cc = (uint32_t)CMP(xw, m[v]); - r = MUX(EQ(cc, 0), r, cc); - } - } else { - if (!pass) { - r = MUX(EQ(xw, 0), r, 1); - } - } - v ++; - } - } - - /* - * When we reach this point at the end of the first pass: - * r is either 0, 1 or -1; we want to set r to 0 if it - * is equal to 0 or 1, and leave it to -1 otherwise. - * - * When we reach this point at the end of the second pass: - * r is either 0 or -1; we want to leave that value - * untouched. This is a subcase of the previous. - */ - r >>= 1; - r |= (r << 1); - } - - x[0] = m[0]; - return r & (uint32_t)1; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i31_decode.c b/src/tls/bearssl/i31_decode.c deleted file mode 100644 index ef142ba20..000000000 --- a/src/tls/bearssl/i31_decode.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_i31_decode(uint32_t *x, const void *src, size_t len) -{ - const unsigned char *buf; - size_t u, v; - uint32_t acc; - int acc_len; - - buf = src; - u = len; - v = 1; - acc = 0; - acc_len = 0; - while (u -- > 0) { - uint32_t b; - - b = buf[u]; - acc |= (b << acc_len); - acc_len += 8; - if (acc_len >= 31) { - x[v ++] = acc & (uint32_t)0x7FFFFFFF; - acc_len -= 31; - acc = b >> (8 - acc_len); - } - } - if (acc_len != 0) { - x[v ++] = acc; - } - x[0] = br_i31_bit_length(x + 1, v - 1); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i31_decred.c b/src/tls/bearssl/i31_decred.c deleted file mode 100644 index 429b7f1d0..000000000 --- a/src/tls/bearssl/i31_decred.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_i31_decode_reduce(uint32_t *x, - const void *src, size_t len, const uint32_t *m) -{ - uint32_t m_ebitlen, m_rbitlen; - size_t mblen, k; - const unsigned char *buf; - uint32_t acc; - int acc_len; - - /* - * Get the encoded bit length. - */ - m_ebitlen = m[0]; - - /* - * Special case for an invalid (null) modulus. - */ - if (m_ebitlen == 0) { - x[0] = 0; - return; - } - - /* - * Clear the destination. - */ - br_i31_zero(x, m_ebitlen); - - /* - * First decode directly as many bytes as possible. This requires - * computing the actual bit length. - */ - m_rbitlen = m_ebitlen >> 5; - m_rbitlen = (m_ebitlen & 31) + (m_rbitlen << 5) - m_rbitlen; - mblen = (m_rbitlen + 7) >> 3; - k = mblen - 1; - if (k >= len) { - br_i31_decode(x, src, len); - x[0] = m_ebitlen; - return; - } - buf = src; - br_i31_decode(x, buf, k); - x[0] = m_ebitlen; - - /* - * Input remaining bytes, using 31-bit words. - */ - acc = 0; - acc_len = 0; - while (k < len) { - uint32_t v; - - v = buf[k ++]; - if (acc_len >= 23) { - acc_len -= 23; - acc <<= (8 - acc_len); - acc |= v >> acc_len; - br_i31_muladd_small(x, acc, m); - acc = v & (0xFF >> (8 - acc_len)); - } else { - acc = (acc << 8) | v; - acc_len += 8; - } - } - - /* - * We may have some bits accumulated. We then perform a shift to - * be able to inject these bits as a full 31-bit word. - */ - if (acc_len != 0) { - acc = (acc | (x[1] << acc_len)) & 0x7FFFFFFF; - br_i31_rshift(x, 31 - acc_len); - br_i31_muladd_small(x, acc, m); - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i31_encode.c b/src/tls/bearssl/i31_encode.c deleted file mode 100644 index 79966df8a..000000000 --- a/src/tls/bearssl/i31_encode.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_i31_encode(void *dst, size_t len, const uint32_t *x) -{ - unsigned char *buf; - size_t k, xlen; - uint32_t acc; - int acc_len; - - xlen = (x[0] + 31) >> 5; - if (xlen == 0) { - memset(dst, 0, len); - return; - } - buf = (unsigned char *)dst + len; - k = 1; - acc = 0; - acc_len = 0; - while (len != 0) { - uint32_t w; - - w = (k <= xlen) ? x[k] : 0; - k ++; - if (acc_len == 0) { - acc = w; - acc_len = 31; - } else { - uint32_t z; - - z = acc | (w << acc_len); - acc_len --; - acc = w >> (31 - acc_len); - if (len >= 4) { - buf -= 4; - len -= 4; - br_enc32be(buf, z); - } else { - switch (len) { - case 3: - buf[-3] = (unsigned char)(z >> 16); - /* fall through */ - case 2: - buf[-2] = (unsigned char)(z >> 8); - /* fall through */ - case 1: - buf[-1] = (unsigned char)z; - break; - } - return; - } - } - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i31_fmont.c b/src/tls/bearssl/i31_fmont.c deleted file mode 100644 index 63d2de431..000000000 --- a/src/tls/bearssl/i31_fmont.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_i31_from_monty(uint32_t *x, const uint32_t *m, uint32_t m0i) -{ - size_t len, u, v; - - len = (m[0] + 31) >> 5; - for (u = 0; u < len; u ++) { - uint32_t f; - uint64_t cc; - - f = MUL31_lo(x[1], m0i); - cc = 0; - for (v = 0; v < len; v ++) { - uint64_t z; - - z = (uint64_t)x[v + 1] + MUL31(f, m[v + 1]) + cc; - cc = z >> 31; - if (v != 0) { - x[v] = (uint32_t)z & 0x7FFFFFFF; - } - } - x[len] = (uint32_t)cc; - } - - /* - * We may have to do an extra subtraction, but only if the - * value in x[] is indeed greater than or equal to that of m[], - * which is why we must do two calls (first call computes the - * carry, second call performs the subtraction only if the carry - * is 0). - */ - br_i31_sub(x, m, NOT(br_i31_sub(x, m, 0))); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i31_iszero.c b/src/tls/bearssl/i31_iszero.c deleted file mode 100644 index 08eeacb1d..000000000 --- a/src/tls/bearssl/i31_iszero.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -uint32_t -br_i31_iszero(const uint32_t *x) -{ - uint32_t z; - size_t u; - - z = 0; - for (u = (x[0] + 31) >> 5; u > 0; u --) { - z |= x[u]; - } - return ~(z | -z) >> 31; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i31_moddiv.c b/src/tls/bearssl/i31_moddiv.c deleted file mode 100644 index 13474f569..000000000 --- a/src/tls/bearssl/i31_moddiv.c +++ /dev/null @@ -1,493 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * In this file, we handle big integers with a custom format, i.e. - * without the usual one-word header. Value is split into 31-bit words, - * each stored in a 32-bit slot (top bit is zero) in little-endian - * order. The length (in words) is provided explicitly. In some cases, - * the value can be negative (using two's complement representation). In - * some cases, the top word is allowed to have a 32th bit. - */ - -/* - * Negate big integer conditionally. The value consists of 'len' words, - * with 31 bits in each word (the top bit of each word should be 0, - * except possibly for the last word). If 'ctl' is 1, the negation is - * computed; otherwise, if 'ctl' is 0, then the value is unchanged. - */ -static void -cond_negate(uint32_t *a, size_t len, uint32_t ctl) -{ - size_t k; - uint32_t cc, xm; - - cc = ctl; - xm = -ctl >> 1; - for (k = 0; k < len; k ++) { - uint32_t aw; - - aw = a[k]; - aw = (aw ^ xm) + cc; - a[k] = aw & 0x7FFFFFFF; - cc = aw >> 31; - } -} - -/* - * Finish modular reduction. Rules on input parameters: - * - * if neg = 1, then -m <= a < 0 - * if neg = 0, then 0 <= a < 2*m - * - * If neg = 0, then the top word of a[] may use 32 bits. - * - * Also, modulus m must be odd. - */ -static void -finish_mod(uint32_t *a, size_t len, const uint32_t *m, uint32_t neg) -{ - size_t k; - uint32_t cc, xm, ym; - - /* - * First pass: compare a (assumed nonnegative) with m. - * Note that if the final word uses the top extra bit, then - * subtracting m must yield a value less than 2^31, since we - * assumed that a < 2*m. - */ - cc = 0; - for (k = 0; k < len; k ++) { - uint32_t aw, mw; - - aw = a[k]; - mw = m[k]; - cc = (aw - mw - cc) >> 31; - } - - /* - * At this point: - * if neg = 1, then we must add m (regardless of cc) - * if neg = 0 and cc = 0, then we must subtract m - * if neg = 0 and cc = 1, then we must do nothing - */ - xm = -neg >> 1; - ym = -(neg | (1 - cc)); - cc = neg; - for (k = 0; k < len; k ++) { - uint32_t aw, mw; - - aw = a[k]; - mw = (m[k] ^ xm) & ym; - aw = aw - mw - cc; - a[k] = aw & 0x7FFFFFFF; - cc = aw >> 31; - } -} - -/* - * Compute: - * a <- (a*pa+b*pb)/(2^31) - * b <- (a*qa+b*qb)/(2^31) - * The division is assumed to be exact (i.e. the low word is dropped). - * If the final a is negative, then it is negated. Similarly for b. - * Returned value is the combination of two bits: - * bit 0: 1 if a had to be negated, 0 otherwise - * bit 1: 1 if b had to be negated, 0 otherwise - * - * Factors pa, pb, qa and qb must be at most 2^31 in absolute value. - * Source integers a and b must be nonnegative; top word is not allowed - * to contain an extra 32th bit. - */ -static uint32_t -co_reduce(uint32_t *a, uint32_t *b, size_t len, - int64_t pa, int64_t pb, int64_t qa, int64_t qb) -{ - size_t k; - int64_t cca, ccb; - uint32_t nega, negb; - - cca = 0; - ccb = 0; - for (k = 0; k < len; k ++) { - uint32_t wa, wb; - uint64_t za, zb; - uint64_t tta, ttb; - - /* - * Since: - * |pa| <= 2^31 - * |pb| <= 2^31 - * 0 <= wa <= 2^31 - 1 - * 0 <= wb <= 2^31 - 1 - * |cca| <= 2^32 - 1 - * Then: - * |za| <= (2^31-1)*(2^32) + (2^32-1) = 2^63 - 1 - * - * Thus, the new value of cca is such that |cca| <= 2^32 - 1. - * The same applies to ccb. - */ - wa = a[k]; - wb = b[k]; - za = wa * (uint64_t)pa + wb * (uint64_t)pb + (uint64_t)cca; - zb = wa * (uint64_t)qa + wb * (uint64_t)qb + (uint64_t)ccb; - if (k > 0) { - a[k - 1] = za & 0x7FFFFFFF; - b[k - 1] = zb & 0x7FFFFFFF; - } - - /* - * For the new values of cca and ccb, we need a signed - * right-shift; since, in C, right-shifting a signed - * negative value is implementation-defined, we use a - * custom portable sign extension expression. - */ -#define M ((uint64_t)1 << 32) - tta = za >> 31; - ttb = zb >> 31; - tta = (tta ^ M) - M; - ttb = (ttb ^ M) - M; - cca = *(int64_t *)&tta; - ccb = *(int64_t *)&ttb; -#undef M - } - a[len - 1] = (uint32_t)cca; - b[len - 1] = (uint32_t)ccb; - - nega = (uint32_t)((uint64_t)cca >> 63); - negb = (uint32_t)((uint64_t)ccb >> 63); - cond_negate(a, len, nega); - cond_negate(b, len, negb); - return nega | (negb << 1); -} - -/* - * Compute: - * a <- (a*pa+b*pb)/(2^31) mod m - * b <- (a*qa+b*qb)/(2^31) mod m - * - * m0i is equal to -1/m[0] mod 2^31. - * - * Factors pa, pb, qa and qb must be at most 2^31 in absolute value. - * Source integers a and b must be nonnegative; top word is not allowed - * to contain an extra 32th bit. - */ -static void -co_reduce_mod(uint32_t *a, uint32_t *b, size_t len, - int64_t pa, int64_t pb, int64_t qa, int64_t qb, - const uint32_t *m, uint32_t m0i) -{ - size_t k; - int64_t cca, ccb; - uint32_t fa, fb; - - cca = 0; - ccb = 0; - fa = ((a[0] * (uint32_t)pa + b[0] * (uint32_t)pb) * m0i) & 0x7FFFFFFF; - fb = ((a[0] * (uint32_t)qa + b[0] * (uint32_t)qb) * m0i) & 0x7FFFFFFF; - for (k = 0; k < len; k ++) { - uint32_t wa, wb; - uint64_t za, zb; - uint64_t tta, ttb; - - /* - * In this loop, carries 'cca' and 'ccb' always fit on - * 33 bits (in absolute value). - */ - wa = a[k]; - wb = b[k]; - za = wa * (uint64_t)pa + wb * (uint64_t)pb - + m[k] * (uint64_t)fa + (uint64_t)cca; - zb = wa * (uint64_t)qa + wb * (uint64_t)qb - + m[k] * (uint64_t)fb + (uint64_t)ccb; - if (k > 0) { - a[k - 1] = (uint32_t)za & 0x7FFFFFFF; - b[k - 1] = (uint32_t)zb & 0x7FFFFFFF; - } - -#define M ((uint64_t)1 << 32) - tta = za >> 31; - ttb = zb >> 31; - tta = (tta ^ M) - M; - ttb = (ttb ^ M) - M; - cca = *(int64_t *)&tta; - ccb = *(int64_t *)&ttb; -#undef M - } - a[len - 1] = (uint32_t)cca; - b[len - 1] = (uint32_t)ccb; - - /* - * At this point: - * -m <= a < 2*m - * -m <= b < 2*m - * (this is a case of Montgomery reduction) - * The top word of 'a' and 'b' may have a 32-th bit set. - * We may have to add or subtract the modulus. - */ - finish_mod(a, len, m, (uint32_t)((uint64_t)cca >> 63)); - finish_mod(b, len, m, (uint32_t)((uint64_t)ccb >> 63)); -} - -/* see inner.h */ -uint32_t -br_i31_moddiv(uint32_t *x, const uint32_t *y, const uint32_t *m, uint32_t m0i, - uint32_t *t) -{ - /* - * Algorithm is an extended binary GCD. We maintain four values - * a, b, u and v, with the following invariants: - * - * a * x = y * u mod m - * b * x = y * v mod m - * - * Starting values are: - * - * a = y - * b = m - * u = x - * v = 0 - * - * The formal definition of the algorithm is a sequence of steps: - * - * - If a is even, then a <- a/2 and u <- u/2 mod m. - * - Otherwise, if b is even, then b <- b/2 and v <- v/2 mod m. - * - Otherwise, if a > b, then a <- (a-b)/2 and u <- (u-v)/2 mod m. - * - Otherwise, b <- (b-a)/2 and v <- (v-u)/2 mod m. - * - * Algorithm stops when a = b. At that point, they both are equal - * to GCD(y,m); the modular division succeeds if that value is 1. - * The result of the modular division is then u (or v: both are - * equal at that point). - * - * Each step makes either a or b shrink by at least one bit; hence, - * if m has bit length k bits, then 2k-2 steps are sufficient. - * - * - * Though complexity is quadratic in the size of m, the bit-by-bit - * processing is not very efficient. We can speed up processing by - * remarking that the decisions are taken based only on observation - * of the top and low bits of a and b. - * - * In the loop below, at each iteration, we use the two top words - * of a and b, and the low words of a and b, to compute reduction - * parameters pa, pb, qa and qb such that the new values for a - * and b are: - * - * a' = (a*pa + b*pb) / (2^31) - * b' = (a*qa + b*qb) / (2^31) - * - * the division being exact. - * - * Since the choices are based on the top words, they may be slightly - * off, requiring an optional correction: if a' < 0, then we replace - * pa with -pa, and pb with -pb. The total length of a and b is - * thus reduced by at least 30 bits at each iteration. - * - * The stopping conditions are still the same, though: when a - * and b become equal, they must be both odd (since m is odd, - * the GCD cannot be even), therefore the next operation is a - * subtraction, and one of the values becomes 0. At that point, - * nothing else happens, i.e. one value is stuck at 0, and the - * other one is the GCD. - */ - size_t len, k; - uint32_t *a, *b, *u, *v; - uint32_t num, r; - - len = (m[0] + 31) >> 5; - a = t; - b = a + len; - u = x + 1; - v = b + len; - memcpy(a, y + 1, len * sizeof *y); - memcpy(b, m + 1, len * sizeof *m); - memset(v, 0, len * sizeof *v); - - /* - * Loop below ensures that a and b are reduced by some bits each, - * for a total of at least 30 bits. - */ - for (num = ((m[0] - (m[0] >> 5)) << 1) + 30; num >= 30; num -= 30) { - size_t j; - uint32_t c0, c1; - uint32_t a0, a1, b0, b1; - uint64_t a_hi, b_hi; - uint32_t a_lo, b_lo; - int64_t pa, pb, qa, qb; - int i; - - /* - * Extract top words of a and b. If j is the highest - * index >= 1 such that a[j] != 0 or b[j] != 0, then we want - * (a[j] << 31) + a[j - 1], and (b[j] << 31) + b[j - 1]. - * If a and b are down to one word each, then we use a[0] - * and b[0]. - */ - c0 = (uint32_t)-1; - c1 = (uint32_t)-1; - a0 = 0; - a1 = 0; - b0 = 0; - b1 = 0; - j = len; - while (j -- > 0) { - uint32_t aw, bw; - - aw = a[j]; - bw = b[j]; - a0 ^= (a0 ^ aw) & c0; - a1 ^= (a1 ^ aw) & c1; - b0 ^= (b0 ^ bw) & c0; - b1 ^= (b1 ^ bw) & c1; - c1 = c0; - c0 &= (((aw | bw) + 0x7FFFFFFF) >> 31) - (uint32_t)1; - } - - /* - * If c1 = 0, then we grabbed two words for a and b. - * If c1 != 0 but c0 = 0, then we grabbed one word. It - * is not possible that c1 != 0 and c0 != 0, because that - * would mean that both integers are zero. - */ - a1 |= a0 & c1; - a0 &= ~c1; - b1 |= b0 & c1; - b0 &= ~c1; - a_hi = ((uint64_t)a0 << 31) + a1; - b_hi = ((uint64_t)b0 << 31) + b1; - a_lo = a[0]; - b_lo = b[0]; - - /* - * Compute reduction factors: - * - * a' = a*pa + b*pb - * b' = a*qa + b*qb - * - * such that a' and b' are both multiple of 2^31, but are - * only marginally larger than a and b. - */ - pa = 1; - pb = 0; - qa = 0; - qb = 1; - for (i = 0; i < 31; i ++) { - /* - * At each iteration: - * - * a <- (a-b)/2 if: a is odd, b is odd, a_hi > b_hi - * b <- (b-a)/2 if: a is odd, b is odd, a_hi <= b_hi - * a <- a/2 if: a is even - * b <- b/2 if: a is odd, b is even - * - * We multiply a_lo and b_lo by 2 at each - * iteration, thus a division by 2 really is a - * non-multiplication by 2. - */ - uint32_t r, oa, ob, cAB, cBA, cA; - uint64_t rz; - - /* - * r = GT(a_hi, b_hi) - * But the GT() function works on uint32_t operands, - * so we inline a 64-bit version here. - */ - rz = b_hi - a_hi; - r = (uint32_t)((rz ^ ((a_hi ^ b_hi) - & (a_hi ^ rz))) >> 63); - - /* - * cAB = 1 if b must be subtracted from a - * cBA = 1 if a must be subtracted from b - * cA = 1 if a is divided by 2, 0 otherwise - * - * Rules: - * - * cAB and cBA cannot be both 1. - * if a is not divided by 2, b is. - */ - oa = (a_lo >> i) & 1; - ob = (b_lo >> i) & 1; - cAB = oa & ob & r; - cBA = oa & ob & NOT(r); - cA = cAB | NOT(oa); - - /* - * Conditional subtractions. - */ - a_lo -= b_lo & -cAB; - a_hi -= b_hi & -(uint64_t)cAB; - pa -= qa & -(int64_t)cAB; - pb -= qb & -(int64_t)cAB; - b_lo -= a_lo & -cBA; - b_hi -= a_hi & -(uint64_t)cBA; - qa -= pa & -(int64_t)cBA; - qb -= pb & -(int64_t)cBA; - - /* - * Shifting. - */ - a_lo += a_lo & (cA - 1); - pa += pa & ((int64_t)cA - 1); - pb += pb & ((int64_t)cA - 1); - a_hi ^= (a_hi ^ (a_hi >> 1)) & -(uint64_t)cA; - b_lo += b_lo & -cA; - qa += qa & -(int64_t)cA; - qb += qb & -(int64_t)cA; - b_hi ^= (b_hi ^ (b_hi >> 1)) & ((uint64_t)cA - 1); - } - - /* - * Replace a and b with new values a' and b'. - */ - r = co_reduce(a, b, len, pa, pb, qa, qb); - pa -= pa * ((r & 1) << 1); - pb -= pb * ((r & 1) << 1); - qa -= qa * (r & 2); - qb -= qb * (r & 2); - co_reduce_mod(u, v, len, pa, pb, qa, qb, m + 1, m0i); - } - - /* - * Now one of the arrays should be 0, and the other contains - * the GCD. If a is 0, then u is 0 as well, and v contains - * the division result. - * Result is correct if and only if GCD is 1. - */ - r = (a[0] | b[0]) ^ 1; - u[0] |= v[0]; - for (k = 1; k < len; k ++) { - r |= a[k] | b[k]; - u[k] |= v[k]; - } - return EQ0(r); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i31_modpow.c b/src/tls/bearssl/i31_modpow.c deleted file mode 100644 index e1a23e64b..000000000 --- a/src/tls/bearssl/i31_modpow.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_i31_modpow(uint32_t *x, - const unsigned char *e, size_t elen, - const uint32_t *m, uint32_t m0i, uint32_t *t1, uint32_t *t2) -{ - size_t mlen; - uint32_t k; - - /* - * 'mlen' is the length of m[] expressed in bytes (including - * the "bit length" first field). - */ - mlen = ((m[0] + 63) >> 5) * sizeof m[0]; - - /* - * Throughout the algorithm: - * -- t1[] is in Montgomery representation; it contains x, x^2, - * x^4, x^8... - * -- The result is accumulated, in normal representation, in - * the x[] array. - * -- t2[] is used as destination buffer for each multiplication. - * - * Note that there is no need to call br_i32_from_monty(). - */ - memcpy(t1, x, mlen); - br_i31_to_monty(t1, m); - br_i31_zero(x, m[0]); - x[1] = 1; - for (k = 0; k < ((uint32_t)elen << 3); k ++) { - uint32_t ctl; - - ctl = (e[elen - 1 - (k >> 3)] >> (k & 7)) & 1; - br_i31_montymul(t2, x, t1, m, m0i); - CCOPY(ctl, x, t2, mlen); - br_i31_montymul(t2, t1, t1, m, m0i); - memcpy(t1, t2, mlen); - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i31_modpow2.c b/src/tls/bearssl/i31_modpow2.c deleted file mode 100644 index b97b1c8fc..000000000 --- a/src/tls/bearssl/i31_modpow2.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -uint32_t -br_i31_modpow_opt(uint32_t *x, - const unsigned char *e, size_t elen, - const uint32_t *m, uint32_t m0i, uint32_t *tmp, size_t twlen) -{ - size_t mlen, mwlen; - uint32_t *t1, *t2, *base; - size_t u, v; - uint32_t acc; - int acc_len, win_len; - - /* - * Get modulus size. - */ - mwlen = (m[0] + 63) >> 5; - mlen = mwlen * sizeof m[0]; - mwlen += (mwlen & 1); - t1 = tmp; - t2 = tmp + mwlen; - - /* - * Compute possible window size, with a maximum of 5 bits. - * When the window has size 1 bit, we use a specific code - * that requires only two temporaries. Otherwise, for a - * window of k bits, we need 2^k+1 temporaries. - */ - if (twlen < (mwlen << 1)) { - return 0; - } - for (win_len = 5; win_len > 1; win_len --) { - if ((((uint32_t)1 << win_len) + 1) * mwlen <= twlen) { - break; - } - } - - /* - * Everything is done in Montgomery representation. - */ - br_i31_to_monty(x, m); - - /* - * Compute window contents. If the window has size one bit only, - * then t2 is set to x; otherwise, t2[0] is left untouched, and - * t2[k] is set to x^k (for k >= 1). - */ - if (win_len == 1) { - memcpy(t2, x, mlen); - } else { - memcpy(t2 + mwlen, x, mlen); - base = t2 + mwlen; - for (u = 2; u < ((unsigned)1 << win_len); u ++) { - br_i31_montymul(base + mwlen, base, x, m, m0i); - base += mwlen; - } - } - - /* - * We need to set x to 1, in Montgomery representation. This can - * be done efficiently by setting the high word to 1, then doing - * one word-sized shift. - */ - br_i31_zero(x, m[0]); - x[(m[0] + 31) >> 5] = 1; - br_i31_muladd_small(x, 0, m); - - /* - * We process bits from most to least significant. At each - * loop iteration, we have acc_len bits in acc. - */ - acc = 0; - acc_len = 0; - while (acc_len > 0 || elen > 0) { - int i, k; - uint32_t bits; - - /* - * Get the next bits. - */ - k = win_len; - if (acc_len < win_len) { - if (elen > 0) { - acc = (acc << 8) | *e ++; - elen --; - acc_len += 8; - } else { - k = acc_len; - } - } - bits = (acc >> (acc_len - k)) & (((uint32_t)1 << k) - 1); - acc_len -= k; - - /* - * We could get exactly k bits. Compute k squarings. - */ - for (i = 0; i < k; i ++) { - br_i31_montymul(t1, x, x, m, m0i); - memcpy(x, t1, mlen); - } - - /* - * Window lookup: we want to set t2 to the window - * lookup value, assuming the bits are non-zero. If - * the window length is 1 bit only, then t2 is - * already set; otherwise, we do a constant-time lookup. - */ - if (win_len > 1) { - br_i31_zero(t2, m[0]); - base = t2 + mwlen; - for (u = 1; u < ((uint32_t)1 << k); u ++) { - uint32_t mask; - - mask = -EQ(u, bits); - for (v = 1; v < mwlen; v ++) { - t2[v] |= mask & base[v]; - } - base += mwlen; - } - } - - /* - * Multiply with the looked-up value. We keep the - * product only if the exponent bits are not all-zero. - */ - br_i31_montymul(t1, x, t2, m, m0i); - CCOPY(NEQ(bits, 0), x, t1, mlen); - } - - /* - * Convert back from Montgomery representation, and exit. - */ - br_i31_from_monty(x, m, m0i); - return 1; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i31_montmul.c b/src/tls/bearssl/i31_montmul.c deleted file mode 100644 index d6ff97bdb..000000000 --- a/src/tls/bearssl/i31_montmul.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_i31_montymul(uint32_t *d, const uint32_t *x, const uint32_t *y, - const uint32_t *m, uint32_t m0i) -{ - size_t len, len4, u, v; - uint64_t dh; - - len = (m[0] + 31) >> 5; - len4 = len & ~(size_t)3; - br_i31_zero(d, m[0]); - dh = 0; - for (u = 0; u < len; u ++) { - uint32_t f, xu; - uint64_t r, zh; - - xu = x[u + 1]; - f = MUL31_lo((d[1] + MUL31_lo(x[u + 1], y[1])), m0i); - - r = 0; - for (v = 0; v < len4; v += 4) { - uint64_t z; - - z = (uint64_t)d[v + 1] + MUL31(xu, y[v + 1]) - + MUL31(f, m[v + 1]) + r; - r = z >> 31; - d[v + 0] = (uint32_t)z & 0x7FFFFFFF; - z = (uint64_t)d[v + 2] + MUL31(xu, y[v + 2]) - + MUL31(f, m[v + 2]) + r; - r = z >> 31; - d[v + 1] = (uint32_t)z & 0x7FFFFFFF; - z = (uint64_t)d[v + 3] + MUL31(xu, y[v + 3]) - + MUL31(f, m[v + 3]) + r; - r = z >> 31; - d[v + 2] = (uint32_t)z & 0x7FFFFFFF; - z = (uint64_t)d[v + 4] + MUL31(xu, y[v + 4]) - + MUL31(f, m[v + 4]) + r; - r = z >> 31; - d[v + 3] = (uint32_t)z & 0x7FFFFFFF; - } - for (; v < len; v ++) { - uint64_t z; - - z = (uint64_t)d[v + 1] + MUL31(xu, y[v + 1]) - + MUL31(f, m[v + 1]) + r; - r = z >> 31; - d[v] = (uint32_t)z & 0x7FFFFFFF; - } - - zh = dh + r; - d[len] = (uint32_t)zh & 0x7FFFFFFF; - dh = zh >> 31; - } - - /* - * We must write back the bit length because it was overwritten in - * the loop (not overwriting it would require a test in the loop, - * which would yield bigger and slower code). - */ - d[0] = m[0]; - - /* - * d[] may still be greater than m[] at that point; notably, the - * 'dh' word may be non-zero. - */ - br_i31_sub(d, m, NEQ(dh, 0) | NOT(br_i31_sub(d, m, 0))); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i31_mulacc.c b/src/tls/bearssl/i31_mulacc.c deleted file mode 100644 index e0fb369b1..000000000 --- a/src/tls/bearssl/i31_mulacc.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_i31_mulacc(uint32_t *d, const uint32_t *a, const uint32_t *b) -{ - size_t alen, blen, u; - uint32_t dl, dh; - - alen = (a[0] + 31) >> 5; - blen = (b[0] + 31) >> 5; - - /* - * We want to add the two bit lengths, but these are encoded, - * which requires some extra care. - */ - dl = (a[0] & 31) + (b[0] & 31); - dh = (a[0] >> 5) + (b[0] >> 5); - d[0] = (dh << 5) + dl + (~(uint32_t)(dl - 31) >> 31); - - for (u = 0; u < blen; u ++) { - uint32_t f; - size_t v; - uint64_t cc; - - f = b[1 + u]; - cc = 0; - for (v = 0; v < alen; v ++) { - uint64_t z; - - z = (uint64_t)d[1 + u + v] + MUL31(f, a[1 + v]) + cc; - cc = z >> 31; - d[1 + u + v] = (uint32_t)z & 0x7FFFFFFF; - } - d[1 + u + alen] = (uint32_t)cc; - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i31_muladd.c b/src/tls/bearssl/i31_muladd.c deleted file mode 100644 index b10e1a1a5..000000000 --- a/src/tls/bearssl/i31_muladd.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_i31_muladd_small(uint32_t *x, uint32_t z, const uint32_t *m) -{ - uint32_t m_bitlen; - unsigned mblr; - size_t u, mlen; - uint32_t a0, a1, b0, hi, g, q, tb; - uint32_t under, over; - uint32_t cc; - - /* - * We can test on the modulus bit length since we accept to - * leak that length. - */ - m_bitlen = m[0]; - if (m_bitlen == 0) { - return; - } - if (m_bitlen <= 31) { - uint32_t lo; - - hi = x[1] >> 1; - lo = (x[1] << 31) | z; - x[1] = br_rem(hi, lo, m[1]); - return; - } - mlen = (m_bitlen + 31) >> 5; - mblr = (unsigned)m_bitlen & 31; - - /* - * Principle: we estimate the quotient (x*2^31+z)/m by - * doing a 64/32 division with the high words. - * - * Let: - * w = 2^31 - * a = (w*a0 + a1) * w^N + a2 - * b = b0 * w^N + b2 - * such that: - * 0 <= a0 < w - * 0 <= a1 < w - * 0 <= a2 < w^N - * w/2 <= b0 < w - * 0 <= b2 < w^N - * a < w*b - * I.e. the two top words of a are a0:a1, the top word of b is - * b0, we ensured that b0 is "full" (high bit set), and a is - * such that the quotient q = a/b fits on one word (0 <= q < w). - * - * If a = b*q + r (with 0 <= r < q), we can estimate q by - * doing an Euclidean division on the top words: - * a0*w+a1 = b0*u + v (with 0 <= v < b0) - * Then the following holds: - * 0 <= u <= w - * u-2 <= q <= u - */ - hi = x[mlen]; - if (mblr == 0) { - a0 = x[mlen]; - memmove(x + 2, x + 1, (mlen - 1) * sizeof *x); - x[1] = z; - a1 = x[mlen]; - b0 = m[mlen]; - } else { - a0 = ((x[mlen] << (31 - mblr)) | (x[mlen - 1] >> mblr)) - & 0x7FFFFFFF; - memmove(x + 2, x + 1, (mlen - 1) * sizeof *x); - x[1] = z; - a1 = ((x[mlen] << (31 - mblr)) | (x[mlen - 1] >> mblr)) - & 0x7FFFFFFF; - b0 = ((m[mlen] << (31 - mblr)) | (m[mlen - 1] >> mblr)) - & 0x7FFFFFFF; - } - - /* - * We estimate a divisor q. If the quotient returned by br_div() - * is g: - * -- If a0 == b0 then g == 0; we want q = 0x7FFFFFFF. - * -- Otherwise: - * -- if g == 0 then we set q = 0; - * -- otherwise, we set q = g - 1. - * The properties described above then ensure that the true - * quotient is q-1, q or q+1. - * - * Take care that a0, a1 and b0 are 31-bit words, not 32-bit. We - * must adjust the parameters to br_div() accordingly. - */ - g = br_div(a0 >> 1, a1 | (a0 << 31), b0); - q = MUX(EQ(a0, b0), 0x7FFFFFFF, MUX(EQ(g, 0), 0, g - 1)); - - /* - * We subtract q*m from x (with the extra high word of value 'hi'). - * Since q may be off by 1 (in either direction), we may have to - * add or subtract m afterwards. - * - * The 'tb' flag will be true (1) at the end of the loop if the - * result is greater than or equal to the modulus (not counting - * 'hi' or the carry). - */ - cc = 0; - tb = 1; - for (u = 1; u <= mlen; u ++) { - uint32_t mw, zw, xw, nxw; - uint64_t zl; - - mw = m[u]; - zl = MUL31(mw, q) + cc; - cc = (uint32_t)(zl >> 31); - zw = (uint32_t)zl & (uint32_t)0x7FFFFFFF; - xw = x[u]; - nxw = xw - zw; - cc += nxw >> 31; - nxw &= 0x7FFFFFFF; - x[u] = nxw; - tb = MUX(EQ(nxw, mw), tb, GT(nxw, mw)); - } - - /* - * If we underestimated q, then either cc < hi (one extra bit - * beyond the top array word), or cc == hi and tb is true (no - * extra bit, but the result is not lower than the modulus). In - * these cases we must subtract m once. - * - * Otherwise, we may have overestimated, which will show as - * cc > hi (thus a negative result). Correction is adding m once. - */ - over = GT(cc, hi); - under = ~over & (tb | LT(cc, hi)); - br_i31_add(x, m, over); - br_i31_sub(x, m, under); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i31_ninv31.c b/src/tls/bearssl/i31_ninv31.c deleted file mode 100644 index fb44f2eb8..000000000 --- a/src/tls/bearssl/i31_ninv31.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -uint32_t -br_i31_ninv31(uint32_t x) -{ - uint32_t y; - - y = 2 - x; - y *= 2 - y * x; - y *= 2 - y * x; - y *= 2 - y * x; - y *= 2 - y * x; - return MUX(x & 1, -y, 0) & 0x7FFFFFFF; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i31_reduce.c b/src/tls/bearssl/i31_reduce.c deleted file mode 100644 index 672a48f90..000000000 --- a/src/tls/bearssl/i31_reduce.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_i31_reduce(uint32_t *x, const uint32_t *a, const uint32_t *m) -{ - uint32_t m_bitlen, a_bitlen; - size_t mlen, alen, u; - - m_bitlen = m[0]; - mlen = (m_bitlen + 31) >> 5; - - x[0] = m_bitlen; - if (m_bitlen == 0) { - return; - } - - /* - * If the source is shorter, then simply copy all words from a[] - * and zero out the upper words. - */ - a_bitlen = a[0]; - alen = (a_bitlen + 31) >> 5; - if (a_bitlen < m_bitlen) { - memcpy(x + 1, a + 1, alen * sizeof *a); - for (u = alen; u < mlen; u ++) { - x[u + 1] = 0; - } - return; - } - - /* - * The source length is at least equal to that of the modulus. - * We must thus copy N-1 words, and input the remaining words - * one by one. - */ - memcpy(x + 1, a + 2 + (alen - mlen), (mlen - 1) * sizeof *a); - x[mlen] = 0; - for (u = 1 + alen - mlen; u > 0; u --) { - br_i31_muladd_small(x, a[u], m); - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i31_rshift.c b/src/tls/bearssl/i31_rshift.c deleted file mode 100644 index 67f09a781..000000000 --- a/src/tls/bearssl/i31_rshift.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_i31_rshift(uint32_t *x, int count) -{ - size_t u, len; - uint32_t r; - - len = (x[0] + 31) >> 5; - if (len == 0) { - return; - } - r = x[1] >> count; - for (u = 2; u <= len; u ++) { - uint32_t w; - - w = x[u]; - x[u - 1] = ((w << (31 - count)) | r) & 0x7FFFFFFF; - r = w >> count; - } - x[len] = r; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i31_sub.c b/src/tls/bearssl/i31_sub.c deleted file mode 100644 index 39ae7bf0b..000000000 --- a/src/tls/bearssl/i31_sub.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -uint32_t -br_i31_sub(uint32_t *a, const uint32_t *b, uint32_t ctl) -{ - uint32_t cc; - size_t u, m; - - cc = 0; - m = (a[0] + 63) >> 5; - for (u = 1; u < m; u ++) { - uint32_t aw, bw, naw; - - aw = a[u]; - bw = b[u]; - naw = aw - bw - cc; - cc = naw >> 31; - a[u] = MUX(ctl, naw & 0x7FFFFFFF, aw); - } - return cc; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i31_tmont.c b/src/tls/bearssl/i31_tmont.c deleted file mode 100644 index 8b9a310f0..000000000 --- a/src/tls/bearssl/i31_tmont.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_i31_to_monty(uint32_t *x, const uint32_t *m) -{ - uint32_t k; - - for (k = (m[0] + 31) >> 5; k > 0; k --) { - br_i31_muladd_small(x, 0, m); - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i32_bitlen.c b/src/tls/bearssl/i32_bitlen.c deleted file mode 100644 index 34b229429..000000000 --- a/src/tls/bearssl/i32_bitlen.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -uint32_t -br_i32_bit_length(uint32_t *x, size_t xlen) -{ - uint32_t tw, twk; - - tw = 0; - twk = 0; - while (xlen -- > 0) { - uint32_t w, c; - - c = EQ(tw, 0); - w = x[xlen]; - tw = MUX(c, w, tw); - twk = MUX(c, (uint32_t)xlen, twk); - } - return (twk << 5) + BIT_LENGTH(tw); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i32_decmod.c b/src/tls/bearssl/i32_decmod.c deleted file mode 100644 index 804e62115..000000000 --- a/src/tls/bearssl/i32_decmod.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -uint32_t -br_i32_decode_mod(uint32_t *x, const void *src, size_t len, const uint32_t *m) -{ - const unsigned char *buf; - uint32_t r; - size_t u, v, mlen; - - buf = src; - - /* - * First pass: determine whether the value fits. The 'r' value - * will contain the comparison result, as 0x00000000 (value is - * equal to the modulus), 0x00000001 (value is greater than the - * modulus), or 0xFFFFFFFF (value is lower than the modulus). - */ - mlen = (m[0] + 7) >> 3; - r = 0; - for (u = (mlen > len) ? mlen : len; u > 0; u --) { - uint32_t mb, xb; - - v = u - 1; - if (v >= mlen) { - mb = 0; - } else { - mb = (m[1 + (v >> 2)] >> ((v & 3) << 3)) & 0xFF; - } - if (v >= len) { - xb = 0; - } else { - xb = buf[len - u]; - } - r = MUX(EQ(r, 0), (uint32_t)CMP(xb, mb), r); - } - - /* - * Only r == 0xFFFFFFFF is acceptable. We want to set r to 0xFF if - * the value fits, 0x00 otherwise. - */ - r >>= 24; - br_i32_zero(x, m[0]); - u = (mlen > len) ? len : mlen; - while (u > 0) { - uint32_t xb; - - xb = buf[len - u] & r; - u --; - x[1 + (u >> 2)] |= xb << ((u & 3) << 3); - } - return r >> 7; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i32_decode.c b/src/tls/bearssl/i32_decode.c deleted file mode 100644 index 19de24c1e..000000000 --- a/src/tls/bearssl/i32_decode.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_i32_decode(uint32_t *x, const void *src, size_t len) -{ - const unsigned char *buf; - size_t u, v; - - buf = src; - u = len; - v = 1; - for (;;) { - if (u < 4) { - uint32_t w; - - if (u < 2) { - if (u == 0) { - break; - } else { - w = buf[0]; - } - } else { - if (u == 2) { - w = br_dec16be(buf); - } else { - w = ((uint32_t)buf[0] << 16) - | br_dec16be(buf + 1); - } - } - x[v ++] = w; - break; - } else { - u -= 4; - x[v ++] = br_dec32be(buf + u); - } - } - x[0] = br_i32_bit_length(x + 1, v - 1); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i32_decred.c b/src/tls/bearssl/i32_decred.c deleted file mode 100644 index 05098dc2b..000000000 --- a/src/tls/bearssl/i32_decred.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_i32_decode_reduce(uint32_t *x, - const void *src, size_t len, const uint32_t *m) -{ - uint32_t m_bitlen; - size_t mblen, k, q; - const unsigned char *buf; - - m_bitlen = m[0]; - - /* - * Special case for an invalid modulus. - */ - if (m_bitlen == 0) { - x[0] = 0; - return; - } - - /* - * Clear the destination. - */ - br_i32_zero(x, m_bitlen); - - /* - * First decode directly as many bytes as possible without - * reduction, taking care to leave a number of bytes which - * is a multiple of 4. - */ - mblen = (m_bitlen + 7) >> 3; - k = mblen - 1; - - /* - * Up to k bytes can be safely decoded. - */ - if (k >= len) { - br_i32_decode(x, src, len); - x[0] = m_bitlen; - return; - } - - /* - * We want to first inject some bytes with direct decoding, - * then extra bytes by whole 32-bit words. First compute - * the size that should be injected that way. - */ - buf = src; - q = (len - k + 3) & ~(size_t)3; - - /* - * It may happen that this is more than what we already have - * (by at most 3 bytes). Such a case may happen only with - * a very short modulus. In that case, we must process the first - * bytes "manually". - */ - if (q > len) { - int i; - uint32_t w; - - w = 0; - for (i = 0; i < 4; i ++) { - w <<= 8; - if (q <= len) { - w |= buf[len - q]; - } - q --; - } - br_i32_muladd_small(x, w, m); - } else { - br_i32_decode(x, buf, len - q); - x[0] = m_bitlen; - } - - /* - * At that point, we have exactly q bytes to inject, and q is - * a multiple of 4. - */ - for (k = len - q; k < len; k += 4) { - br_i32_muladd_small(x, br_dec32be(buf + k), m); - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i32_div32.c b/src/tls/bearssl/i32_div32.c deleted file mode 100644 index b275effd9..000000000 --- a/src/tls/bearssl/i32_div32.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -uint32_t -br_divrem(uint32_t hi, uint32_t lo, uint32_t d, uint32_t *r) -{ - /* TODO: optimize this */ - uint32_t q; - uint32_t ch, cf; - int k; - - q = 0; - ch = EQ(hi, d); - hi = MUX(ch, 0, hi); - for (k = 31; k > 0; k --) { - int j; - uint32_t w, ctl, hi2, lo2; - - j = 32 - k; - w = (hi << j) | (lo >> k); - ctl = GE(w, d) | (hi >> k); - hi2 = (w - d) >> j; - lo2 = lo - (d << k); - hi = MUX(ctl, hi2, hi); - lo = MUX(ctl, lo2, lo); - q |= ctl << k; - } - cf = GE(lo, d) | hi; - q |= cf; - *r = MUX(cf, lo - d, lo); - return q; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i32_encode.c b/src/tls/bearssl/i32_encode.c deleted file mode 100644 index 6d1ddac44..000000000 --- a/src/tls/bearssl/i32_encode.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_i32_encode(void *dst, size_t len, const uint32_t *x) -{ - unsigned char *buf; - size_t k; - - buf = dst; - - /* - * Compute the announced size of x in bytes; extra bytes are - * filled with zeros. - */ - k = (x[0] + 7) >> 3; - while (len > k) { - *buf ++ = 0; - len --; - } - - /* - * Now we use k as index within x[]. That index starts at 1; - * we initialize it to the topmost complete word, and process - * any remaining incomplete word. - */ - k = (len + 3) >> 2; - switch (len & 3) { - case 3: - *buf ++ = x[k] >> 16; - /* fall through */ - case 2: - *buf ++ = x[k] >> 8; - /* fall through */ - case 1: - *buf ++ = x[k]; - k --; - } - - /* - * Encode all complete words. - */ - while (k > 0) { - br_enc32be(buf, x[k]); - k --; - buf += 4; - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i32_fmont.c b/src/tls/bearssl/i32_fmont.c deleted file mode 100644 index c0751b5b6..000000000 --- a/src/tls/bearssl/i32_fmont.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_i32_from_monty(uint32_t *x, const uint32_t *m, uint32_t m0i) -{ - size_t len, u, v; - - len = (m[0] + 31) >> 5; - for (u = 0; u < len; u ++) { - uint32_t f; - uint64_t cc; - - f = x[1] * m0i; - cc = 0; - for (v = 0; v < len; v ++) { - uint64_t z; - - z = (uint64_t)x[v + 1] + MUL(f, m[v + 1]) + cc; - cc = z >> 32; - if (v != 0) { - x[v] = (uint32_t)z; - } - } - x[len] = (uint32_t)cc; - } - - /* - * We may have to do an extra subtraction, but only if the - * value in x[] is indeed greater than or equal to that of m[], - * which is why we must do two calls (first call computes the - * carry, second call performs the subtraction only if the carry - * is 0). - */ - br_i32_sub(x, m, NOT(br_i32_sub(x, m, 0))); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i32_iszero.c b/src/tls/bearssl/i32_iszero.c deleted file mode 100644 index d0b964623..000000000 --- a/src/tls/bearssl/i32_iszero.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -uint32_t -br_i32_iszero(const uint32_t *x) -{ - uint32_t z; - size_t u; - - z = 0; - for (u = (x[0] + 31) >> 5; u > 0; u --) { - z |= x[u]; - } - return ~(z | -z) >> 31; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i32_modpow.c b/src/tls/bearssl/i32_modpow.c deleted file mode 100644 index 58c78adb9..000000000 --- a/src/tls/bearssl/i32_modpow.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_i32_modpow(uint32_t *x, - const unsigned char *e, size_t elen, - const uint32_t *m, uint32_t m0i, uint32_t *t1, uint32_t *t2) -{ - size_t mlen; - uint32_t k; - - /* - * 'mlen' is the length of m[] expressed in bytes (including - * the "bit length" first field). - */ - mlen = ((m[0] + 63) >> 5) * sizeof m[0]; - - /* - * Throughout the algorithm: - * -- t1[] is in Montgomery representation; it contains x, x^2, - * x^4, x^8... - * -- The result is accumulated, in normal representation, in - * the x[] array. - * -- t2[] is used as destination buffer for each multiplication. - * - * Note that there is no need to call br_i32_from_monty(). - */ - memcpy(t1, x, mlen); - br_i32_to_monty(t1, m); - br_i32_zero(x, m[0]); - x[1] = 1; - for (k = 0; k < ((uint32_t)elen << 3); k ++) { - uint32_t ctl; - - ctl = (e[elen - 1 - (k >> 3)] >> (k & 7)) & 1; - br_i32_montymul(t2, x, t1, m, m0i); - CCOPY(ctl, x, t2, mlen); - br_i32_montymul(t2, t1, t1, m, m0i); - memcpy(t1, t2, mlen); - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i32_montmul.c b/src/tls/bearssl/i32_montmul.c deleted file mode 100644 index 4ba5d4d60..000000000 --- a/src/tls/bearssl/i32_montmul.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_i32_montymul(uint32_t *d, const uint32_t *x, const uint32_t *y, - const uint32_t *m, uint32_t m0i) -{ - size_t len, u, v; - uint64_t dh; - - len = (m[0] + 31) >> 5; - br_i32_zero(d, m[0]); - dh = 0; - for (u = 0; u < len; u ++) { - uint32_t f, xu; - uint64_t r1, r2, zh; - - xu = x[u + 1]; - f = (d[1] + x[u + 1] * y[1]) * m0i; - r1 = 0; - r2 = 0; - for (v = 0; v < len; v ++) { - uint64_t z; - uint32_t t; - - z = (uint64_t)d[v + 1] + MUL(xu, y[v + 1]) + r1; - r1 = z >> 32; - t = (uint32_t)z; - z = (uint64_t)t + MUL(f, m[v + 1]) + r2; - r2 = z >> 32; - if (v != 0) { - d[v] = (uint32_t)z; - } - } - zh = dh + r1 + r2; - d[len] = (uint32_t)zh; - dh = zh >> 32; - } - - /* - * d[] may still be greater than m[] at that point; notably, the - * 'dh' word may be non-zero. - */ - br_i32_sub(d, m, NEQ(dh, 0) | NOT(br_i32_sub(d, m, 0))); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i32_mulacc.c b/src/tls/bearssl/i32_mulacc.c deleted file mode 100644 index 4119d96ca..000000000 --- a/src/tls/bearssl/i32_mulacc.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_i32_mulacc(uint32_t *d, const uint32_t *a, const uint32_t *b) -{ - size_t alen, blen, u; - - alen = (a[0] + 31) >> 5; - blen = (b[0] + 31) >> 5; - d[0] = a[0] + b[0]; - for (u = 0; u < blen; u ++) { - uint32_t f; - size_t v; - uint64_t cc; - - f = b[1 + u]; - cc = 0; - for (v = 0; v < alen; v ++) { - uint64_t z; - - z = (uint64_t)d[1 + u + v] + MUL(f, a[1 + v]) + cc; - cc = z >> 32; - d[1 + u + v] = (uint32_t)z; - } - d[1 + u + alen] = (uint32_t)cc; - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i32_muladd.c b/src/tls/bearssl/i32_muladd.c deleted file mode 100644 index 922881ff9..000000000 --- a/src/tls/bearssl/i32_muladd.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_i32_muladd_small(uint32_t *x, uint32_t z, const uint32_t *m) -{ - uint32_t m_bitlen; - size_t u, mlen; - uint32_t a0, a1, b0, hi, g, q, tb; - uint32_t chf, clow, under, over; - uint64_t cc; - - /* - * We can test on the modulus bit length since we accept to - * leak that length. - */ - m_bitlen = m[0]; - if (m_bitlen == 0) { - return; - } - if (m_bitlen <= 32) { - x[1] = br_rem(x[1], z, m[1]); - return; - } - mlen = (m_bitlen + 31) >> 5; - - /* - * Principle: we estimate the quotient (x*2^32+z)/m by - * doing a 64/32 division with the high words. - * - * Let: - * w = 2^32 - * a = (w*a0 + a1) * w^N + a2 - * b = b0 * w^N + b2 - * such that: - * 0 <= a0 < w - * 0 <= a1 < w - * 0 <= a2 < w^N - * w/2 <= b0 < w - * 0 <= b2 < w^N - * a < w*b - * I.e. the two top words of a are a0:a1, the top word of b is - * b0, we ensured that b0 is "full" (high bit set), and a is - * such that the quotient q = a/b fits on one word (0 <= q < w). - * - * If a = b*q + r (with 0 <= r < q), we can estimate q by - * doing an Euclidean division on the top words: - * a0*w+a1 = b0*u + v (with 0 <= v < w) - * Then the following holds: - * 0 <= u <= w - * u-2 <= q <= u - */ - a0 = br_i32_word(x, m_bitlen - 32); - hi = x[mlen]; - memmove(x + 2, x + 1, (mlen - 1) * sizeof *x); - x[1] = z; - a1 = br_i32_word(x, m_bitlen - 32); - b0 = br_i32_word(m, m_bitlen - 32); - - /* - * We estimate a divisor q. If the quotient returned by br_div() - * is g: - * -- If a0 == b0 then g == 0; we want q = 0xFFFFFFFF. - * -- Otherwise: - * -- if g == 0 then we set q = 0; - * -- otherwise, we set q = g - 1. - * The properties described above then ensure that the true - * quotient is q-1, q or q+1. - */ - g = br_div(a0, a1, b0); - q = MUX(EQ(a0, b0), 0xFFFFFFFF, MUX(EQ(g, 0), 0, g - 1)); - - /* - * We subtract q*m from x (with the extra high word of value 'hi'). - * Since q may be off by 1 (in either direction), we may have to - * add or subtract m afterwards. - * - * The 'tb' flag will be true (1) at the end of the loop if the - * result is greater than or equal to the modulus (not counting - * 'hi' or the carry). - */ - cc = 0; - tb = 1; - for (u = 1; u <= mlen; u ++) { - uint32_t mw, zw, xw, nxw; - uint64_t zl; - - mw = m[u]; - zl = MUL(mw, q) + cc; - cc = (uint32_t)(zl >> 32); - zw = (uint32_t)zl; - xw = x[u]; - nxw = xw - zw; - cc += (uint64_t)GT(nxw, xw); - x[u] = nxw; - tb = MUX(EQ(nxw, mw), tb, GT(nxw, mw)); - } - - /* - * If we underestimated q, then either cc < hi (one extra bit - * beyond the top array word), or cc == hi and tb is true (no - * extra bit, but the result is not lower than the modulus). In - * these cases we must subtract m once. - * - * Otherwise, we may have overestimated, which will show as - * cc > hi (thus a negative result). Correction is adding m once. - */ - chf = (uint32_t)(cc >> 32); - clow = (uint32_t)cc; - over = chf | GT(clow, hi); - under = ~over & (tb | (~chf & LT(clow, hi))); - br_i32_add(x, m, over); - br_i32_sub(x, m, under); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i32_ninv32.c b/src/tls/bearssl/i32_ninv32.c deleted file mode 100644 index d691a0cec..000000000 --- a/src/tls/bearssl/i32_ninv32.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -uint32_t -br_i32_ninv32(uint32_t x) -{ - uint32_t y; - - y = 2 - x; - y *= 2 - y * x; - y *= 2 - y * x; - y *= 2 - y * x; - y *= 2 - y * x; - return MUX(x & 1, -y, 0); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i32_reduce.c b/src/tls/bearssl/i32_reduce.c deleted file mode 100644 index 3c6ea9aa2..000000000 --- a/src/tls/bearssl/i32_reduce.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_i32_reduce(uint32_t *x, const uint32_t *a, const uint32_t *m) -{ - uint32_t m_bitlen, a_bitlen; - size_t mlen, alen, u; - - m_bitlen = m[0]; - mlen = (m_bitlen + 31) >> 5; - - x[0] = m_bitlen; - if (m_bitlen == 0) { - return; - } - - /* - * If the source is shorter, then simply copy all words from a[] - * and zero out the upper words. - */ - a_bitlen = a[0]; - alen = (a_bitlen + 31) >> 5; - if (a_bitlen < m_bitlen) { - memcpy(x + 1, a + 1, alen * sizeof *a); - for (u = alen; u < mlen; u ++) { - x[u + 1] = 0; - } - return; - } - - /* - * The source length is at least equal to that of the modulus. - * We must thus copy N-1 words, and input the remaining words - * one by one. - */ - memcpy(x + 1, a + 2 + (alen - mlen), (mlen - 1) * sizeof *a); - x[mlen] = 0; - for (u = 1 + alen - mlen; u > 0; u --) { - br_i32_muladd_small(x, a[u], m); - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i32_sub.c b/src/tls/bearssl/i32_sub.c deleted file mode 100644 index 58048ecbd..000000000 --- a/src/tls/bearssl/i32_sub.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -uint32_t -br_i32_sub(uint32_t *a, const uint32_t *b, uint32_t ctl) -{ - uint32_t cc; - size_t u, m; - - cc = 0; - m = (a[0] + 63) >> 5; - for (u = 1; u < m; u ++) { - uint32_t aw, bw, naw; - - aw = a[u]; - bw = b[u]; - naw = aw - bw - cc; - - /* - * Carry is 1 if naw > aw. Carry is 1 also if naw == aw - * AND the carry was already 1. - */ - cc = (cc & EQ(naw, aw)) | GT(naw, aw); - a[u] = MUX(ctl, naw, aw); - } - return cc; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i32_tmont.c b/src/tls/bearssl/i32_tmont.c deleted file mode 100644 index be9c003ff..000000000 --- a/src/tls/bearssl/i32_tmont.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_i32_to_monty(uint32_t *x, const uint32_t *m) -{ - uint32_t k; - - for (k = (m[0] + 31) >> 5; k > 0; k --) { - br_i32_muladd_small(x, 0, m); - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/i62_modpow2.c b/src/tls/bearssl/i62_modpow2.c deleted file mode 100644 index 674101c7f..000000000 --- a/src/tls/bearssl/i62_modpow2.c +++ /dev/null @@ -1,498 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -#if BR_INT128 || BR_UMUL128 - -#if BR_INT128 - -/* - * Compute x*y+v1+v2. Operands are 64-bit, and result is 128-bit, with - * high word in "hi" and low word in "lo". - */ -#define FMA1(hi, lo, x, y, v1, v2) do { \ - unsigned __int128 fmaz; \ - fmaz = (unsigned __int128)(x) * (unsigned __int128)(y) \ - + (unsigned __int128)(v1) + (unsigned __int128)(v2); \ - (hi) = (uint64_t)(fmaz >> 64); \ - (lo) = (uint64_t)fmaz; \ - } while (0) - -/* - * Compute x1*y1+x2*y2+v1+v2. Operands are 64-bit, and result is 128-bit, - * with high word in "hi" and low word in "lo". - * - * Callers should ensure that the two inner products, and the v1 and v2 - * operands, are multiple of 4 (this is not used by this specific definition - * but may help other implementations). - */ -#define FMA2(hi, lo, x1, y1, x2, y2, v1, v2) do { \ - unsigned __int128 fmaz; \ - fmaz = (unsigned __int128)(x1) * (unsigned __int128)(y1) \ - + (unsigned __int128)(x2) * (unsigned __int128)(y2) \ - + (unsigned __int128)(v1) + (unsigned __int128)(v2); \ - (hi) = (uint64_t)(fmaz >> 64); \ - (lo) = (uint64_t)fmaz; \ - } while (0) - -#elif BR_UMUL128 - -#include - -#define FMA1(hi, lo, x, y, v1, v2) do { \ - uint64_t fmahi, fmalo; \ - unsigned char fmacc; \ - fmalo = _umul128((x), (y), &fmahi); \ - fmacc = _addcarry_u64(0, fmalo, (v1), &fmalo); \ - _addcarry_u64(fmacc, fmahi, 0, &fmahi); \ - fmacc = _addcarry_u64(0, fmalo, (v2), &(lo)); \ - _addcarry_u64(fmacc, fmahi, 0, &(hi)); \ - } while (0) - -/* - * Normally we should use _addcarry_u64() for FMA2 too, but it makes - * Visual Studio crash. Instead we use this version, which leverages - * the fact that the vx operands, and the products, are multiple of 4. - * This is unfortunately slower. - */ -#define FMA2(hi, lo, x1, y1, x2, y2, v1, v2) do { \ - uint64_t fma1hi, fma1lo; \ - uint64_t fma2hi, fma2lo; \ - uint64_t fmatt; \ - fma1lo = _umul128((x1), (y1), &fma1hi); \ - fma2lo = _umul128((x2), (y2), &fma2hi); \ - fmatt = (fma1lo >> 2) + (fma2lo >> 2) \ - + ((v1) >> 2) + ((v2) >> 2); \ - (lo) = fmatt << 2; \ - (hi) = fma1hi + fma2hi + (fmatt >> 62); \ - } while (0) - -/* - * The FMA2 macro definition we would prefer to use, but it triggers - * an internal compiler error in Visual Studio 2015. - * -#define FMA2(hi, lo, x1, y1, x2, y2, v1, v2) do { \ - uint64_t fma1hi, fma1lo; \ - uint64_t fma2hi, fma2lo; \ - unsigned char fmacc; \ - fma1lo = _umul128((x1), (y1), &fma1hi); \ - fma2lo = _umul128((x2), (y2), &fma2hi); \ - fmacc = _addcarry_u64(0, fma1lo, (v1), &fma1lo); \ - _addcarry_u64(fmacc, fma1hi, 0, &fma1hi); \ - fmacc = _addcarry_u64(0, fma2lo, (v2), &fma2lo); \ - _addcarry_u64(fmacc, fma2hi, 0, &fma2hi); \ - fmacc = _addcarry_u64(0, fma1lo, fma2lo, &(lo)); \ - _addcarry_u64(fmacc, fma1hi, fma2hi, &(hi)); \ - } while (0) - */ - -#endif - -#define MASK62 ((uint64_t)0x3FFFFFFFFFFFFFFF) -#define MUL62_lo(x, y) (((uint64_t)(x) * (uint64_t)(y)) & MASK62) - -/* - * Subtract b from a, and return the final carry. If 'ctl32' is 0, then - * a[] is kept unmodified, but the final carry is still computed and - * returned. - */ -static uint32_t -i62_sub(uint64_t *a, const uint64_t *b, size_t num, uint32_t ctl32) -{ - uint64_t cc, mask; - size_t u; - - cc = 0; - ctl32 = -ctl32; - mask = (uint64_t)ctl32 | ((uint64_t)ctl32 << 32); - for (u = 0; u < num; u ++) { - uint64_t aw, bw, dw; - - aw = a[u]; - bw = b[u]; - dw = aw - bw - cc; - cc = dw >> 63; - dw &= MASK62; - a[u] = aw ^ (mask & (dw ^ aw)); - } - return (uint32_t)cc; -} - -/* - * Montgomery multiplication, over arrays of 62-bit values. The - * destination array (d) must be distinct from the other operands - * (x, y and m). All arrays are in little-endian format (least - * significant word comes first) over 'num' words. - */ -static void -montymul(uint64_t *d, const uint64_t *x, const uint64_t *y, - const uint64_t *m, size_t num, uint64_t m0i) -{ - uint64_t dh; - size_t u, num4; - - num4 = 1 + ((num - 1) & ~(size_t)3); - memset(d, 0, num * sizeof *d); - dh = 0; - for (u = 0; u < num; u ++) { - size_t v; - uint64_t f, xu; - uint64_t r, zh; - uint64_t hi, lo; - - xu = x[u] << 2; - f = MUL62_lo(d[0] + MUL62_lo(x[u], y[0]), m0i) << 2; - - FMA2(hi, lo, xu, y[0], f, m[0], d[0] << 2, 0); - r = hi; - - for (v = 1; v < num4; v += 4) { - FMA2(hi, lo, xu, y[v + 0], - f, m[v + 0], d[v + 0] << 2, r << 2); - r = hi + (r >> 62); - d[v - 1] = lo >> 2; - FMA2(hi, lo, xu, y[v + 1], - f, m[v + 1], d[v + 1] << 2, r << 2); - r = hi + (r >> 62); - d[v + 0] = lo >> 2; - FMA2(hi, lo, xu, y[v + 2], - f, m[v + 2], d[v + 2] << 2, r << 2); - r = hi + (r >> 62); - d[v + 1] = lo >> 2; - FMA2(hi, lo, xu, y[v + 3], - f, m[v + 3], d[v + 3] << 2, r << 2); - r = hi + (r >> 62); - d[v + 2] = lo >> 2; - } - for (; v < num; v ++) { - FMA2(hi, lo, xu, y[v], f, m[v], d[v] << 2, r << 2); - r = hi + (r >> 62); - d[v - 1] = lo >> 2; - } - - zh = dh + r; - d[num - 1] = zh & MASK62; - dh = zh >> 62; - } - i62_sub(d, m, num, (uint32_t)dh | NOT(i62_sub(d, m, num, 0))); -} - -/* - * Conversion back from Montgomery representation. - */ -static void -frommonty(uint64_t *x, const uint64_t *m, size_t num, uint64_t m0i) -{ - size_t u, v; - - for (u = 0; u < num; u ++) { - uint64_t f, cc; - - f = MUL62_lo(x[0], m0i) << 2; - cc = 0; - for (v = 0; v < num; v ++) { - uint64_t hi, lo; - - FMA1(hi, lo, f, m[v], x[v] << 2, cc); - cc = hi << 2; - if (v != 0) { - x[v - 1] = lo >> 2; - } - } - x[num - 1] = cc >> 2; - } - i62_sub(x, m, num, NOT(i62_sub(x, m, num, 0))); -} - -/* see inner.h */ -uint32_t -br_i62_modpow_opt(uint32_t *x31, const unsigned char *e, size_t elen, - const uint32_t *m31, uint32_t m0i31, uint64_t *tmp, size_t twlen) -{ - size_t u, mw31num, mw62num; - uint64_t *x, *m, *t1, *t2; - uint64_t m0i; - uint32_t acc; - int win_len, acc_len; - - /* - * Get modulus size, in words. - */ - mw31num = (m31[0] + 31) >> 5; - mw62num = (mw31num + 1) >> 1; - - /* - * In order to apply this function, we must have enough room to - * copy the operand and modulus into the temporary array, along - * with at least two temporaries. If there is not enough room, - * switch to br_i31_modpow(). We also use br_i31_modpow() if the - * modulus length is not at least four words (94 bits or more). - */ - if (mw31num < 4 || (mw62num << 2) > twlen) { - /* - * We assume here that we can split an aligned uint64_t - * into two properly aligned uint32_t. Since both types - * are supposed to have an exact width with no padding, - * then this property must hold. - */ - size_t txlen; - - txlen = mw31num + 1; - if (twlen < txlen) { - return 0; - } - br_i31_modpow(x31, e, elen, m31, m0i31, - (uint32_t *)tmp, (uint32_t *)tmp + txlen); - return 1; - } - - /* - * Convert x to Montgomery representation: this means that - * we replace x with x*2^z mod m, where z is the smallest multiple - * of the word size such that 2^z >= m. We want to reuse the 31-bit - * functions here (for constant-time operation), but we need z - * for a 62-bit word size. - */ - for (u = 0; u < mw62num; u ++) { - br_i31_muladd_small(x31, 0, m31); - br_i31_muladd_small(x31, 0, m31); - } - - /* - * Assemble operands into arrays of 62-bit words. Note that - * all the arrays of 62-bit words that we will handle here - * are without any leading size word. - * - * We also adjust tmp and twlen to account for the words used - * for these extra arrays. - */ - m = tmp; - x = tmp + mw62num; - tmp += (mw62num << 1); - twlen -= (mw62num << 1); - for (u = 0; u < mw31num; u += 2) { - size_t v; - - v = u >> 1; - if ((u + 1) == mw31num) { - m[v] = (uint64_t)m31[u + 1]; - x[v] = (uint64_t)x31[u + 1]; - } else { - m[v] = (uint64_t)m31[u + 1] - + ((uint64_t)m31[u + 2] << 31); - x[v] = (uint64_t)x31[u + 1] - + ((uint64_t)x31[u + 2] << 31); - } - } - - /* - * Compute window size. We support windows up to 5 bits; for a - * window of size k bits, we need 2^k+1 temporaries (for k = 1, - * we use special code that uses only 2 temporaries). - */ - for (win_len = 5; win_len > 1; win_len --) { - if ((((uint32_t)1 << win_len) + 1) * mw62num <= twlen) { - break; - } - } - - t1 = tmp; - t2 = tmp + mw62num; - - /* - * Compute m0i, which is equal to -(1/m0) mod 2^62. We were - * provided with m0i31, which already fulfills this property - * modulo 2^31; the single expression below is then sufficient. - */ - m0i = (uint64_t)m0i31; - m0i = MUL62_lo(m0i, (uint64_t)2 + MUL62_lo(m0i, m[0])); - - /* - * Compute window contents. If the window has size one bit only, - * then t2 is set to x; otherwise, t2[0] is left untouched, and - * t2[k] is set to x^k (for k >= 1). - */ - if (win_len == 1) { - memcpy(t2, x, mw62num * sizeof *x); - } else { - uint64_t *base; - - memcpy(t2 + mw62num, x, mw62num * sizeof *x); - base = t2 + mw62num; - for (u = 2; u < ((unsigned)1 << win_len); u ++) { - montymul(base + mw62num, base, x, m, mw62num, m0i); - base += mw62num; - } - } - - /* - * Set x to 1, in Montgomery representation. We again use the - * 31-bit code. - */ - br_i31_zero(x31, m31[0]); - x31[(m31[0] + 31) >> 5] = 1; - br_i31_muladd_small(x31, 0, m31); - if (mw31num & 1) { - br_i31_muladd_small(x31, 0, m31); - } - for (u = 0; u < mw31num; u += 2) { - size_t v; - - v = u >> 1; - if ((u + 1) == mw31num) { - x[v] = (uint64_t)x31[u + 1]; - } else { - x[v] = (uint64_t)x31[u + 1] - + ((uint64_t)x31[u + 2] << 31); - } - } - - /* - * We process bits from most to least significant. At each - * loop iteration, we have acc_len bits in acc. - */ - acc = 0; - acc_len = 0; - while (acc_len > 0 || elen > 0) { - int i, k; - uint32_t bits; - uint64_t mask1, mask2; - - /* - * Get the next bits. - */ - k = win_len; - if (acc_len < win_len) { - if (elen > 0) { - acc = (acc << 8) | *e ++; - elen --; - acc_len += 8; - } else { - k = acc_len; - } - } - bits = (acc >> (acc_len - k)) & (((uint32_t)1 << k) - 1); - acc_len -= k; - - /* - * We could get exactly k bits. Compute k squarings. - */ - for (i = 0; i < k; i ++) { - montymul(t1, x, x, m, mw62num, m0i); - memcpy(x, t1, mw62num * sizeof *x); - } - - /* - * Window lookup: we want to set t2 to the window - * lookup value, assuming the bits are non-zero. If - * the window length is 1 bit only, then t2 is - * already set; otherwise, we do a constant-time lookup. - */ - if (win_len > 1) { - uint64_t *base; - - memset(t2, 0, mw62num * sizeof *t2); - base = t2 + mw62num; - for (u = 1; u < ((uint32_t)1 << k); u ++) { - uint64_t mask; - size_t v; - - mask = -(uint64_t)EQ(u, bits); - for (v = 0; v < mw62num; v ++) { - t2[v] |= mask & base[v]; - } - base += mw62num; - } - } - - /* - * Multiply with the looked-up value. We keep the product - * only if the exponent bits are not all-zero. - */ - montymul(t1, x, t2, m, mw62num, m0i); - mask1 = -(uint64_t)EQ(bits, 0); - mask2 = ~mask1; - for (u = 0; u < mw62num; u ++) { - x[u] = (mask1 & x[u]) | (mask2 & t1[u]); - } - } - - /* - * Convert back from Montgomery representation. - */ - frommonty(x, m, mw62num, m0i); - - /* - * Convert result into 31-bit words. - */ - for (u = 0; u < mw31num; u += 2) { - uint64_t zw; - - zw = x[u >> 1]; - x31[u + 1] = (uint32_t)zw & 0x7FFFFFFF; - if ((u + 1) < mw31num) { - x31[u + 2] = (uint32_t)(zw >> 31); - } - } - return 1; -} - -#else - -/* see inner.h */ -uint32_t -br_i62_modpow_opt(uint32_t *x31, const unsigned char *e, size_t elen, - const uint32_t *m31, uint32_t m0i31, uint64_t *tmp, size_t twlen) -{ - size_t mwlen; - - mwlen = (m31[0] + 63) >> 5; - if (twlen < mwlen) { - return 0; - } - return br_i31_modpow_opt(x31, e, elen, m31, m0i31, - (uint32_t *)tmp, twlen << 1); -} - -#endif - -/* see inner.h */ -uint32_t -br_i62_modpow_opt_as_i31(uint32_t *x31, const unsigned char *e, size_t elen, - const uint32_t *m31, uint32_t m0i31, uint32_t *tmp, size_t twlen) -{ - /* - * As documented, this function expects the 'tmp' argument to be - * 64-bit aligned. This is OK since this function is internal (it - * is not part of BearSSL's public API). - */ - return br_i62_modpow_opt(x31, e, elen, m31, m0i31, - (uint64_t *)tmp, twlen >> 1); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/inner.h b/src/tls/bearssl/inner.h deleted file mode 100644 index a73fa54eb..000000000 --- a/src/tls/bearssl/inner.h +++ /dev/null @@ -1,2532 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef INNER_H__ -#define INNER_H__ - -#include -#include - -#include "config.h" -#include "bearssl.h" - -/* - * On MSVC, disable the warning about applying unary minus on an - * unsigned type: it is standard, we do it all the time, and for - * good reasons. - */ -#if _MSC_VER -#pragma warning( disable : 4146 ) -#endif - -/* - * Maximum size for a RSA modulus (in bits). Allocated stack buffers - * depend on that size, so this value should be kept small. Currently, - * 2048-bit RSA keys offer adequate security, and should still do so for - * the next few decades; however, a number of widespread PKI have - * already set their root keys to RSA-4096, so we should be able to - * process such keys. - * - * This value MUST be a multiple of 64. This value MUST NOT exceed 47666 - * (some computations in RSA key generation rely on the factor size being - * no more than 23833 bits). RSA key sizes beyond 3072 bits don't make a - * lot of sense anyway. - */ -#define BR_MAX_RSA_SIZE 4096 - -/* - * Minimum size for a RSA modulus (in bits); this value is used only to - * filter out invalid parameters for key pair generation. Normally, - * applications should not use RSA keys smaller than 2048 bits; but some - * specific cases might need shorter keys, for legacy or research - * purposes. - */ -#define BR_MIN_RSA_SIZE 512 - -/* - * Maximum size for a RSA factor (in bits). This is for RSA private-key - * operations. Default is to support factors up to a bit more than half - * the maximum modulus size. - * - * This value MUST be a multiple of 32. - */ -#define BR_MAX_RSA_FACTOR ((BR_MAX_RSA_SIZE + 64) >> 1) - -/* - * Maximum size for an EC curve (modulus or order), in bits. Size of - * stack buffers depends on that parameter. This size MUST be a multiple - * of 8 (so that decoding an integer with that many bytes does not - * overflow). - */ -#define BR_MAX_EC_SIZE 528 - -/* - * Some macros to recognize the current architecture. Right now, we are - * interested into automatically recognizing architecture with efficient - * 64-bit types so that we may automatically use implementations that - * use 64-bit registers in that case. Future versions may detect, e.g., - * availability of SSE2 intrinsics. - * - * If 'unsigned long' is a 64-bit type, then we assume that 64-bit types - * are efficient. Otherwise, we rely on macros that depend on compiler, - * OS and architecture. In any case, failure to detect the architecture - * as 64-bit means that the 32-bit code will be used, and that code - * works also on 64-bit architectures (the 64-bit code may simply be - * more efficient). - * - * The test on 'unsigned long' should already catch most cases, the one - * notable exception being Windows code where 'unsigned long' is kept to - * 32-bit for compatibility with all the legacy code that liberally uses - * the 'DWORD' type for 32-bit values. - * - * Macro names are taken from: http://nadeausoftware.com/articles/2012/02/c_c_tip_how_detect_processor_type_using_compiler_predefined_macros - */ -#ifndef BR_64 -#if ((ULONG_MAX >> 31) >> 31) == 3 -#define BR_64 1 -#elif defined(__ia64) || defined(__itanium__) || defined(_M_IA64) -#define BR_64 1 -#elif defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) \ - || defined(__64BIT__) || defined(_LP64) || defined(__LP64__) -#define BR_64 1 -#elif defined(__sparc64__) -#define BR_64 1 -#elif defined(__x86_64__) || defined(_M_X64) -#define BR_64 1 -#endif -#endif - -/* - * Set BR_LOMUL on platforms where it makes sense. - */ -#ifndef BR_LOMUL -#if BR_ARMEL_CORTEXM_GCC -#define BR_LOMUL 1 -#endif -#endif - -/* - * Architecture detection. - */ -#ifndef BR_i386 -#if __i386__ || _M_IX86 -#define BR_i386 1 -#endif -#endif - -#ifndef BR_amd64 -#if __x86_64__ || _M_X64 -#define BR_amd64 1 -#endif -#endif - -/* - * Compiler brand and version. - * - * Implementations that use intrinsics need to detect the compiler type - * and version because some specific actions may be needed to activate - * the corresponding opcodes, both for header inclusion, and when using - * them in a function. - * - * BR_GCC, BR_CLANG and BR_MSC will be set to 1 for, respectively, GCC, - * Clang and MS Visual C. For each of them, sub-macros will be defined - * for versions; each sub-macro is set whenever the compiler version is - * at least as recent as the one corresponding to the macro. - */ - -/* - * GCC thresholds are on versions 4.4 to 4.9 and 5.0. - */ -#ifndef BR_GCC -#if __GNUC__ && !__clang__ -#define BR_GCC 1 - -#if __GNUC__ > 4 -#define BR_GCC_5_0 1 -#elif __GNUC__ == 4 && __GNUC_MINOR__ >= 9 -#define BR_GCC_4_9 1 -#elif __GNUC__ == 4 && __GNUC_MINOR__ >= 8 -#define BR_GCC_4_8 1 -#elif __GNUC__ == 4 && __GNUC_MINOR__ >= 7 -#define BR_GCC_4_7 1 -#elif __GNUC__ == 4 && __GNUC_MINOR__ >= 6 -#define BR_GCC_4_6 1 -#elif __GNUC__ == 4 && __GNUC_MINOR__ >= 5 -#define BR_GCC_4_5 1 -#elif __GNUC__ == 4 && __GNUC_MINOR__ >= 4 -#define BR_GCC_4_4 1 -#endif - -#if BR_GCC_5_0 -#define BR_GCC_4_9 1 -#endif -#if BR_GCC_4_9 -#define BR_GCC_4_8 1 -#endif -#if BR_GCC_4_8 -#define BR_GCC_4_7 1 -#endif -#if BR_GCC_4_7 -#define BR_GCC_4_6 1 -#endif -#if BR_GCC_4_6 -#define BR_GCC_4_5 1 -#endif -#if BR_GCC_4_5 -#define BR_GCC_4_4 1 -#endif - -#endif -#endif - -/* - * Clang thresholds are on versions 3.7.0 and 3.8.0. - */ -#ifndef BR_CLANG -#if __clang__ -#define BR_CLANG 1 - -#if __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 8) -#define BR_CLANG_3_8 1 -#elif __clang_major__ == 3 && __clang_minor__ >= 7 -#define BR_CLANG_3_7 1 -#endif - -#if BR_CLANG_3_8 -#define BR_CLANG_3_7 1 -#endif - -#endif -#endif - -/* - * MS Visual C thresholds are on Visual Studio 2005 to 2015. - */ -#ifndef BR_MSC -#if _MSC_VER -#define BR_MSC 1 - -#if _MSC_VER >= 1900 -#define BR_MSC_2015 1 -#elif _MSC_VER >= 1800 -#define BR_MSC_2013 1 -#elif _MSC_VER >= 1700 -#define BR_MSC_2012 1 -#elif _MSC_VER >= 1600 -#define BR_MSC_2010 1 -#elif _MSC_VER >= 1500 -#define BR_MSC_2008 1 -#elif _MSC_VER >= 1400 -#define BR_MSC_2005 1 -#endif - -#if BR_MSC_2015 -#define BR_MSC_2013 1 -#endif -#if BR_MSC_2013 -#define BR_MSC_2012 1 -#endif -#if BR_MSC_2012 -#define BR_MSC_2010 1 -#endif -#if BR_MSC_2010 -#define BR_MSC_2008 1 -#endif -#if BR_MSC_2008 -#define BR_MSC_2005 1 -#endif - -#endif -#endif - -/* - * GCC 4.4+ and Clang 3.7+ allow tagging specific functions with a - * 'target' attribute that activates support for specific opcodes. - */ -#if BR_GCC_4_4 || BR_CLANG_3_7 -#define BR_TARGET(x) __attribute__((target(x))) -#else -#define BR_TARGET(x) -#endif - -/* - * AES-NI intrinsics are available on x86 (32-bit and 64-bit) with - * GCC 4.8+, Clang 3.7+ and MSC 2012+. - */ -#ifndef BR_AES_X86NI -#if (BR_i386 || BR_amd64) && (BR_GCC_4_8 || BR_CLANG_3_7 || BR_MSC_2012) -#define BR_AES_X86NI 1 -#endif -#endif - -/* - * SSE2 intrinsics are available on x86 (32-bit and 64-bit) with - * GCC 4.4+, Clang 3.7+ and MSC 2005+. - */ -#ifndef BR_SSE2 -#if (BR_i386 || BR_amd64) && (BR_GCC_4_4 || BR_CLANG_3_7 || BR_MSC_2005) -#define BR_SSE2 1 -#endif -#endif - -/* - * RDRAND intrinsics are available on x86 (32-bit and 64-bit) with - * GCC 4.6+, Clang 3.7+ and MSC 2012+. - */ -#ifndef BR_RDRAND -#if (BR_i386 || BR_amd64) && (BR_GCC_4_6 || BR_CLANG_3_7 || BR_MSC_2012) -#define BR_RDRAND 1 -#endif -#endif - -/* - * Determine type of OS for random number generation. Macro names and - * values are documented on: - * https://sourceforge.net/p/predef/wiki/OperatingSystems/ - * - * TODO: enrich the list of detected system. Also add detection for - * alternate system calls like getentropy(), which are usually - * preferable when available. - */ - -#ifndef BR_USE_URANDOM -#if defined _AIX \ - || defined __ANDROID__ \ - || defined __FreeBSD__ \ - || defined __NetBSD__ \ - || defined __OpenBSD__ \ - || defined __DragonFly__ \ - || defined __linux__ \ - || (defined __sun && (defined __SVR4 || defined __svr4__)) \ - || (defined __APPLE__ && defined __MACH__) -#define BR_USE_URANDOM 1 -#endif -#endif - -#ifndef BR_USE_WIN32_RAND -#if defined _WIN32 || defined _WIN64 -#define BR_USE_WIN32_RAND 1 -#endif -#endif - -/* - * POWER8 crypto support. We rely on compiler macros for the - * architecture, since we do not have a reliable, simple way to detect - * the required support at runtime (we could try running an opcode, and - * trapping the exception or signal on illegal instruction, but this - * induces some non-trivial OS dependencies that we would prefer to - * avoid if possible). - */ -#ifndef BR_POWER8 -#if __GNUC__ && ((_ARCH_PWR8 || _ARCH_PPC) && __CRYPTO__) -#define BR_POWER8 1 -#endif -#endif - -/* - * Detect endinanness on POWER8. - */ -#if BR_POWER8 -#if defined BR_POWER8_LE -#undef BR_POWER8_BE -#if BR_POWER8_LE -#define BR_POWER8_BE 0 -#else -#define BR_POWER8_BE 1 -#endif -#elif defined BR_POWER8_BE -#undef BR_POWER8_LE -#if BR_POWER8_BE -#define BR_POWER8_LE 0 -#else -#define BR_POWER8_LE 1 -#endif -#else -#if __LITTLE_ENDIAN__ -#define BR_POWER8_LE 1 -#define BR_POWER8_BE 0 -#else -#define BR_POWER8_LE 0 -#define BR_POWER8_BE 1 -#endif -#endif -#endif - -/* - * Detect support for 128-bit integers. - */ -#if !defined BR_INT128 && !defined BR_UMUL128 -#ifdef __SIZEOF_INT128__ -#define BR_INT128 1 -#elif _M_X64 -#define BR_UMUL128 1 -#endif -#endif - -/* - * Detect support for unaligned accesses with known endianness. - * - * x86 (both 32-bit and 64-bit) is little-endian and allows unaligned - * accesses. - * - * POWER/PowerPC allows unaligned accesses when big-endian. POWER8 and - * later also allow unaligned accesses when little-endian. - */ -#if !defined BR_LE_UNALIGNED && !defined BR_BE_UNALIGNED - -#if __i386 || __i386__ || __x86_64__ || _M_IX86 || _M_X64 -#define BR_LE_UNALIGNED 1 -#elif BR_POWER8_BE -#define BR_BE_UNALIGNED 1 -#elif BR_POWER8_LE -#define BR_LE_UNALIGNED 1 -#elif (__powerpc__ || __powerpc64__ || _M_PPC || _ARCH_PPC || _ARCH_PPC64) \ - && __BIG_ENDIAN__ -#define BR_BE_UNALIGNED 1 -#endif - -#endif - -/* - * Detect support for an OS-provided time source. - */ - -#ifndef BR_USE_UNIX_TIME -#if defined __unix__ || defined __linux__ \ - || defined _POSIX_SOURCE || defined _POSIX_C_SOURCE \ - || (defined __APPLE__ && defined __MACH__) -#define BR_USE_UNIX_TIME 1 -#endif -#endif - -#ifndef BR_USE_WIN32_TIME -#if defined _WIN32 || defined _WIN64 -#define BR_USE_WIN32_TIME 1 -#endif -#endif - -/* ==================================================================== */ -/* - * Encoding/decoding functions. - * - * 32-bit and 64-bit decoding, both little-endian and big-endian, is - * implemented with the inline functions below. - * - * When allowed by some compile-time options (autodetected or provided), - * optimised code is used, to perform direct memory access when the - * underlying architecture supports it, both for endianness and - * alignment. This, however, may trigger strict aliasing issues; the - * code below uses unions to perform (supposedly) safe type punning. - * Since the C aliasing rules are relatively complex and were amended, - * or at least re-explained with different phrasing, in all successive - * versions of the C standard, it is always a bit risky to bet that any - * specific version of a C compiler got it right, for some notion of - * "right". - */ - -typedef union { - uint16_t u; - unsigned char b[sizeof(uint16_t)]; -} br_union_u16; - -typedef union { - uint32_t u; - unsigned char b[sizeof(uint32_t)]; -} br_union_u32; - -typedef union { - uint64_t u; - unsigned char b[sizeof(uint64_t)]; -} br_union_u64; - -static inline void -br_enc16le(void *dst, unsigned x) -{ -#if BR_LE_UNALIGNED - ((br_union_u16 *)dst)->u = x; -#else - unsigned char *buf; - - buf = dst; - buf[0] = (unsigned char)x; - buf[1] = (unsigned char)(x >> 8); -#endif -} - -static inline void -br_enc16be(void *dst, unsigned x) -{ -#if BR_BE_UNALIGNED - ((br_union_u16 *)dst)->u = x; -#else - unsigned char *buf; - - buf = dst; - buf[0] = (unsigned char)(x >> 8); - buf[1] = (unsigned char)x; -#endif -} - -static inline unsigned -br_dec16le(const void *src) -{ -#if BR_LE_UNALIGNED - return ((const br_union_u16 *)src)->u; -#else - const unsigned char *buf; - - buf = src; - return (unsigned)buf[0] | ((unsigned)buf[1] << 8); -#endif -} - -static inline unsigned -br_dec16be(const void *src) -{ -#if BR_BE_UNALIGNED - return ((const br_union_u16 *)src)->u; -#else - const unsigned char *buf; - - buf = src; - return ((unsigned)buf[0] << 8) | (unsigned)buf[1]; -#endif -} - -static inline void -br_enc32le(void *dst, uint32_t x) -{ -#if BR_LE_UNALIGNED - ((br_union_u32 *)dst)->u = x; -#else - unsigned char *buf; - - buf = dst; - buf[0] = (unsigned char)x; - buf[1] = (unsigned char)(x >> 8); - buf[2] = (unsigned char)(x >> 16); - buf[3] = (unsigned char)(x >> 24); -#endif -} - -static inline void -br_enc32be(void *dst, uint32_t x) -{ -#if BR_BE_UNALIGNED - ((br_union_u32 *)dst)->u = x; -#else - unsigned char *buf; - - buf = dst; - buf[0] = (unsigned char)(x >> 24); - buf[1] = (unsigned char)(x >> 16); - buf[2] = (unsigned char)(x >> 8); - buf[3] = (unsigned char)x; -#endif -} - -static inline uint32_t -br_dec32le(const void *src) -{ -#if BR_LE_UNALIGNED - return ((const br_union_u32 *)src)->u; -#else - const unsigned char *buf; - - buf = src; - return (uint32_t)buf[0] - | ((uint32_t)buf[1] << 8) - | ((uint32_t)buf[2] << 16) - | ((uint32_t)buf[3] << 24); -#endif -} - -static inline uint32_t -br_dec32be(const void *src) -{ -#if BR_BE_UNALIGNED - return ((const br_union_u32 *)src)->u; -#else - const unsigned char *buf; - - buf = src; - return ((uint32_t)buf[0] << 24) - | ((uint32_t)buf[1] << 16) - | ((uint32_t)buf[2] << 8) - | (uint32_t)buf[3]; -#endif -} - -static inline void -br_enc64le(void *dst, uint64_t x) -{ -#if BR_LE_UNALIGNED - ((br_union_u64 *)dst)->u = x; -#else - unsigned char *buf; - - buf = dst; - br_enc32le(buf, (uint32_t)x); - br_enc32le(buf + 4, (uint32_t)(x >> 32)); -#endif -} - -static inline void -br_enc64be(void *dst, uint64_t x) -{ -#if BR_BE_UNALIGNED - ((br_union_u64 *)dst)->u = x; -#else - unsigned char *buf; - - buf = dst; - br_enc32be(buf, (uint32_t)(x >> 32)); - br_enc32be(buf + 4, (uint32_t)x); -#endif -} - -static inline uint64_t -br_dec64le(const void *src) -{ -#if BR_LE_UNALIGNED - return ((const br_union_u64 *)src)->u; -#else - const unsigned char *buf; - - buf = src; - return (uint64_t)br_dec32le(buf) - | ((uint64_t)br_dec32le(buf + 4) << 32); -#endif -} - -static inline uint64_t -br_dec64be(const void *src) -{ -#if BR_BE_UNALIGNED - return ((const br_union_u64 *)src)->u; -#else - const unsigned char *buf; - - buf = src; - return ((uint64_t)br_dec32be(buf) << 32) - | (uint64_t)br_dec32be(buf + 4); -#endif -} - -/* - * Range decoding and encoding (for several successive values). - */ -void br_range_dec16le(uint16_t *v, size_t num, const void *src); -void br_range_dec16be(uint16_t *v, size_t num, const void *src); -void br_range_enc16le(void *dst, const uint16_t *v, size_t num); -void br_range_enc16be(void *dst, const uint16_t *v, size_t num); - -void br_range_dec32le(uint32_t *v, size_t num, const void *src); -void br_range_dec32be(uint32_t *v, size_t num, const void *src); -void br_range_enc32le(void *dst, const uint32_t *v, size_t num); -void br_range_enc32be(void *dst, const uint32_t *v, size_t num); - -void br_range_dec64le(uint64_t *v, size_t num, const void *src); -void br_range_dec64be(uint64_t *v, size_t num, const void *src); -void br_range_enc64le(void *dst, const uint64_t *v, size_t num); -void br_range_enc64be(void *dst, const uint64_t *v, size_t num); - -/* - * Byte-swap a 32-bit integer. - */ -static inline uint32_t -br_swap32(uint32_t x) -{ - x = ((x & (uint32_t)0x00FF00FF) << 8) - | ((x >> 8) & (uint32_t)0x00FF00FF); - return (x << 16) | (x >> 16); -} - -/* ==================================================================== */ -/* - * Support code for hash functions. - */ - -/* - * IV for MD5, SHA-1, SHA-224 and SHA-256. - */ -extern const uint32_t br_md5_IV[]; -extern const uint32_t br_sha1_IV[]; -extern const uint32_t br_sha224_IV[]; -extern const uint32_t br_sha256_IV[]; - -/* - * Round functions for MD5, SHA-1, SHA-224 and SHA-256 (SHA-224 and - * SHA-256 use the same round function). - */ -void br_md5_round(const unsigned char *buf, uint32_t *val); -void br_sha1_round(const unsigned char *buf, uint32_t *val); -void br_sha2small_round(const unsigned char *buf, uint32_t *val); - -/* - * The core function for the TLS PRF. It computes - * P_hash(secret, label + seed), and XORs the result into the dst buffer. - */ -void br_tls_phash(void *dst, size_t len, - const br_hash_class *dig, - const void *secret, size_t secret_len, const char *label, - size_t seed_num, const br_tls_prf_seed_chunk *seed); - -/* - * Copy all configured hash implementations from a multihash context - * to another. - */ -static inline void -br_multihash_copyimpl(br_multihash_context *dst, - const br_multihash_context *src) -{ - memcpy((void *)dst->impl, src->impl, sizeof src->impl); -} - -/* ==================================================================== */ -/* - * Constant-time primitives. These functions manipulate 32-bit values in - * order to provide constant-time comparisons and multiplexers. - * - * Boolean values (the "ctl" bits) MUST have value 0 or 1. - * - * Implementation notes: - * ===================== - * - * The uintN_t types are unsigned and with width exactly N bits; the C - * standard guarantees that computations are performed modulo 2^N, and - * there can be no overflow. Negation (unary '-') works on unsigned types - * as well. - * - * The intN_t types are guaranteed to have width exactly N bits, with no - * padding bit, and using two's complement representation. Casting - * intN_t to uintN_t really is conversion modulo 2^N. Beware that intN_t - * types, being signed, trigger implementation-defined behaviour on - * overflow (including raising some signal): with GCC, while modular - * arithmetic is usually applied, the optimizer may assume that - * overflows don't occur (unless the -fwrapv command-line option is - * added); Clang has the additional -ftrapv option to explicitly trap on - * integer overflow or underflow. - */ - -/* - * Negate a boolean. - */ -static inline uint32_t -NOT(uint32_t ctl) -{ - return ctl ^ 1; -} - -/* - * Multiplexer: returns x if ctl == 1, y if ctl == 0. - */ -static inline uint32_t -MUX(uint32_t ctl, uint32_t x, uint32_t y) -{ - return y ^ (-ctl & (x ^ y)); -} - -/* - * Equality check: returns 1 if x == y, 0 otherwise. - */ -static inline uint32_t -EQ(uint32_t x, uint32_t y) -{ - uint32_t q; - - q = x ^ y; - return NOT((q | -q) >> 31); -} - -/* - * Inequality check: returns 1 if x != y, 0 otherwise. - */ -static inline uint32_t -NEQ(uint32_t x, uint32_t y) -{ - uint32_t q; - - q = x ^ y; - return (q | -q) >> 31; -} - -/* - * Comparison: returns 1 if x > y, 0 otherwise. - */ -static inline uint32_t -GT(uint32_t x, uint32_t y) -{ - /* - * If both x < 2^31 and x < 2^31, then y-x will have its high - * bit set if x > y, cleared otherwise. - * - * If either x >= 2^31 or y >= 2^31 (but not both), then the - * result is the high bit of x. - * - * If both x >= 2^31 and y >= 2^31, then we can virtually - * subtract 2^31 from both, and we are back to the first case. - * Since (y-2^31)-(x-2^31) = y-x, the subtraction is already - * fine. - */ - uint32_t z; - - z = y - x; - return (z ^ ((x ^ y) & (x ^ z))) >> 31; -} - -/* - * Other comparisons (greater-or-equal, lower-than, lower-or-equal). - */ -#define GE(x, y) NOT(GT(y, x)) -#define LT(x, y) GT(y, x) -#define LE(x, y) NOT(GT(x, y)) - -/* - * General comparison: returned value is -1, 0 or 1, depending on - * whether x is lower than, equal to, or greater than y. - */ -static inline int32_t -CMP(uint32_t x, uint32_t y) -{ - return (int32_t)GT(x, y) | -(int32_t)GT(y, x); -} - -/* - * Returns 1 if x == 0, 0 otherwise. Take care that the operand is signed. - */ -static inline uint32_t -EQ0(int32_t x) -{ - uint32_t q; - - q = (uint32_t)x; - return ~(q | -q) >> 31; -} - -/* - * Returns 1 if x > 0, 0 otherwise. Take care that the operand is signed. - */ -static inline uint32_t -GT0(int32_t x) -{ - /* - * High bit of -x is 0 if x == 0, but 1 if x > 0. - */ - uint32_t q; - - q = (uint32_t)x; - return (~q & -q) >> 31; -} - -/* - * Returns 1 if x >= 0, 0 otherwise. Take care that the operand is signed. - */ -static inline uint32_t -GE0(int32_t x) -{ - return ~(uint32_t)x >> 31; -} - -/* - * Returns 1 if x < 0, 0 otherwise. Take care that the operand is signed. - */ -static inline uint32_t -LT0(int32_t x) -{ - return (uint32_t)x >> 31; -} - -/* - * Returns 1 if x <= 0, 0 otherwise. Take care that the operand is signed. - */ -static inline uint32_t -LE0(int32_t x) -{ - uint32_t q; - - /* - * ~-x has its high bit set if and only if -x is nonnegative (as - * a signed int), i.e. x is in the -(2^31-1) to 0 range. We must - * do an OR with x itself to account for x = -2^31. - */ - q = (uint32_t)x; - return (q | ~-q) >> 31; -} - -/* - * Conditional copy: src[] is copied into dst[] if and only if ctl is 1. - * dst[] and src[] may overlap completely (but not partially). - */ -void br_ccopy(uint32_t ctl, void *dst, const void *src, size_t len); - -#define CCOPY br_ccopy - -/* - * Compute the bit length of a 32-bit integer. Returned value is between 0 - * and 32 (inclusive). - */ -static inline uint32_t -BIT_LENGTH(uint32_t x) -{ - uint32_t k, c; - - k = NEQ(x, 0); - c = GT(x, 0xFFFF); x = MUX(c, x >> 16, x); k += c << 4; - c = GT(x, 0x00FF); x = MUX(c, x >> 8, x); k += c << 3; - c = GT(x, 0x000F); x = MUX(c, x >> 4, x); k += c << 2; - c = GT(x, 0x0003); x = MUX(c, x >> 2, x); k += c << 1; - k += GT(x, 0x0001); - return k; -} - -/* - * Compute the minimum of x and y. - */ -static inline uint32_t -MIN(uint32_t x, uint32_t y) -{ - return MUX(GT(x, y), y, x); -} - -/* - * Compute the maximum of x and y. - */ -static inline uint32_t -MAX(uint32_t x, uint32_t y) -{ - return MUX(GT(x, y), x, y); -} - -/* - * Multiply two 32-bit integers, with a 64-bit result. This default - * implementation assumes that the basic multiplication operator - * yields constant-time code. - */ -#define MUL(x, y) ((uint64_t)(x) * (uint64_t)(y)) - -#if BR_CT_MUL31 - -/* - * Alternate implementation of MUL31, that will be constant-time on some - * (old) platforms where the default MUL31 is not. Unfortunately, it is - * also substantially slower, and yields larger code, on more modern - * platforms, which is why it is deactivated by default. - * - * MUL31_lo() must do some extra work because on some platforms, the - * _signed_ multiplication may return early if the top bits are 1. - * Simply truncating (casting) the output of MUL31() would not be - * sufficient, because the compiler may notice that we keep only the low - * word, and then replace automatically the unsigned multiplication with - * a signed multiplication opcode. - */ -#define MUL31(x, y) ((uint64_t)((x) | (uint32_t)0x80000000) \ - * (uint64_t)((y) | (uint32_t)0x80000000) \ - - ((uint64_t)(x) << 31) - ((uint64_t)(y) << 31) \ - - ((uint64_t)1 << 62)) -static inline uint32_t -MUL31_lo(uint32_t x, uint32_t y) -{ - uint32_t xl, xh; - uint32_t yl, yh; - - xl = (x & 0xFFFF) | (uint32_t)0x80000000; - xh = (x >> 16) | (uint32_t)0x80000000; - yl = (y & 0xFFFF) | (uint32_t)0x80000000; - yh = (y >> 16) | (uint32_t)0x80000000; - return (xl * yl + ((xl * yh + xh * yl) << 16)) & (uint32_t)0x7FFFFFFF; -} - -#else - -/* - * Multiply two 31-bit integers, with a 62-bit result. This default - * implementation assumes that the basic multiplication operator - * yields constant-time code. - * The MUL31_lo() macro returns only the low 31 bits of the product. - */ -#define MUL31(x, y) ((uint64_t)(x) * (uint64_t)(y)) -#define MUL31_lo(x, y) (((uint32_t)(x) * (uint32_t)(y)) & (uint32_t)0x7FFFFFFF) - -#endif - -/* - * Multiply two words together; the sum of the lengths of the two - * operands must not exceed 31 (for instance, one operand may use 16 - * bits if the other fits on 15). If BR_CT_MUL15 is non-zero, then the - * macro will contain some extra operations that help in making the - * operation constant-time on some platforms, where the basic 32-bit - * multiplication is not constant-time. - */ -#if BR_CT_MUL15 -#define MUL15(x, y) (((uint32_t)(x) | (uint32_t)0x80000000) \ - * ((uint32_t)(y) | (uint32_t)0x80000000) \ - & (uint32_t)0x7FFFFFFF) -#else -#define MUL15(x, y) ((uint32_t)(x) * (uint32_t)(y)) -#endif - -/* - * Arithmetic right shift (sign bit is copied). What happens when - * right-shifting a negative value is _implementation-defined_, so it - * does not trigger undefined behaviour, but it is still up to each - * compiler to define (and document) what it does. Most/all compilers - * will do an arithmetic shift, the sign bit being used to fill the - * holes; this is a native operation on the underlying CPU, and it would - * make little sense for the compiler to do otherwise. GCC explicitly - * documents that it follows that convention. - * - * Still, if BR_NO_ARITH_SHIFT is defined (and non-zero), then an - * alternate version will be used, that does not rely on such - * implementation-defined behaviour. Unfortunately, it is also slower - * and yields bigger code, which is why it is deactivated by default. - */ -#if BR_NO_ARITH_SHIFT -#define ARSH(x, n) (((uint32_t)(x) >> (n)) \ - | ((-((uint32_t)(x) >> 31)) << (32 - (n)))) -#else -#define ARSH(x, n) ((*(int32_t *)&(x)) >> (n)) -#endif - -/* - * Constant-time division. The dividend hi:lo is divided by the - * divisor d; the quotient is returned and the remainder is written - * in *r. If hi == d, then the quotient does not fit on 32 bits; - * returned value is thus truncated. If hi > d, returned values are - * indeterminate. - */ -uint32_t br_divrem(uint32_t hi, uint32_t lo, uint32_t d, uint32_t *r); - -/* - * Wrapper for br_divrem(); the remainder is returned, and the quotient - * is discarded. - */ -static inline uint32_t -br_rem(uint32_t hi, uint32_t lo, uint32_t d) -{ - uint32_t r; - - br_divrem(hi, lo, d, &r); - return r; -} - -/* - * Wrapper for br_divrem(); the quotient is returned, and the remainder - * is discarded. - */ -static inline uint32_t -br_div(uint32_t hi, uint32_t lo, uint32_t d) -{ - uint32_t r; - - return br_divrem(hi, lo, d, &r); -} - -/* ==================================================================== */ - -/* - * Integers 'i32' - * -------------- - * - * The 'i32' functions implement computations on big integers using - * an internal representation as an array of 32-bit integers. For - * an array x[]: - * -- x[0] contains the "announced bit length" of the integer - * -- x[1], x[2]... contain the value in little-endian order (x[1] - * contains the least significant 32 bits) - * - * Multiplications rely on the elementary 32x32->64 multiplication. - * - * The announced bit length specifies the number of bits that are - * significant in the subsequent 32-bit words. Unused bits in the - * last (most significant) word are set to 0; subsequent words are - * uninitialized and need not exist at all. - * - * The execution time and memory access patterns of all computations - * depend on the announced bit length, but not on the actual word - * values. For modular integers, the announced bit length of any integer - * modulo n is equal to the actual bit length of n; thus, computations - * on modular integers are "constant-time" (only the modulus length may - * leak). - */ - -/* - * Compute the actual bit length of an integer. The argument x should - * point to the first (least significant) value word of the integer. - * The len 'xlen' contains the number of 32-bit words to access. - * - * CT: value or length of x does not leak. - */ -uint32_t br_i32_bit_length(uint32_t *x, size_t xlen); - -/* - * Decode an integer from its big-endian unsigned representation. The - * "true" bit length of the integer is computed, but all words of x[] - * corresponding to the full 'len' bytes of the source are set. - * - * CT: value or length of x does not leak. - */ -void br_i32_decode(uint32_t *x, const void *src, size_t len); - -/* - * Decode an integer from its big-endian unsigned representation. The - * integer MUST be lower than m[]; the announced bit length written in - * x[] will be equal to that of m[]. All 'len' bytes from the source are - * read. - * - * Returned value is 1 if the decode value fits within the modulus, 0 - * otherwise. In the latter case, the x[] buffer will be set to 0 (but - * still with the announced bit length of m[]). - * - * CT: value or length of x does not leak. Memory access pattern depends - * only of 'len' and the announced bit length of m. Whether x fits or - * not does not leak either. - */ -uint32_t br_i32_decode_mod(uint32_t *x, - const void *src, size_t len, const uint32_t *m); - -/* - * Reduce an integer (a[]) modulo another (m[]). The result is written - * in x[] and its announced bit length is set to be equal to that of m[]. - * - * x[] MUST be distinct from a[] and m[]. - * - * CT: only announced bit lengths leak, not values of x, a or m. - */ -void br_i32_reduce(uint32_t *x, const uint32_t *a, const uint32_t *m); - -/* - * Decode an integer from its big-endian unsigned representation, and - * reduce it modulo the provided modulus m[]. The announced bit length - * of the result is set to be equal to that of the modulus. - * - * x[] MUST be distinct from m[]. - */ -void br_i32_decode_reduce(uint32_t *x, - const void *src, size_t len, const uint32_t *m); - -/* - * Encode an integer into its big-endian unsigned representation. The - * output length in bytes is provided (parameter 'len'); if the length - * is too short then the integer is appropriately truncated; if it is - * too long then the extra bytes are set to 0. - */ -void br_i32_encode(void *dst, size_t len, const uint32_t *x); - -/* - * Multiply x[] by 2^32 and then add integer z, modulo m[]. This - * function assumes that x[] and m[] have the same announced bit - * length, and the announced bit length of m[] matches its true - * bit length. - * - * x[] and m[] MUST be distinct arrays. - * - * CT: only the common announced bit length of x and m leaks, not - * the values of x, z or m. - */ -void br_i32_muladd_small(uint32_t *x, uint32_t z, const uint32_t *m); - -/* - * Extract one word from an integer. The offset is counted in bits. - * The word MUST entirely fit within the word elements corresponding - * to the announced bit length of a[]. - */ -static inline uint32_t -br_i32_word(const uint32_t *a, uint32_t off) -{ - size_t u; - unsigned j; - - u = (size_t)(off >> 5) + 1; - j = (unsigned)off & 31; - if (j == 0) { - return a[u]; - } else { - return (a[u] >> j) | (a[u + 1] << (32 - j)); - } -} - -/* - * Test whether an integer is zero. - */ -uint32_t br_i32_iszero(const uint32_t *x); - -/* - * Add b[] to a[] and return the carry (0 or 1). If ctl is 0, then a[] - * is unmodified, but the carry is still computed and returned. The - * arrays a[] and b[] MUST have the same announced bit length. - * - * a[] and b[] MAY be the same array, but partial overlap is not allowed. - */ -uint32_t br_i32_add(uint32_t *a, const uint32_t *b, uint32_t ctl); - -/* - * Subtract b[] from a[] and return the carry (0 or 1). If ctl is 0, - * then a[] is unmodified, but the carry is still computed and returned. - * The arrays a[] and b[] MUST have the same announced bit length. - * - * a[] and b[] MAY be the same array, but partial overlap is not allowed. - */ -uint32_t br_i32_sub(uint32_t *a, const uint32_t *b, uint32_t ctl); - -/* - * Compute d+a*b, result in d. The initial announced bit length of d[] - * MUST match that of a[]. The d[] array MUST be large enough to - * accommodate the full result, plus (possibly) an extra word. The - * resulting announced bit length of d[] will be the sum of the announced - * bit lengths of a[] and b[] (therefore, it may be larger than the actual - * bit length of the numerical result). - * - * a[] and b[] may be the same array. d[] must be disjoint from both a[] - * and b[]. - */ -void br_i32_mulacc(uint32_t *d, const uint32_t *a, const uint32_t *b); - -/* - * Zeroize an integer. The announced bit length is set to the provided - * value, and the corresponding words are set to 0. - */ -static inline void -br_i32_zero(uint32_t *x, uint32_t bit_len) -{ - *x ++ = bit_len; - memset(x, 0, ((bit_len + 31) >> 5) * sizeof *x); -} - -/* - * Compute -(1/x) mod 2^32. If x is even, then this function returns 0. - */ -uint32_t br_i32_ninv32(uint32_t x); - -/* - * Convert a modular integer to Montgomery representation. The integer x[] - * MUST be lower than m[], but with the same announced bit length. - */ -void br_i32_to_monty(uint32_t *x, const uint32_t *m); - -/* - * Convert a modular integer back from Montgomery representation. The - * integer x[] MUST be lower than m[], but with the same announced bit - * length. The "m0i" parameter is equal to -(1/m0) mod 2^32, where m0 is - * the least significant value word of m[] (this works only if m[] is - * an odd integer). - */ -void br_i32_from_monty(uint32_t *x, const uint32_t *m, uint32_t m0i); - -/* - * Compute a modular Montgomery multiplication. d[] is filled with the - * value of x*y/R modulo m[] (where R is the Montgomery factor). The - * array d[] MUST be distinct from x[], y[] and m[]. x[] and y[] MUST be - * numerically lower than m[]. x[] and y[] MAY be the same array. The - * "m0i" parameter is equal to -(1/m0) mod 2^32, where m0 is the least - * significant value word of m[] (this works only if m[] is an odd - * integer). - */ -void br_i32_montymul(uint32_t *d, const uint32_t *x, const uint32_t *y, - const uint32_t *m, uint32_t m0i); - -/* - * Compute a modular exponentiation. x[] MUST be an integer modulo m[] - * (same announced bit length, lower value). m[] MUST be odd. The - * exponent is in big-endian unsigned notation, over 'elen' bytes. The - * "m0i" parameter is equal to -(1/m0) mod 2^32, where m0 is the least - * significant value word of m[] (this works only if m[] is an odd - * integer). The t1[] and t2[] parameters must be temporary arrays, - * each large enough to accommodate an integer with the same size as m[]. - */ -void br_i32_modpow(uint32_t *x, const unsigned char *e, size_t elen, - const uint32_t *m, uint32_t m0i, uint32_t *t1, uint32_t *t2); - -/* ==================================================================== */ - -/* - * Integers 'i31' - * -------------- - * - * The 'i31' functions implement computations on big integers using - * an internal representation as an array of 32-bit integers. For - * an array x[]: - * -- x[0] encodes the array length and the "announced bit length" - * of the integer: namely, if the announced bit length is k, - * then x[0] = ((k / 31) << 5) + (k % 31). - * -- x[1], x[2]... contain the value in little-endian order, 31 - * bits per word (x[1] contains the least significant 31 bits). - * The upper bit of each word is 0. - * - * Multiplications rely on the elementary 32x32->64 multiplication. - * - * The announced bit length specifies the number of bits that are - * significant in the subsequent 32-bit words. Unused bits in the - * last (most significant) word are set to 0; subsequent words are - * uninitialized and need not exist at all. - * - * The execution time and memory access patterns of all computations - * depend on the announced bit length, but not on the actual word - * values. For modular integers, the announced bit length of any integer - * modulo n is equal to the actual bit length of n; thus, computations - * on modular integers are "constant-time" (only the modulus length may - * leak). - */ - -/* - * Test whether an integer is zero. - */ -uint32_t br_i31_iszero(const uint32_t *x); - -/* - * Add b[] to a[] and return the carry (0 or 1). If ctl is 0, then a[] - * is unmodified, but the carry is still computed and returned. The - * arrays a[] and b[] MUST have the same announced bit length. - * - * a[] and b[] MAY be the same array, but partial overlap is not allowed. - */ -uint32_t br_i31_add(uint32_t *a, const uint32_t *b, uint32_t ctl); - -/* - * Subtract b[] from a[] and return the carry (0 or 1). If ctl is 0, - * then a[] is unmodified, but the carry is still computed and returned. - * The arrays a[] and b[] MUST have the same announced bit length. - * - * a[] and b[] MAY be the same array, but partial overlap is not allowed. - */ -uint32_t br_i31_sub(uint32_t *a, const uint32_t *b, uint32_t ctl); - -/* - * Compute the ENCODED actual bit length of an integer. The argument x - * should point to the first (least significant) value word of the - * integer. The len 'xlen' contains the number of 32-bit words to - * access. The upper bit of each value word MUST be 0. - * Returned value is ((k / 31) << 5) + (k % 31) if the bit length is k. - * - * CT: value or length of x does not leak. - */ -uint32_t br_i31_bit_length(uint32_t *x, size_t xlen); - -/* - * Decode an integer from its big-endian unsigned representation. The - * "true" bit length of the integer is computed and set in the encoded - * announced bit length (x[0]), but all words of x[] corresponding to - * the full 'len' bytes of the source are set. - * - * CT: value or length of x does not leak. - */ -void br_i31_decode(uint32_t *x, const void *src, size_t len); - -/* - * Decode an integer from its big-endian unsigned representation. The - * integer MUST be lower than m[]; the (encoded) announced bit length - * written in x[] will be equal to that of m[]. All 'len' bytes from the - * source are read. - * - * Returned value is 1 if the decode value fits within the modulus, 0 - * otherwise. In the latter case, the x[] buffer will be set to 0 (but - * still with the announced bit length of m[]). - * - * CT: value or length of x does not leak. Memory access pattern depends - * only of 'len' and the announced bit length of m. Whether x fits or - * not does not leak either. - */ -uint32_t br_i31_decode_mod(uint32_t *x, - const void *src, size_t len, const uint32_t *m); - -/* - * Zeroize an integer. The announced bit length is set to the provided - * value, and the corresponding words are set to 0. The ENCODED bit length - * is expected here. - */ -static inline void -br_i31_zero(uint32_t *x, uint32_t bit_len) -{ - *x ++ = bit_len; - memset(x, 0, ((bit_len + 31) >> 5) * sizeof *x); -} - -/* - * Right-shift an integer. The shift amount must be lower than 31 - * bits. - */ -void br_i31_rshift(uint32_t *x, int count); - -/* - * Reduce an integer (a[]) modulo another (m[]). The result is written - * in x[] and its announced bit length is set to be equal to that of m[]. - * - * x[] MUST be distinct from a[] and m[]. - * - * CT: only announced bit lengths leak, not values of x, a or m. - */ -void br_i31_reduce(uint32_t *x, const uint32_t *a, const uint32_t *m); - -/* - * Decode an integer from its big-endian unsigned representation, and - * reduce it modulo the provided modulus m[]. The announced bit length - * of the result is set to be equal to that of the modulus. - * - * x[] MUST be distinct from m[]. - */ -void br_i31_decode_reduce(uint32_t *x, - const void *src, size_t len, const uint32_t *m); - -/* - * Multiply x[] by 2^31 and then add integer z, modulo m[]. This - * function assumes that x[] and m[] have the same announced bit - * length, the announced bit length of m[] matches its true - * bit length. - * - * x[] and m[] MUST be distinct arrays. z MUST fit in 31 bits (upper - * bit set to 0). - * - * CT: only the common announced bit length of x and m leaks, not - * the values of x, z or m. - */ -void br_i31_muladd_small(uint32_t *x, uint32_t z, const uint32_t *m); - -/* - * Encode an integer into its big-endian unsigned representation. The - * output length in bytes is provided (parameter 'len'); if the length - * is too short then the integer is appropriately truncated; if it is - * too long then the extra bytes are set to 0. - */ -void br_i31_encode(void *dst, size_t len, const uint32_t *x); - -/* - * Compute -(1/x) mod 2^31. If x is even, then this function returns 0. - */ -uint32_t br_i31_ninv31(uint32_t x); - -/* - * Compute a modular Montgomery multiplication. d[] is filled with the - * value of x*y/R modulo m[] (where R is the Montgomery factor). The - * array d[] MUST be distinct from x[], y[] and m[]. x[] and y[] MUST be - * numerically lower than m[]. x[] and y[] MAY be the same array. The - * "m0i" parameter is equal to -(1/m0) mod 2^31, where m0 is the least - * significant value word of m[] (this works only if m[] is an odd - * integer). - */ -void br_i31_montymul(uint32_t *d, const uint32_t *x, const uint32_t *y, - const uint32_t *m, uint32_t m0i); - -/* - * Convert a modular integer to Montgomery representation. The integer x[] - * MUST be lower than m[], but with the same announced bit length. - */ -void br_i31_to_monty(uint32_t *x, const uint32_t *m); - -/* - * Convert a modular integer back from Montgomery representation. The - * integer x[] MUST be lower than m[], but with the same announced bit - * length. The "m0i" parameter is equal to -(1/m0) mod 2^32, where m0 is - * the least significant value word of m[] (this works only if m[] is - * an odd integer). - */ -void br_i31_from_monty(uint32_t *x, const uint32_t *m, uint32_t m0i); - -/* - * Compute a modular exponentiation. x[] MUST be an integer modulo m[] - * (same announced bit length, lower value). m[] MUST be odd. The - * exponent is in big-endian unsigned notation, over 'elen' bytes. The - * "m0i" parameter is equal to -(1/m0) mod 2^31, where m0 is the least - * significant value word of m[] (this works only if m[] is an odd - * integer). The t1[] and t2[] parameters must be temporary arrays, - * each large enough to accommodate an integer with the same size as m[]. - */ -void br_i31_modpow(uint32_t *x, const unsigned char *e, size_t elen, - const uint32_t *m, uint32_t m0i, uint32_t *t1, uint32_t *t2); - -/* - * Compute a modular exponentiation. x[] MUST be an integer modulo m[] - * (same announced bit length, lower value). m[] MUST be odd. The - * exponent is in big-endian unsigned notation, over 'elen' bytes. The - * "m0i" parameter is equal to -(1/m0) mod 2^31, where m0 is the least - * significant value word of m[] (this works only if m[] is an odd - * integer). The tmp[] array is used for temporaries, and has size - * 'twlen' words; it must be large enough to accommodate at least two - * temporary values with the same size as m[] (including the leading - * "bit length" word). If there is room for more temporaries, then this - * function may use the extra room for window-based optimisation, - * resulting in faster computations. - * - * Returned value is 1 on success, 0 on error. An error is reported if - * the provided tmp[] array is too short. - */ -uint32_t br_i31_modpow_opt(uint32_t *x, const unsigned char *e, size_t elen, - const uint32_t *m, uint32_t m0i, uint32_t *tmp, size_t twlen); - -/* - * Compute d+a*b, result in d. The initial announced bit length of d[] - * MUST match that of a[]. The d[] array MUST be large enough to - * accommodate the full result, plus (possibly) an extra word. The - * resulting announced bit length of d[] will be the sum of the announced - * bit lengths of a[] and b[] (therefore, it may be larger than the actual - * bit length of the numerical result). - * - * a[] and b[] may be the same array. d[] must be disjoint from both a[] - * and b[]. - */ -void br_i31_mulacc(uint32_t *d, const uint32_t *a, const uint32_t *b); - -/* - * Compute x/y mod m, result in x. Values x and y must be between 0 and - * m-1, and have the same announced bit length as m. Modulus m must be - * odd. The "m0i" parameter is equal to -1/m mod 2^31. The array 't' - * must point to a temporary area that can hold at least three integers - * of the size of m. - * - * m may not overlap x and y. x and y may overlap each other (this can - * be useful to test whether a value is invertible modulo m). t must be - * disjoint from all other arrays. - * - * Returned value is 1 on success, 0 otherwise. Success is attained if - * y is invertible modulo m. - */ -uint32_t br_i31_moddiv(uint32_t *x, const uint32_t *y, - const uint32_t *m, uint32_t m0i, uint32_t *t); - -/* ==================================================================== */ - -/* - * FIXME: document "i15" functions. - */ - -static inline void -br_i15_zero(uint16_t *x, uint16_t bit_len) -{ - *x ++ = bit_len; - memset(x, 0, ((bit_len + 15) >> 4) * sizeof *x); -} - -uint32_t br_i15_iszero(const uint16_t *x); - -uint16_t br_i15_ninv15(uint16_t x); - -uint32_t br_i15_add(uint16_t *a, const uint16_t *b, uint32_t ctl); - -uint32_t br_i15_sub(uint16_t *a, const uint16_t *b, uint32_t ctl); - -void br_i15_muladd_small(uint16_t *x, uint16_t z, const uint16_t *m); - -void br_i15_montymul(uint16_t *d, const uint16_t *x, const uint16_t *y, - const uint16_t *m, uint16_t m0i); - -void br_i15_to_monty(uint16_t *x, const uint16_t *m); - -void br_i15_modpow(uint16_t *x, const unsigned char *e, size_t elen, - const uint16_t *m, uint16_t m0i, uint16_t *t1, uint16_t *t2); - -uint32_t br_i15_modpow_opt(uint16_t *x, const unsigned char *e, size_t elen, - const uint16_t *m, uint16_t m0i, uint16_t *tmp, size_t twlen); - -void br_i15_encode(void *dst, size_t len, const uint16_t *x); - -uint32_t br_i15_decode_mod(uint16_t *x, - const void *src, size_t len, const uint16_t *m); - -void br_i15_rshift(uint16_t *x, int count); - -uint32_t br_i15_bit_length(uint16_t *x, size_t xlen); - -void br_i15_decode(uint16_t *x, const void *src, size_t len); - -void br_i15_from_monty(uint16_t *x, const uint16_t *m, uint16_t m0i); - -void br_i15_decode_reduce(uint16_t *x, - const void *src, size_t len, const uint16_t *m); - -void br_i15_reduce(uint16_t *x, const uint16_t *a, const uint16_t *m); - -void br_i15_mulacc(uint16_t *d, const uint16_t *a, const uint16_t *b); - -uint32_t br_i15_moddiv(uint16_t *x, const uint16_t *y, - const uint16_t *m, uint16_t m0i, uint16_t *t); - -/* - * Variant of br_i31_modpow_opt() that internally uses 64x64->128 - * multiplications. It expects the same parameters as br_i31_modpow_opt(), - * except that the temporaries should be 64-bit integers, not 32-bit - * integers. - */ -uint32_t br_i62_modpow_opt(uint32_t *x31, const unsigned char *e, size_t elen, - const uint32_t *m31, uint32_t m0i31, uint64_t *tmp, size_t twlen); - -/* - * Type for a function with the same API as br_i31_modpow_opt() (some - * implementations of this type may have stricter alignment requirements - * on the temporaries). - */ -typedef uint32_t (*br_i31_modpow_opt_type)(uint32_t *x, - const unsigned char *e, size_t elen, - const uint32_t *m, uint32_t m0i, uint32_t *tmp, size_t twlen); - -/* - * Wrapper for br_i62_modpow_opt() that uses the same type as - * br_i31_modpow_opt(); however, it requires its 'tmp' argument to the - * 64-bit aligned. - */ -uint32_t br_i62_modpow_opt_as_i31(uint32_t *x, - const unsigned char *e, size_t elen, - const uint32_t *m, uint32_t m0i, uint32_t *tmp, size_t twlen); - -/* ==================================================================== */ - -static inline size_t -br_digest_size(const br_hash_class *digest_class) -{ - return (size_t)(digest_class->desc >> BR_HASHDESC_OUT_OFF) - & BR_HASHDESC_OUT_MASK; -} - -/* - * Get the output size (in bytes) of a hash function. - */ -size_t br_digest_size_by_ID(int digest_id); - -/* - * Get the OID (encoded OBJECT IDENTIFIER value, without tag and length) - * for a hash function. If digest_id is not a supported digest identifier - * (in particular if it is equal to 0, i.e. br_md5sha1_ID), then NULL is - * returned and *len is set to 0. - */ -const unsigned char *br_digest_OID(int digest_id, size_t *len); - -/* ==================================================================== */ -/* - * DES support functions. - */ - -/* - * Apply DES Initial Permutation. - */ -void br_des_do_IP(uint32_t *xl, uint32_t *xr); - -/* - * Apply DES Final Permutation (inverse of IP). - */ -void br_des_do_invIP(uint32_t *xl, uint32_t *xr); - -/* - * Key schedule unit: for a DES key (8 bytes), compute 16 subkeys. Each - * subkey is two 28-bit words represented as two 32-bit words; the PC-2 - * bit exctration is NOT applied. - */ -void br_des_keysched_unit(uint32_t *skey, const void *key); - -/* - * Reversal of 16 DES sub-keys (for decryption). - */ -void br_des_rev_skey(uint32_t *skey); - -/* - * DES/3DES key schedule for 'des_tab' (encryption direction). Returned - * value is the number of rounds. - */ -unsigned br_des_tab_keysched(uint32_t *skey, const void *key, size_t key_len); - -/* - * DES/3DES key schedule for 'des_ct' (encryption direction). Returned - * value is the number of rounds. - */ -unsigned br_des_ct_keysched(uint32_t *skey, const void *key, size_t key_len); - -/* - * DES/3DES subkey decompression (from the compressed bitsliced subkeys). - */ -void br_des_ct_skey_expand(uint32_t *sk_exp, - unsigned num_rounds, const uint32_t *skey); - -/* - * DES/3DES block encryption/decryption ('des_tab'). - */ -void br_des_tab_process_block(unsigned num_rounds, - const uint32_t *skey, void *block); - -/* - * DES/3DES block encryption/decryption ('des_ct'). - */ -void br_des_ct_process_block(unsigned num_rounds, - const uint32_t *skey, void *block); - -/* ==================================================================== */ -/* - * AES support functions. - */ - -/* - * The AES S-box (256-byte table). - */ -extern const unsigned char br_aes_S[]; - -/* - * AES key schedule. skey[] is filled with n+1 128-bit subkeys, where n - * is the number of rounds (10 to 14, depending on key size). The number - * of rounds is returned. If the key size is invalid (not 16, 24 or 32), - * then 0 is returned. - * - * This implementation uses a 256-byte table and is NOT constant-time. - */ -unsigned br_aes_keysched(uint32_t *skey, const void *key, size_t key_len); - -/* - * AES key schedule for decryption ('aes_big' implementation). - */ -unsigned br_aes_big_keysched_inv(uint32_t *skey, - const void *key, size_t key_len); - -/* - * AES block encryption with the 'aes_big' implementation (fast, but - * not constant-time). This function encrypts a single block "in place". - */ -void br_aes_big_encrypt(unsigned num_rounds, const uint32_t *skey, void *data); - -/* - * AES block decryption with the 'aes_big' implementation (fast, but - * not constant-time). This function decrypts a single block "in place". - */ -void br_aes_big_decrypt(unsigned num_rounds, const uint32_t *skey, void *data); - -/* - * AES block encryption with the 'aes_small' implementation (small, but - * slow and not constant-time). This function encrypts a single block - * "in place". - */ -void br_aes_small_encrypt(unsigned num_rounds, - const uint32_t *skey, void *data); - -/* - * AES block decryption with the 'aes_small' implementation (small, but - * slow and not constant-time). This function decrypts a single block - * "in place". - */ -void br_aes_small_decrypt(unsigned num_rounds, - const uint32_t *skey, void *data); - -/* - * The constant-time implementation is "bitsliced": the 128-bit state is - * split over eight 32-bit words q* in the following way: - * - * -- Input block consists in 16 bytes: - * a00 a10 a20 a30 a01 a11 a21 a31 a02 a12 a22 a32 a03 a13 a23 a33 - * In the terminology of FIPS 197, this is a 4x4 matrix which is read - * column by column. - * - * -- Each byte is split into eight bits which are distributed over the - * eight words, at the same rank. Thus, for a byte x at rank k, bit 0 - * (least significant) of x will be at rank k in q0 (if that bit is b, - * then it contributes "b << k" to the value of q0), bit 1 of x will be - * at rank k in q1, and so on. - * - * -- Ranks given to bits are in "row order" and are either all even, or - * all odd. Two independent AES states are thus interleaved, one using - * the even ranks, the other the odd ranks. Row order means: - * a00 a01 a02 a03 a10 a11 a12 a13 a20 a21 a22 a23 a30 a31 a32 a33 - * - * Converting input bytes from two AES blocks to bitslice representation - * is done in the following way: - * -- Decode first block into the four words q0 q2 q4 q6, in that order, - * using little-endian convention. - * -- Decode second block into the four words q1 q3 q5 q7, in that order, - * using little-endian convention. - * -- Call br_aes_ct_ortho(). - * - * Converting back to bytes is done by using the reverse operations. Note - * that br_aes_ct_ortho() is its own inverse. - */ - -/* - * Perform bytewise orthogonalization of eight 32-bit words. Bytes - * of q0..q7 are spread over all words: for a byte x that occurs - * at rank i in q[j] (byte x uses bits 8*i to 8*i+7 in q[j]), the bit - * of rank k in x (0 <= k <= 7) goes to q[k] at rank 8*i+j. - * - * This operation is an involution. - */ -void br_aes_ct_ortho(uint32_t *q); - -/* - * The AES S-box, as a bitsliced constant-time version. The input array - * consists in eight 32-bit words; 32 S-box instances are computed in - * parallel. Bits 0 to 7 of each S-box input (bit 0 is least significant) - * are spread over the words 0 to 7, at the same rank. - */ -void br_aes_ct_bitslice_Sbox(uint32_t *q); - -/* - * Like br_aes_bitslice_Sbox(), but for the inverse S-box. - */ -void br_aes_ct_bitslice_invSbox(uint32_t *q); - -/* - * Compute AES encryption on bitsliced data. Since input is stored on - * eight 32-bit words, two block encryptions are actually performed - * in parallel. - */ -void br_aes_ct_bitslice_encrypt(unsigned num_rounds, - const uint32_t *skey, uint32_t *q); - -/* - * Compute AES decryption on bitsliced data. Since input is stored on - * eight 32-bit words, two block decryptions are actually performed - * in parallel. - */ -void br_aes_ct_bitslice_decrypt(unsigned num_rounds, - const uint32_t *skey, uint32_t *q); - -/* - * AES key schedule, constant-time version. skey[] is filled with n+1 - * 128-bit subkeys, where n is the number of rounds (10 to 14, depending - * on key size). The number of rounds is returned. If the key size is - * invalid (not 16, 24 or 32), then 0 is returned. - */ -unsigned br_aes_ct_keysched(uint32_t *comp_skey, - const void *key, size_t key_len); - -/* - * Expand AES subkeys as produced by br_aes_ct_keysched(), into - * a larger array suitable for br_aes_ct_bitslice_encrypt() and - * br_aes_ct_bitslice_decrypt(). - */ -void br_aes_ct_skey_expand(uint32_t *skey, - unsigned num_rounds, const uint32_t *comp_skey); - -/* - * For the ct64 implementation, the same bitslicing technique is used, - * but four instances are interleaved. First instance uses bits 0, 4, - * 8, 12,... of each word; second instance uses bits 1, 5, 9, 13,... - * and so on. - */ - -/* - * Perform bytewise orthogonalization of eight 64-bit words. Bytes - * of q0..q7 are spread over all words: for a byte x that occurs - * at rank i in q[j] (byte x uses bits 8*i to 8*i+7 in q[j]), the bit - * of rank k in x (0 <= k <= 7) goes to q[k] at rank 8*i+j. - * - * This operation is an involution. - */ -void br_aes_ct64_ortho(uint64_t *q); - -/* - * Interleave bytes for an AES input block. If input bytes are - * denoted 0123456789ABCDEF, and have been decoded with little-endian - * convention (w[0] contains 0123, with '3' being most significant; - * w[1] contains 4567, and so on), then output word q0 will be - * set to 08192A3B (again little-endian convention) and q1 will - * be set to 4C5D6E7F. - */ -void br_aes_ct64_interleave_in(uint64_t *q0, uint64_t *q1, const uint32_t *w); - -/* - * Perform the opposite of br_aes_ct64_interleave_in(). - */ -void br_aes_ct64_interleave_out(uint32_t *w, uint64_t q0, uint64_t q1); - -/* - * The AES S-box, as a bitsliced constant-time version. The input array - * consists in eight 64-bit words; 64 S-box instances are computed in - * parallel. Bits 0 to 7 of each S-box input (bit 0 is least significant) - * are spread over the words 0 to 7, at the same rank. - */ -void br_aes_ct64_bitslice_Sbox(uint64_t *q); - -/* - * Like br_aes_bitslice_Sbox(), but for the inverse S-box. - */ -void br_aes_ct64_bitslice_invSbox(uint64_t *q); - -/* - * Compute AES encryption on bitsliced data. Since input is stored on - * eight 64-bit words, four block encryptions are actually performed - * in parallel. - */ -void br_aes_ct64_bitslice_encrypt(unsigned num_rounds, - const uint64_t *skey, uint64_t *q); - -/* - * Compute AES decryption on bitsliced data. Since input is stored on - * eight 64-bit words, four block decryptions are actually performed - * in parallel. - */ -void br_aes_ct64_bitslice_decrypt(unsigned num_rounds, - const uint64_t *skey, uint64_t *q); - -/* - * AES key schedule, constant-time version. skey[] is filled with n+1 - * 128-bit subkeys, where n is the number of rounds (10 to 14, depending - * on key size). The number of rounds is returned. If the key size is - * invalid (not 16, 24 or 32), then 0 is returned. - */ -unsigned br_aes_ct64_keysched(uint64_t *comp_skey, - const void *key, size_t key_len); - -/* - * Expand AES subkeys as produced by br_aes_ct64_keysched(), into - * a larger array suitable for br_aes_ct64_bitslice_encrypt() and - * br_aes_ct64_bitslice_decrypt(). - */ -void br_aes_ct64_skey_expand(uint64_t *skey, - unsigned num_rounds, const uint64_t *comp_skey); - -/* - * Test support for AES-NI opcodes. - */ -int br_aes_x86ni_supported(void); - -/* - * AES key schedule, using x86 AES-NI instructions. This yields the - * subkeys in the encryption direction. Number of rounds is returned. - * Key size MUST be 16, 24 or 32 bytes; otherwise, 0 is returned. - */ -unsigned br_aes_x86ni_keysched_enc(unsigned char *skni, - const void *key, size_t len); - -/* - * AES key schedule, using x86 AES-NI instructions. This yields the - * subkeys in the decryption direction. Number of rounds is returned. - * Key size MUST be 16, 24 or 32 bytes; otherwise, 0 is returned. - */ -unsigned br_aes_x86ni_keysched_dec(unsigned char *skni, - const void *key, size_t len); - -/* - * Test support for AES POWER8 opcodes. - */ -int br_aes_pwr8_supported(void); - -/* - * AES key schedule, using POWER8 instructions. This yields the - * subkeys in the encryption direction. Number of rounds is returned. - * Key size MUST be 16, 24 or 32 bytes; otherwise, 0 is returned. - */ -unsigned br_aes_pwr8_keysched(unsigned char *skni, - const void *key, size_t len); - -/* ==================================================================== */ -/* - * RSA. - */ - -/* - * Apply proper PKCS#1 v1.5 padding (for signatures). 'hash_oid' is - * the encoded hash function OID, or NULL. - */ -uint32_t br_rsa_pkcs1_sig_pad(const unsigned char *hash_oid, - const unsigned char *hash, size_t hash_len, - uint32_t n_bitlen, unsigned char *x); - -/* - * Check PKCS#1 v1.5 padding (for signatures). 'hash_oid' is the encoded - * hash function OID, or NULL. The provided 'sig' value is _after_ the - * modular exponentiation, i.e. it should be the padded hash. On - * success, the hashed message is extracted. - */ -uint32_t br_rsa_pkcs1_sig_unpad(const unsigned char *sig, size_t sig_len, - const unsigned char *hash_oid, size_t hash_len, - unsigned char *hash_out); - -/* - * Apply OAEP padding. Returned value is the actual padded string length, - * or zero on error. - */ -size_t br_rsa_oaep_pad(const br_prng_class **rnd, const br_hash_class *dig, - const void *label, size_t label_len, const br_rsa_public_key *pk, - void *dst, size_t dst_nax_len, const void *src, size_t src_len); - -/* - * Unravel and check OAEP padding. If the padding is correct, then 1 is - * returned, '*len' is adjusted to the length of the message, and the - * data is moved to the start of the 'data' buffer. If the padding is - * incorrect, then 0 is returned and '*len' is untouched. Either way, - * the complete buffer contents are altered. - */ -uint32_t br_rsa_oaep_unpad(const br_hash_class *dig, - const void *label, size_t label_len, void *data, size_t *len); - -/* - * Compute MGF1 for a given seed, and XOR the output into the provided - * buffer. - */ -void br_mgf1_xor(void *data, size_t len, - const br_hash_class *dig, const void *seed, size_t seed_len); - -/* - * Inner function for RSA key generation; used by the "i31" and "i62" - * implementations. - */ -uint32_t br_rsa_i31_keygen_inner(const br_prng_class **rng, - br_rsa_private_key *sk, void *kbuf_priv, - br_rsa_public_key *pk, void *kbuf_pub, - unsigned size, uint32_t pubexp, br_i31_modpow_opt_type mp31); - -/* ==================================================================== */ -/* - * Elliptic curves. - */ - -/* - * Type for generic EC parameters: curve order (unsigned big-endian - * encoding) and encoded conventional generator. - */ -typedef struct { - int curve; - const unsigned char *order; - size_t order_len; - const unsigned char *generator; - size_t generator_len; -} br_ec_curve_def; - -extern const br_ec_curve_def br_secp256r1; -extern const br_ec_curve_def br_secp384r1; -extern const br_ec_curve_def br_secp521r1; - -/* - * For Curve25519, the advertised "order" really is 2^255-1, since the - * point multipliction function really works over arbitrary 255-bit - * scalars. This value is only meant as a hint for ECDH key generation; - * only ECDSA uses the exact curve order, and ECDSA is not used with - * that specific curve. - */ -extern const br_ec_curve_def br_curve25519; - -/* - * Decode some bytes as an i31 integer, with truncation (corresponding - * to the 'bits2int' operation in RFC 6979). The target ENCODED bit - * length is provided as last parameter. The resulting value will have - * this declared bit length, and consists the big-endian unsigned decoding - * of exactly that many bits in the source (capped at the source length). - */ -void br_ecdsa_i31_bits2int(uint32_t *x, - const void *src, size_t len, uint32_t ebitlen); - -/* - * Decode some bytes as an i15 integer, with truncation (corresponding - * to the 'bits2int' operation in RFC 6979). The target ENCODED bit - * length is provided as last parameter. The resulting value will have - * this declared bit length, and consists the big-endian unsigned decoding - * of exactly that many bits in the source (capped at the source length). - */ -void br_ecdsa_i15_bits2int(uint16_t *x, - const void *src, size_t len, uint32_t ebitlen); - -/* ==================================================================== */ -/* - * ASN.1 support functions. - */ - -/* - * A br_asn1_uint structure contains encoding information about an - * INTEGER nonnegative value: pointer to the integer contents (unsigned - * big-endian representation), length of the integer contents, - * and length of the encoded value. The data shall have minimal length: - * - If the integer value is zero, then 'len' must be zero. - * - If the integer value is not zero, then data[0] must be non-zero. - * - * Under these conditions, 'asn1len' is necessarily equal to either len - * or len+1. - */ -typedef struct { - const unsigned char *data; - size_t len; - size_t asn1len; -} br_asn1_uint; - -/* - * Given an encoded integer (unsigned big-endian, with possible leading - * bytes of value 0), returned the "prepared INTEGER" structure. - */ -br_asn1_uint br_asn1_uint_prepare(const void *xdata, size_t xlen); - -/* - * Encode an ASN.1 length. The length of the encoded length is returned. - * If 'dest' is NULL, then no encoding is performed, but the length of - * the encoded length is still computed and returned. - */ -size_t br_asn1_encode_length(void *dest, size_t len); - -/* - * Convenient macro for computing lengths of lengths. - */ -#define len_of_len(len) br_asn1_encode_length(NULL, len) - -/* - * Encode a (prepared) ASN.1 INTEGER. The encoded length is returned. - * If 'dest' is NULL, then no encoding is performed, but the length of - * the encoded integer is still computed and returned. - */ -size_t br_asn1_encode_uint(void *dest, br_asn1_uint pp); - -/* - * Get the OID that identifies an elliptic curve. Returned value is - * the DER-encoded OID, with the length (always one byte) but without - * the tag. Thus, the first byte of the returned buffer contains the - * number of subsequent bytes in the value. If the curve is not - * recognised, NULL is returned. - */ -const unsigned char *br_get_curve_OID(int curve); - -/* - * Inner function for EC private key encoding. This is equivalent to - * the API function br_encode_ec_raw_der(), except for an extra - * parameter: if 'include_curve_oid' is zero, then the curve OID is - * _not_ included in the output blob (this is for PKCS#8 support). - */ -size_t br_encode_ec_raw_der_inner(void *dest, - const br_ec_private_key *sk, const br_ec_public_key *pk, - int include_curve_oid); - -/* ==================================================================== */ -/* - * SSL/TLS support functions. - */ - -/* - * Record types. - */ -#define BR_SSL_CHANGE_CIPHER_SPEC 20 -#define BR_SSL_ALERT 21 -#define BR_SSL_HANDSHAKE 22 -#define BR_SSL_APPLICATION_DATA 23 - -/* - * Handshake message types. - */ -#define BR_SSL_HELLO_REQUEST 0 -#define BR_SSL_CLIENT_HELLO 1 -#define BR_SSL_SERVER_HELLO 2 -#define BR_SSL_CERTIFICATE 11 -#define BR_SSL_SERVER_KEY_EXCHANGE 12 -#define BR_SSL_CERTIFICATE_REQUEST 13 -#define BR_SSL_SERVER_HELLO_DONE 14 -#define BR_SSL_CERTIFICATE_VERIFY 15 -#define BR_SSL_CLIENT_KEY_EXCHANGE 16 -#define BR_SSL_FINISHED 20 - -/* - * Alert levels. - */ -#define BR_LEVEL_WARNING 1 -#define BR_LEVEL_FATAL 2 - -/* - * Low-level I/O state. - */ -#define BR_IO_FAILED 0 -#define BR_IO_IN 1 -#define BR_IO_OUT 2 -#define BR_IO_INOUT 3 - -/* - * Mark a SSL engine as failed. The provided error code is recorded if - * the engine was not already marked as failed. If 'err' is 0, then the - * engine is marked as closed (without error). - */ -void br_ssl_engine_fail(br_ssl_engine_context *cc, int err); - -/* - * Test whether the engine is closed (normally or as a failure). - */ -static inline int -br_ssl_engine_closed(const br_ssl_engine_context *cc) -{ - return cc->iomode == BR_IO_FAILED; -} - -/* - * Configure a new maximum fragment length. If possible, the maximum - * length for outgoing records is immediately adjusted (if there are - * not already too many buffered bytes for that). - */ -void br_ssl_engine_new_max_frag_len( - br_ssl_engine_context *rc, unsigned max_frag_len); - -/* - * Test whether the current incoming record has been fully received - * or not. This functions returns 0 only if a complete record header - * has been received, but some of the (possibly encrypted) payload - * has not yet been obtained. - */ -int br_ssl_engine_recvrec_finished(const br_ssl_engine_context *rc); - -/* - * Flush the current record (if not empty). This is meant to be called - * from the handshake processor only. - */ -void br_ssl_engine_flush_record(br_ssl_engine_context *cc); - -/* - * Test whether there is some accumulated payload to send. - */ -static inline int -br_ssl_engine_has_pld_to_send(const br_ssl_engine_context *rc) -{ - return rc->oxa != rc->oxb && rc->oxa != rc->oxc; -} - -/* - * Initialize RNG in engine. Returned value is 1 on success, 0 on error. - * This function will try to use the OS-provided RNG, if available. If - * there is no OS-provided RNG, or if it failed, and no entropy was - * injected by the caller, then a failure will be reported. On error, - * the context error code is set. - */ -int br_ssl_engine_init_rand(br_ssl_engine_context *cc); - -/* - * Reset the handshake-related parts of the engine. - */ -void br_ssl_engine_hs_reset(br_ssl_engine_context *cc, - void (*hsinit)(void *), void (*hsrun)(void *)); - -/* - * Get the PRF to use for this context, for the provided PRF hash - * function ID. - */ -br_tls_prf_impl br_ssl_engine_get_PRF(br_ssl_engine_context *cc, int prf_id); - -/* - * Consume the provided pre-master secret and compute the corresponding - * master secret. The 'prf_id' is the ID of the hash function to use - * with the TLS 1.2 PRF (ignored if the version is TLS 1.0 or 1.1). - */ -void br_ssl_engine_compute_master(br_ssl_engine_context *cc, - int prf_id, const void *pms, size_t len); - -/* - * Switch to CBC decryption for incoming records. - * cc the engine context - * is_client non-zero for a client, zero for a server - * prf_id id of hash function for PRF (ignored if not TLS 1.2+) - * mac_id id of hash function for HMAC - * bc_impl block cipher implementation (CBC decryption) - * cipher_key_len block cipher key length (in bytes) - */ -void br_ssl_engine_switch_cbc_in(br_ssl_engine_context *cc, - int is_client, int prf_id, int mac_id, - const br_block_cbcdec_class *bc_impl, size_t cipher_key_len); - -/* - * Switch to CBC encryption for outgoing records. - * cc the engine context - * is_client non-zero for a client, zero for a server - * prf_id id of hash function for PRF (ignored if not TLS 1.2+) - * mac_id id of hash function for HMAC - * bc_impl block cipher implementation (CBC encryption) - * cipher_key_len block cipher key length (in bytes) - */ -void br_ssl_engine_switch_cbc_out(br_ssl_engine_context *cc, - int is_client, int prf_id, int mac_id, - const br_block_cbcenc_class *bc_impl, size_t cipher_key_len); - -/* - * Switch to GCM decryption for incoming records. - * cc the engine context - * is_client non-zero for a client, zero for a server - * prf_id id of hash function for PRF - * bc_impl block cipher implementation (CTR) - * cipher_key_len block cipher key length (in bytes) - */ -void br_ssl_engine_switch_gcm_in(br_ssl_engine_context *cc, - int is_client, int prf_id, - const br_block_ctr_class *bc_impl, size_t cipher_key_len); - -/* - * Switch to GCM encryption for outgoing records. - * cc the engine context - * is_client non-zero for a client, zero for a server - * prf_id id of hash function for PRF - * bc_impl block cipher implementation (CTR) - * cipher_key_len block cipher key length (in bytes) - */ -void br_ssl_engine_switch_gcm_out(br_ssl_engine_context *cc, - int is_client, int prf_id, - const br_block_ctr_class *bc_impl, size_t cipher_key_len); - -/* - * Switch to ChaCha20+Poly1305 decryption for incoming records. - * cc the engine context - * is_client non-zero for a client, zero for a server - * prf_id id of hash function for PRF - */ -void br_ssl_engine_switch_chapol_in(br_ssl_engine_context *cc, - int is_client, int prf_id); - -/* - * Switch to ChaCha20+Poly1305 encryption for outgoing records. - * cc the engine context - * is_client non-zero for a client, zero for a server - * prf_id id of hash function for PRF - */ -void br_ssl_engine_switch_chapol_out(br_ssl_engine_context *cc, - int is_client, int prf_id); - -/* - * Switch to CCM decryption for incoming records. - * cc the engine context - * is_client non-zero for a client, zero for a server - * prf_id id of hash function for PRF - * bc_impl block cipher implementation (CTR+CBC) - * cipher_key_len block cipher key length (in bytes) - * tag_len tag length (in bytes) - */ -void br_ssl_engine_switch_ccm_in(br_ssl_engine_context *cc, - int is_client, int prf_id, - const br_block_ctrcbc_class *bc_impl, - size_t cipher_key_len, size_t tag_len); - -/* - * Switch to GCM encryption for outgoing records. - * cc the engine context - * is_client non-zero for a client, zero for a server - * prf_id id of hash function for PRF - * bc_impl block cipher implementation (CTR+CBC) - * cipher_key_len block cipher key length (in bytes) - * tag_len tag length (in bytes) - */ -void br_ssl_engine_switch_ccm_out(br_ssl_engine_context *cc, - int is_client, int prf_id, - const br_block_ctrcbc_class *bc_impl, - size_t cipher_key_len, size_t tag_len); - -/* - * Calls to T0-generated code. - */ -void br_ssl_hs_client_init_main(void *ctx); -void br_ssl_hs_client_run(void *ctx); -void br_ssl_hs_server_init_main(void *ctx); -void br_ssl_hs_server_run(void *ctx); - -/* - * Get the hash function to use for signatures, given a bit mask of - * supported hash functions. This implements a strict choice order - * (namely SHA-256, SHA-384, SHA-512, SHA-224, SHA-1). If the mask - * does not document support of any of these hash functions, then this - * functions returns 0. - */ -int br_ssl_choose_hash(unsigned bf); - -/* ==================================================================== */ - -/* - * PowerPC / POWER assembly stuff. The special BR_POWER_ASM_MACROS macro - * must be defined before including this file; this is done by source - * files that use some inline assembly for PowerPC / POWER machines. - */ - -#if BR_POWER_ASM_MACROS - -#define lxvw4x(xt, ra, rb) lxvw4x_(xt, ra, rb) -#define stxvw4x(xt, ra, rb) stxvw4x_(xt, ra, rb) - -#define bdnz(foo) bdnz_(foo) -#define bdz(foo) bdz_(foo) -#define beq(foo) beq_(foo) - -#define li(rx, value) li_(rx, value) -#define addi(rx, ra, imm) addi_(rx, ra, imm) -#define cmpldi(rx, imm) cmpldi_(rx, imm) -#define mtctr(rx) mtctr_(rx) -#define vspltb(vrt, vrb, uim) vspltb_(vrt, vrb, uim) -#define vspltw(vrt, vrb, uim) vspltw_(vrt, vrb, uim) -#define vspltisb(vrt, imm) vspltisb_(vrt, imm) -#define vspltisw(vrt, imm) vspltisw_(vrt, imm) -#define vrlw(vrt, vra, vrb) vrlw_(vrt, vra, vrb) -#define vsbox(vrt, vra) vsbox_(vrt, vra) -#define vxor(vrt, vra, vrb) vxor_(vrt, vra, vrb) -#define vand(vrt, vra, vrb) vand_(vrt, vra, vrb) -#define vsro(vrt, vra, vrb) vsro_(vrt, vra, vrb) -#define vsl(vrt, vra, vrb) vsl_(vrt, vra, vrb) -#define vsldoi(vt, va, vb, sh) vsldoi_(vt, va, vb, sh) -#define vsr(vrt, vra, vrb) vsr_(vrt, vra, vrb) -#define vaddcuw(vrt, vra, vrb) vaddcuw_(vrt, vra, vrb) -#define vadduwm(vrt, vra, vrb) vadduwm_(vrt, vra, vrb) -#define vsububm(vrt, vra, vrb) vsububm_(vrt, vra, vrb) -#define vsubuwm(vrt, vra, vrb) vsubuwm_(vrt, vra, vrb) -#define vsrw(vrt, vra, vrb) vsrw_(vrt, vra, vrb) -#define vcipher(vt, va, vb) vcipher_(vt, va, vb) -#define vcipherlast(vt, va, vb) vcipherlast_(vt, va, vb) -#define vncipher(vt, va, vb) vncipher_(vt, va, vb) -#define vncipherlast(vt, va, vb) vncipherlast_(vt, va, vb) -#define vperm(vt, va, vb, vc) vperm_(vt, va, vb, vc) -#define vpmsumd(vt, va, vb) vpmsumd_(vt, va, vb) -#define xxpermdi(vt, va, vb, d) xxpermdi_(vt, va, vb, d) - -#define lxvw4x_(xt, ra, rb) "\tlxvw4x\t" #xt "," #ra "," #rb "\n" -#define stxvw4x_(xt, ra, rb) "\tstxvw4x\t" #xt "," #ra "," #rb "\n" - -#define label(foo) #foo "%=:\n" -#define bdnz_(foo) "\tbdnz\t" #foo "%=\n" -#define bdz_(foo) "\tbdz\t" #foo "%=\n" -#define beq_(foo) "\tbeq\t" #foo "%=\n" - -#define li_(rx, value) "\tli\t" #rx "," #value "\n" -#define addi_(rx, ra, imm) "\taddi\t" #rx "," #ra "," #imm "\n" -#define cmpldi_(rx, imm) "\tcmpldi\t" #rx "," #imm "\n" -#define mtctr_(rx) "\tmtctr\t" #rx "\n" -#define vspltb_(vrt, vrb, uim) "\tvspltb\t" #vrt "," #vrb "," #uim "\n" -#define vspltw_(vrt, vrb, uim) "\tvspltw\t" #vrt "," #vrb "," #uim "\n" -#define vspltisb_(vrt, imm) "\tvspltisb\t" #vrt "," #imm "\n" -#define vspltisw_(vrt, imm) "\tvspltisw\t" #vrt "," #imm "\n" -#define vrlw_(vrt, vra, vrb) "\tvrlw\t" #vrt "," #vra "," #vrb "\n" -#define vsbox_(vrt, vra) "\tvsbox\t" #vrt "," #vra "\n" -#define vxor_(vrt, vra, vrb) "\tvxor\t" #vrt "," #vra "," #vrb "\n" -#define vand_(vrt, vra, vrb) "\tvand\t" #vrt "," #vra "," #vrb "\n" -#define vsro_(vrt, vra, vrb) "\tvsro\t" #vrt "," #vra "," #vrb "\n" -#define vsl_(vrt, vra, vrb) "\tvsl\t" #vrt "," #vra "," #vrb "\n" -#define vsldoi_(vt, va, vb, sh) "\tvsldoi\t" #vt "," #va "," #vb "," #sh "\n" -#define vsr_(vrt, vra, vrb) "\tvsr\t" #vrt "," #vra "," #vrb "\n" -#define vaddcuw_(vrt, vra, vrb) "\tvaddcuw\t" #vrt "," #vra "," #vrb "\n" -#define vadduwm_(vrt, vra, vrb) "\tvadduwm\t" #vrt "," #vra "," #vrb "\n" -#define vsububm_(vrt, vra, vrb) "\tvsububm\t" #vrt "," #vra "," #vrb "\n" -#define vsubuwm_(vrt, vra, vrb) "\tvsubuwm\t" #vrt "," #vra "," #vrb "\n" -#define vsrw_(vrt, vra, vrb) "\tvsrw\t" #vrt "," #vra "," #vrb "\n" -#define vcipher_(vt, va, vb) "\tvcipher\t" #vt "," #va "," #vb "\n" -#define vcipherlast_(vt, va, vb) "\tvcipherlast\t" #vt "," #va "," #vb "\n" -#define vncipher_(vt, va, vb) "\tvncipher\t" #vt "," #va "," #vb "\n" -#define vncipherlast_(vt, va, vb) "\tvncipherlast\t" #vt "," #va "," #vb "\n" -#define vperm_(vt, va, vb, vc) "\tvperm\t" #vt "," #va "," #vb "," #vc "\n" -#define vpmsumd_(vt, va, vb) "\tvpmsumd\t" #vt "," #va "," #vb "\n" -#define xxpermdi_(vt, va, vb, d) "\txxpermdi\t" #vt "," #va "," #vb "," #d "\n" - -#endif - -/* ==================================================================== */ -/* - * Special "activate intrinsics" code, needed for some compiler versions. - * This is defined at the end of this file, so that it won't impact any - * of the inline functions defined previously; and it is controlled by - * a specific macro defined in the caller code. - * - * Calling code conventions: - * - * - Caller must define BR_ENABLE_INTRINSICS before including "inner.h". - * - Functions that use intrinsics must be enclosed in an "enabled" - * region (between BR_TARGETS_X86_UP and BR_TARGETS_X86_DOWN). - * - Functions that use intrinsics must be tagged with the appropriate - * BR_TARGET(). - */ - -#if BR_ENABLE_INTRINSICS && (BR_GCC_4_4 || BR_CLANG_3_7 || BR_MSC_2005) - -/* - * x86 intrinsics (both 32-bit and 64-bit). - */ -#if BR_i386 || BR_amd64 - -/* - * On GCC before version 5.0, we need to use the pragma to enable the - * target options globally, because the 'target' function attribute - * appears to be unreliable. Before 4.6 we must also avoid the - * push_options / pop_options mechanism, because it tends to trigger - * some internal compiler errors. - */ -#if BR_GCC && !BR_GCC_5_0 -#if BR_GCC_4_6 -#define BR_TARGETS_X86_UP \ - _Pragma("GCC push_options") \ - _Pragma("GCC target(\"sse2,ssse3,sse4.1,aes,pclmul,rdrnd\")") -#define BR_TARGETS_X86_DOWN \ - _Pragma("GCC pop_options") -#else -#define BR_TARGETS_X86_UP \ - _Pragma("GCC target(\"sse2,ssse3,sse4.1,aes,pclmul\")") -#endif -#define BR_TARGETS_X86_DOWN -#pragma GCC diagnostic ignored "-Wpsabi" -#endif - -#if BR_CLANG && !BR_CLANG_3_8 -#undef __SSE2__ -#undef __SSE3__ -#undef __SSSE3__ -#undef __SSE4_1__ -#undef __AES__ -#undef __PCLMUL__ -#undef __RDRND__ -#define __SSE2__ 1 -#define __SSE3__ 1 -#define __SSSE3__ 1 -#define __SSE4_1__ 1 -#define __AES__ 1 -#define __PCLMUL__ 1 -#define __RDRND__ 1 -#endif - -#ifndef BR_TARGETS_X86_UP -#define BR_TARGETS_X86_UP -#endif -#ifndef BR_TARGETS_X86_DOWN -#define BR_TARGETS_X86_DOWN -#endif - -#if BR_GCC || BR_CLANG -BR_TARGETS_X86_UP -#include -#include -#define br_bswap32 __builtin_bswap32 -BR_TARGETS_X86_DOWN -#endif - -#if BR_MSC -#include -#include -#include -#define br_bswap32 _byteswap_ulong -#endif - -static inline int -br_cpuid(uint32_t mask_eax, uint32_t mask_ebx, - uint32_t mask_ecx, uint32_t mask_edx) -{ -#if BR_GCC || BR_CLANG - unsigned eax, ebx, ecx, edx; - - if (__get_cpuid(1, &eax, &ebx, &ecx, &edx)) { - if ((eax & mask_eax) == mask_eax - && (ebx & mask_ebx) == mask_ebx - && (ecx & mask_ecx) == mask_ecx - && (edx & mask_edx) == mask_edx) - { - return 1; - } - } -#elif BR_MSC - int info[4]; - - __cpuid(info, 1); - if (((uint32_t)info[0] & mask_eax) == mask_eax - && ((uint32_t)info[1] & mask_ebx) == mask_ebx - && ((uint32_t)info[2] & mask_ecx) == mask_ecx - && ((uint32_t)info[3] & mask_edx) == mask_edx) - { - return 1; - } -#endif - return 0; -} - -#endif - -#endif - -/* ==================================================================== */ - -#endif diff --git a/src/tls/bearssl/md5.c b/src/tls/bearssl/md5.c deleted file mode 100644 index c6dff1940..000000000 --- a/src/tls/bearssl/md5.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -#define F(B, C, D) ((((C) ^ (D)) & (B)) ^ (D)) -#define G(B, C, D) ((((C) ^ (B)) & (D)) ^ (C)) -#define H(B, C, D) ((B) ^ (C) ^ (D)) -#define I(B, C, D) ((C) ^ ((B) | ~(D))) - -#define ROTL(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) - -/* see inner.h */ -const uint32_t br_md5_IV[4] = { - 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476 -}; - -static const uint32_t K[64] = { - 0xD76AA478, 0xE8C7B756, 0x242070DB, 0xC1BDCEEE, - 0xF57C0FAF, 0x4787C62A, 0xA8304613, 0xFD469501, - 0x698098D8, 0x8B44F7AF, 0xFFFF5BB1, 0x895CD7BE, - 0x6B901122, 0xFD987193, 0xA679438E, 0x49B40821, - - 0xF61E2562, 0xC040B340, 0x265E5A51, 0xE9B6C7AA, - 0xD62F105D, 0x02441453, 0xD8A1E681, 0xE7D3FBC8, - 0x21E1CDE6, 0xC33707D6, 0xF4D50D87, 0x455A14ED, - 0xA9E3E905, 0xFCEFA3F8, 0x676F02D9, 0x8D2A4C8A, - - 0xFFFA3942, 0x8771F681, 0x6D9D6122, 0xFDE5380C, - 0xA4BEEA44, 0x4BDECFA9, 0xF6BB4B60, 0xBEBFBC70, - 0x289B7EC6, 0xEAA127FA, 0xD4EF3085, 0x04881D05, - 0xD9D4D039, 0xE6DB99E5, 0x1FA27CF8, 0xC4AC5665, - - 0xF4292244, 0x432AFF97, 0xAB9423A7, 0xFC93A039, - 0x655B59C3, 0x8F0CCC92, 0xFFEFF47D, 0x85845DD1, - 0x6FA87E4F, 0xFE2CE6E0, 0xA3014314, 0x4E0811A1, - 0xF7537E82, 0xBD3AF235, 0x2AD7D2BB, 0xEB86D391 -}; - -static const unsigned char MP[48] = { - 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, - 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, - 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 -}; - -/* see inner.h */ -void -br_md5_round(const unsigned char *buf, uint32_t *val) -{ - uint32_t m[16]; - uint32_t a, b, c, d; - int i; - - a = val[0]; - b = val[1]; - c = val[2]; - d = val[3]; - /* obsolete - for (i = 0; i < 16; i ++) { - m[i] = br_dec32le(buf + (i << 2)); - } - */ - br_range_dec32le(m, 16, buf); - - for (i = 0; i < 16; i += 4) { - a = b + ROTL(a + F(b, c, d) + m[i + 0] + K[i + 0], 7); - d = a + ROTL(d + F(a, b, c) + m[i + 1] + K[i + 1], 12); - c = d + ROTL(c + F(d, a, b) + m[i + 2] + K[i + 2], 17); - b = c + ROTL(b + F(c, d, a) + m[i + 3] + K[i + 3], 22); - } - for (i = 16; i < 32; i += 4) { - a = b + ROTL(a + G(b, c, d) + m[MP[i - 16]] + K[i + 0], 5); - d = a + ROTL(d + G(a, b, c) + m[MP[i - 15]] + K[i + 1], 9); - c = d + ROTL(c + G(d, a, b) + m[MP[i - 14]] + K[i + 2], 14); - b = c + ROTL(b + G(c, d, a) + m[MP[i - 13]] + K[i + 3], 20); - } - for (i = 32; i < 48; i += 4) { - a = b + ROTL(a + H(b, c, d) + m[MP[i - 16]] + K[i + 0], 4); - d = a + ROTL(d + H(a, b, c) + m[MP[i - 15]] + K[i + 1], 11); - c = d + ROTL(c + H(d, a, b) + m[MP[i - 14]] + K[i + 2], 16); - b = c + ROTL(b + H(c, d, a) + m[MP[i - 13]] + K[i + 3], 23); - } - for (i = 48; i < 64; i += 4) { - a = b + ROTL(a + I(b, c, d) + m[MP[i - 16]] + K[i + 0], 6); - d = a + ROTL(d + I(a, b, c) + m[MP[i - 15]] + K[i + 1], 10); - c = d + ROTL(c + I(d, a, b) + m[MP[i - 14]] + K[i + 2], 15); - b = c + ROTL(b + I(c, d, a) + m[MP[i - 13]] + K[i + 3], 21); - } - - val[0] += a; - val[1] += b; - val[2] += c; - val[3] += d; -} - -/* see bearssl.h */ -void -br_md5_init(br_md5_context *cc) -{ - cc->vtable = &br_md5_vtable; - memcpy(cc->val, br_md5_IV, sizeof cc->val); - cc->count = 0; -} - -/* see bearssl.h */ -void -br_md5_update(br_md5_context *cc, const void *data, size_t len) -{ - const unsigned char *buf; - size_t ptr; - - buf = data; - ptr = (size_t)cc->count & 63; - while (len > 0) { - size_t clen; - - clen = 64 - ptr; - if (clen > len) { - clen = len; - } - memcpy(cc->buf + ptr, buf, clen); - ptr += clen; - buf += clen; - len -= clen; - cc->count += (uint64_t)clen; - if (ptr == 64) { - br_md5_round(cc->buf, cc->val); - ptr = 0; - } - } -} - -/* see bearssl.h */ -void -br_md5_out(const br_md5_context *cc, void *dst) -{ - unsigned char buf[64]; - uint32_t val[4]; - size_t ptr; - - ptr = (size_t)cc->count & 63; - memcpy(buf, cc->buf, ptr); - memcpy(val, cc->val, sizeof val); - buf[ptr ++] = 0x80; - if (ptr > 56) { - memset(buf + ptr, 0, 64 - ptr); - br_md5_round(buf, val); - memset(buf, 0, 56); - } else { - memset(buf + ptr, 0, 56 - ptr); - } - br_enc64le(buf + 56, cc->count << 3); - br_md5_round(buf, val); - br_range_enc32le(dst, val, 4); -} - -/* see bearssl.h */ -uint64_t -br_md5_state(const br_md5_context *cc, void *dst) -{ - br_range_enc32le(dst, cc->val, 4); - return cc->count; -} - -/* see bearssl.h */ -void -br_md5_set_state(br_md5_context *cc, const void *stb, uint64_t count) -{ - br_range_dec32le(cc->val, 4, stb); - cc->count = count; -} - -/* see bearssl.h */ -const br_hash_class br_md5_vtable = { - sizeof(br_md5_context), - BR_HASHDESC_ID(br_md5_ID) - | BR_HASHDESC_OUT(16) - | BR_HASHDESC_STATE(16) - | BR_HASHDESC_LBLEN(6) - | BR_HASHDESC_MD_PADDING, - (void (*)(const br_hash_class **))&br_md5_init, - (void (*)(const br_hash_class **, const void *, size_t))&br_md5_update, - (void (*)(const br_hash_class *const *, void *))&br_md5_out, - (uint64_t (*)(const br_hash_class *const *, void *))&br_md5_state, - (void (*)(const br_hash_class **, const void *, uint64_t)) - &br_md5_set_state -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/md5sha1.c b/src/tls/bearssl/md5sha1.c deleted file mode 100644 index 1357f9084..000000000 --- a/src/tls/bearssl/md5sha1.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl.h */ -void -br_md5sha1_init(br_md5sha1_context *cc) -{ - cc->vtable = &br_md5sha1_vtable; - memcpy(cc->val_md5, br_md5_IV, sizeof cc->val_md5); - memcpy(cc->val_sha1, br_sha1_IV, sizeof cc->val_sha1); - cc->count = 0; -} - -/* see bearssl.h */ -void -br_md5sha1_update(br_md5sha1_context *cc, const void *data, size_t len) -{ - const unsigned char *buf; - size_t ptr; - - buf = data; - ptr = (size_t)cc->count & 63; - while (len > 0) { - size_t clen; - - clen = 64 - ptr; - if (clen > len) { - clen = len; - } - memcpy(cc->buf + ptr, buf, clen); - ptr += clen; - buf += clen; - len -= clen; - cc->count += (uint64_t)clen; - if (ptr == 64) { - br_md5_round(cc->buf, cc->val_md5); - br_sha1_round(cc->buf, cc->val_sha1); - ptr = 0; - } - } -} - -/* see bearssl.h */ -void -br_md5sha1_out(const br_md5sha1_context *cc, void *dst) -{ - unsigned char buf[64]; - uint32_t val_md5[4]; - uint32_t val_sha1[5]; - size_t ptr; - unsigned char *out; - uint64_t count; - - count = cc->count; - ptr = (size_t)count & 63; - memcpy(buf, cc->buf, ptr); - memcpy(val_md5, cc->val_md5, sizeof val_md5); - memcpy(val_sha1, cc->val_sha1, sizeof val_sha1); - buf[ptr ++] = 0x80; - if (ptr > 56) { - memset(buf + ptr, 0, 64 - ptr); - br_md5_round(buf, val_md5); - br_sha1_round(buf, val_sha1); - memset(buf, 0, 56); - } else { - memset(buf + ptr, 0, 56 - ptr); - } - count <<= 3; - br_enc64le(buf + 56, count); - br_md5_round(buf, val_md5); - br_enc64be(buf + 56, count); - br_sha1_round(buf, val_sha1); - out = dst; - br_range_enc32le(out, val_md5, 4); - br_range_enc32be(out + 16, val_sha1, 5); -} - -/* see bearssl.h */ -uint64_t -br_md5sha1_state(const br_md5sha1_context *cc, void *dst) -{ - unsigned char *out; - - out = dst; - br_range_enc32le(out, cc->val_md5, 4); - br_range_enc32be(out + 16, cc->val_sha1, 5); - return cc->count; -} - -/* see bearssl.h */ -void -br_md5sha1_set_state(br_md5sha1_context *cc, const void *stb, uint64_t count) -{ - const unsigned char *buf; - - buf = stb; - br_range_dec32le(cc->val_md5, 4, buf); - br_range_dec32be(cc->val_sha1, 5, buf + 16); - cc->count = count; -} - -/* see bearssl.h */ -const br_hash_class br_md5sha1_vtable = { - sizeof(br_md5sha1_context), - BR_HASHDESC_ID(br_md5sha1_ID) - | BR_HASHDESC_OUT(36) - | BR_HASHDESC_STATE(36) - | BR_HASHDESC_LBLEN(6), - (void (*)(const br_hash_class **))&br_md5sha1_init, - (void (*)(const br_hash_class **, const void *, size_t)) - &br_md5sha1_update, - (void (*)(const br_hash_class *const *, void *)) - &br_md5sha1_out, - (uint64_t (*)(const br_hash_class *const *, void *)) - &br_md5sha1_state, - (void (*)(const br_hash_class **, const void *, uint64_t)) - &br_md5sha1_set_state -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/mgf1.c b/src/tls/bearssl/mgf1.c deleted file mode 100644 index 409306ed1..000000000 --- a/src/tls/bearssl/mgf1.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_mgf1_xor(void *data, size_t len, - const br_hash_class *dig, const void *seed, size_t seed_len) -{ - unsigned char *buf; - size_t u, hlen; - uint32_t c; - - buf = data; - hlen = br_digest_size(dig); - for (u = 0, c = 0; u < len; u += hlen, c ++) { - br_hash_compat_context hc; - unsigned char tmp[64]; - size_t v; - - hc.vtable = dig; - dig->init(&hc.vtable); - dig->update(&hc.vtable, seed, seed_len); - br_enc32be(tmp, c); - dig->update(&hc.vtable, tmp, 4); - dig->out(&hc.vtable, tmp); - for (v = 0; v < hlen; v ++) { - if ((u + v) >= len) { - break; - } - buf[u + v] ^= tmp[v]; - } - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/multihash.c b/src/tls/bearssl/multihash.c deleted file mode 100644 index 4a2805922..000000000 --- a/src/tls/bearssl/multihash.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * An aggregate context that is large enough for all supported hash - * functions. - */ -typedef union { - const br_hash_class *vtable; - br_md5_context md5; - br_sha1_context sha1; - br_sha224_context sha224; - br_sha256_context sha256; - br_sha384_context sha384; - br_sha512_context sha512; -} gen_hash_context; - -/* - * Get the offset to the state for a specific hash function within the - * context structure. This shall be called only for the supported hash - * functions, - */ -static size_t -get_state_offset(int id) -{ - if (id >= 5) { - /* - * SHA-384 has id 5, and SHA-512 has id 6. Both use - * eight 64-bit words for their state. - */ - return offsetof(br_multihash_context, val_64) - + ((size_t)(id - 5) * (8 * sizeof(uint64_t))); - } else { - /* - * MD5 has id 1, SHA-1 has id 2, SHA-224 has id 3 and - * SHA-256 has id 4. They use 32-bit words for their - * states (4 words for MD5, 5 for SHA-1, 8 for SHA-224 - * and 8 for SHA-256). - */ - unsigned x; - - x = id - 1; - x = ((x + (x & (x >> 1))) << 2) + (x >> 1); - return offsetof(br_multihash_context, val_32) - + x * sizeof(uint32_t); - } -} - -/* see bearssl_hash.h */ -void -br_multihash_zero(br_multihash_context *ctx) -{ - /* - * This is not standard, but yields very short and efficient code, - * and it works "everywhere". - */ - memset(ctx, 0, sizeof *ctx); -} - -/* see bearssl_hash.h */ -void -br_multihash_init(br_multihash_context *ctx) -{ - int i; - - ctx->count = 0; - for (i = 1; i <= 6; i ++) { - const br_hash_class *hc; - - hc = ctx->impl[i - 1]; - if (hc != NULL) { - gen_hash_context g; - - hc->init(&g.vtable); - hc->state(&g.vtable, - (unsigned char *)ctx + get_state_offset(i)); - } - } -} - -/* see bearssl_hash.h */ -void -br_multihash_update(br_multihash_context *ctx, const void *data, size_t len) -{ - const unsigned char *buf; - size_t ptr; - - buf = data; - ptr = (size_t)ctx->count & 127; - while (len > 0) { - size_t clen; - - clen = 128 - ptr; - if (clen > len) { - clen = len; - } - memcpy(ctx->buf + ptr, buf, clen); - ptr += clen; - buf += clen; - len -= clen; - ctx->count += (uint64_t)clen; - if (ptr == 128) { - int i; - - for (i = 1; i <= 6; i ++) { - const br_hash_class *hc; - - hc = ctx->impl[i - 1]; - if (hc != NULL) { - gen_hash_context g; - unsigned char *state; - - state = (unsigned char *)ctx - + get_state_offset(i); - hc->set_state(&g.vtable, - state, ctx->count - 128); - hc->update(&g.vtable, ctx->buf, 128); - hc->state(&g.vtable, state); - } - } - ptr = 0; - } - } -} - -/* see bearssl_hash.h */ -size_t -br_multihash_out(const br_multihash_context *ctx, int id, void *dst) -{ - const br_hash_class *hc; - gen_hash_context g; - const unsigned char *state; - - hc = ctx->impl[id - 1]; - if (hc == NULL) { - return 0; - } - state = (const unsigned char *)ctx + get_state_offset(id); - hc->set_state(&g.vtable, state, ctx->count & ~(uint64_t)127); - hc->update(&g.vtable, ctx->buf, ctx->count & (uint64_t)127); - hc->out(&g.vtable, dst); - return (hc->desc >> BR_HASHDESC_OUT_OFF) & BR_HASHDESC_OUT_MASK; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/pemdec.c b/src/tls/bearssl/pemdec.c deleted file mode 100644 index 0ec43aa74..000000000 --- a/src/tls/bearssl/pemdec.c +++ /dev/null @@ -1,531 +0,0 @@ -/* Automatically generated code; do not modify directly. */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include -#include - -typedef struct { - uint32_t *dp; - uint32_t *rp; - const unsigned char *ip; -} t0_context; - -static uint32_t -t0_parse7E_unsigned(const unsigned char **p) -{ - uint32_t x; - - x = 0; - for (;;) { - unsigned y; - - y = *(*p) ++; - x = (x << 7) | (uint32_t)(y & 0x7F); - if (y < 0x80) { - return x; - } - } -} - -static int32_t -t0_parse7E_signed(const unsigned char **p) -{ - int neg; - uint32_t x; - - neg = ((**p) >> 6) & 1; - x = (uint32_t)-neg; - for (;;) { - unsigned y; - - y = *(*p) ++; - x = (x << 7) | (uint32_t)(y & 0x7F); - if (y < 0x80) { - if (neg) { - return -(int32_t)~x - 1; - } else { - return (int32_t)x; - } - } - } -} - -#define T0_VBYTE(x, n) (unsigned char)((((uint32_t)(x) >> (n)) & 0x7F) | 0x80) -#define T0_FBYTE(x, n) (unsigned char)(((uint32_t)(x) >> (n)) & 0x7F) -#define T0_SBYTE(x) (unsigned char)((((uint32_t)(x) >> 28) + 0xF8) ^ 0xF8) -#define T0_INT1(x) T0_FBYTE(x, 0) -#define T0_INT2(x) T0_VBYTE(x, 7), T0_FBYTE(x, 0) -#define T0_INT3(x) T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) -#define T0_INT4(x) T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) -#define T0_INT5(x) T0_SBYTE(x), T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) - -/* static const unsigned char t0_datablock[]; */ - - -void br_pem_decoder_init_main(void *t0ctx); - -void br_pem_decoder_run(void *t0ctx); - - - -#include "inner.h" - -#define CTX ((br_pem_decoder_context *)(void *)((unsigned char *)t0ctx - offsetof(br_pem_decoder_context, cpu))) - -/* see bearssl_pem.h */ -void -br_pem_decoder_init(br_pem_decoder_context *ctx) -{ - memset(ctx, 0, sizeof *ctx); - ctx->cpu.dp = &ctx->dp_stack[0]; - ctx->cpu.rp = &ctx->rp_stack[0]; - br_pem_decoder_init_main(&ctx->cpu); - br_pem_decoder_run(&ctx->cpu); -} - -/* see bearssl_pem.h */ -size_t -br_pem_decoder_push(br_pem_decoder_context *ctx, - const void *data, size_t len) -{ - if (ctx->event) { - return 0; - } - ctx->hbuf = data; - ctx->hlen = len; - br_pem_decoder_run(&ctx->cpu); - return len - ctx->hlen; -} - -/* see bearssl_pem.h */ -int -br_pem_decoder_event(br_pem_decoder_context *ctx) -{ - int event; - - event = ctx->event; - ctx->event = 0; - return event; -} - - - -static const unsigned char t0_datablock[] = { - 0x00, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, - 0x00, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x00 -}; - -static const unsigned char t0_codeblock[] = { - 0x00, 0x01, 0x00, 0x09, 0x00, 0x00, 0x01, 0x01, 0x07, 0x00, 0x00, 0x01, - 0x01, 0x08, 0x00, 0x00, 0x13, 0x13, 0x00, 0x00, 0x01, - T0_INT2(offsetof(br_pem_decoder_context, event)), 0x00, 0x00, 0x01, - T0_INT2(offsetof(br_pem_decoder_context, name)), 0x00, 0x00, 0x05, - 0x14, 0x2C, 0x14, 0x01, 0x0A, 0x0D, 0x06, 0x03, 0x13, 0x04, 0x76, 0x01, - 0x2D, 0x0C, 0x06, 0x05, 0x2E, 0x01, 0x03, 0x2D, 0x00, 0x01, 0x0D, 0x27, - 0x05, 0x04, 0x01, 0x03, 0x2D, 0x00, 0x15, 0x2E, 0x01, 0x02, 0x2D, 0x00, - 0x01, 0x01, 0x7F, 0x03, 0x00, 0x25, 0x01, 0x00, 0x18, 0x0D, 0x06, 0x03, - 0x13, 0x04, 0x3C, 0x01, 0x7F, 0x18, 0x0D, 0x06, 0x13, 0x13, 0x02, 0x00, - 0x05, 0x06, 0x2E, 0x01, 0x03, 0x2D, 0x04, 0x03, 0x01, 0x7F, 0x23, 0x01, - 0x00, 0x00, 0x04, 0x23, 0x01, 0x01, 0x18, 0x0D, 0x06, 0x09, 0x13, 0x01, - 0x00, 0x23, 0x01, 0x00, 0x00, 0x04, 0x14, 0x01, 0x02, 0x18, 0x0D, 0x06, - 0x06, 0x13, 0x01, 0x7F, 0x00, 0x04, 0x08, 0x13, 0x01, 0x03, 0x2D, 0x01, - 0x00, 0x00, 0x13, 0x01, 0x00, 0x03, 0x00, 0x04, 0xFF, 0x33, 0x01, 0x2C, - 0x14, 0x01, 0x2D, 0x0D, 0x06, 0x04, 0x13, 0x01, 0x7F, 0x00, 0x14, 0x31, - 0x06, 0x02, 0x13, 0x29, 0x14, 0x01, 0x0A, 0x0D, 0x06, 0x04, 0x13, 0x01, - 0x02, 0x00, 0x16, 0x14, 0x1D, 0x06, 0x05, 0x13, 0x2E, 0x01, 0x03, 0x00, - 0x03, 0x00, 0x29, 0x14, 0x01, 0x0A, 0x0D, 0x06, 0x04, 0x13, 0x01, 0x03, - 0x00, 0x16, 0x14, 0x1D, 0x06, 0x05, 0x13, 0x2E, 0x01, 0x03, 0x00, 0x02, - 0x00, 0x01, 0x06, 0x0A, 0x07, 0x03, 0x00, 0x29, 0x14, 0x01, 0x0A, 0x0D, - 0x06, 0x04, 0x13, 0x01, 0x03, 0x00, 0x14, 0x01, 0x3D, 0x0D, 0x06, 0x2E, - 0x13, 0x29, 0x14, 0x01, 0x0A, 0x0D, 0x06, 0x04, 0x13, 0x01, 0x03, 0x00, - 0x2F, 0x05, 0x04, 0x13, 0x01, 0x03, 0x00, 0x01, 0x3D, 0x0C, 0x06, 0x03, - 0x01, 0x03, 0x00, 0x02, 0x00, 0x01, 0x0F, 0x10, 0x06, 0x03, 0x01, 0x03, - 0x00, 0x02, 0x00, 0x01, 0x04, 0x0F, 0x1C, 0x01, 0x01, 0x00, 0x16, 0x14, - 0x1D, 0x06, 0x05, 0x13, 0x2E, 0x01, 0x03, 0x00, 0x02, 0x00, 0x01, 0x06, - 0x0A, 0x07, 0x03, 0x00, 0x29, 0x14, 0x01, 0x0A, 0x0D, 0x06, 0x04, 0x13, - 0x01, 0x03, 0x00, 0x14, 0x01, 0x3D, 0x0D, 0x06, 0x20, 0x13, 0x2F, 0x05, - 0x03, 0x01, 0x03, 0x00, 0x02, 0x00, 0x01, 0x03, 0x10, 0x06, 0x03, 0x01, - 0x03, 0x00, 0x02, 0x00, 0x01, 0x0A, 0x0F, 0x1C, 0x02, 0x00, 0x01, 0x02, - 0x0F, 0x1C, 0x01, 0x01, 0x00, 0x16, 0x14, 0x1D, 0x06, 0x05, 0x13, 0x2E, - 0x01, 0x03, 0x00, 0x02, 0x00, 0x01, 0x06, 0x0A, 0x07, 0x03, 0x00, 0x02, - 0x00, 0x01, 0x10, 0x0F, 0x1C, 0x02, 0x00, 0x01, 0x08, 0x0F, 0x1C, 0x02, - 0x00, 0x1C, 0x01, 0x00, 0x00, 0x00, 0x28, 0x01, 0x01, 0x2D, 0x24, 0x06, - 0x02, 0x04, 0x7B, 0x04, 0x75, 0x00, 0x14, 0x12, 0x2A, 0x14, 0x05, 0x04, - 0x20, 0x01, 0x7F, 0x00, 0x2C, 0x2A, 0x14, 0x01, 0x0A, 0x0D, 0x06, 0x05, - 0x13, 0x20, 0x01, 0x00, 0x00, 0x0D, 0x05, 0x05, 0x13, 0x2E, 0x01, 0x00, - 0x00, 0x1E, 0x04, 0x5E, 0x00, 0x01, 0x01, 0x27, 0x06, 0x0B, 0x22, 0x01, - 0x80, 0x7F, 0x2B, 0x14, 0x06, 0x02, 0x30, 0x00, 0x13, 0x04, 0x6E, 0x00, - 0x2C, 0x14, 0x31, 0x05, 0x01, 0x00, 0x13, 0x04, 0x77, 0x00, 0x14, 0x14, - 0x01, 0x80, 0x61, 0x0E, 0x1B, 0x01, 0x80, 0x7A, 0x0B, 0x10, 0x06, 0x03, - 0x01, 0x20, 0x08, 0x00, 0x01, 0x14, 0x03, 0x00, 0x1B, 0x18, 0x05, 0x05, - 0x20, 0x2E, 0x01, 0x00, 0x00, 0x2C, 0x14, 0x01, 0x0A, 0x0D, 0x06, 0x06, - 0x20, 0x02, 0x00, 0x1B, 0x08, 0x00, 0x14, 0x01, 0x0D, 0x0D, 0x06, 0x03, - 0x13, 0x04, 0x03, 0x2A, 0x18, 0x1A, 0x1E, 0x1B, 0x1F, 0x1B, 0x04, 0x59, - 0x00, 0x19, 0x14, 0x1D, 0x05, 0x01, 0x00, 0x13, 0x11, 0x04, 0x76, 0x00, - 0x21, 0x1A, 0x11, 0x00, 0x00, 0x2C, 0x01, 0x0A, 0x0C, 0x06, 0x02, 0x04, - 0x78, 0x00, 0x01, 0x01, 0x7F, 0x03, 0x00, 0x2C, 0x14, 0x01, 0x0A, 0x0C, - 0x06, 0x09, 0x31, 0x05, 0x04, 0x01, 0x00, 0x03, 0x00, 0x04, 0x70, 0x13, - 0x02, 0x00, 0x00, 0x00, 0x14, 0x06, 0x14, 0x1F, 0x14, 0x22, 0x07, 0x17, - 0x01, 0x2D, 0x0C, 0x06, 0x08, 0x22, 0x07, 0x1E, 0x01, 0x00, 0x1B, 0x1A, - 0x00, 0x04, 0x69, 0x22, 0x1A, 0x00, 0x00, 0x14, 0x01, 0x0A, 0x0C, 0x1B, - 0x01, 0x20, 0x0B, 0x10, 0x00 -}; - -static const uint16_t t0_caddr[] = { - 0, - 5, - 10, - 15, - 19, - 24, - 29, - 67, - 149, - 384, - 396, - 431, - 450, - 460, - 479, - 523, - 534, - 539, - 549, - 574, - 601 -}; - -#define T0_INTERPRETED 29 - -#define T0_ENTER(ip, rp, slot) do { \ - const unsigned char *t0_newip; \ - uint32_t t0_lnum; \ - t0_newip = &t0_codeblock[t0_caddr[(slot) - T0_INTERPRETED]]; \ - t0_lnum = t0_parse7E_unsigned(&t0_newip); \ - (rp) += t0_lnum; \ - *((rp) ++) = (uint32_t)((ip) - &t0_codeblock[0]) + (t0_lnum << 16); \ - (ip) = t0_newip; \ - } while (0) - -#define T0_DEFENTRY(name, slot) \ -void \ -name(void *ctx) \ -{ \ - t0_context *t0ctx = ctx; \ - t0ctx->ip = &t0_codeblock[0]; \ - T0_ENTER(t0ctx->ip, t0ctx->rp, slot); \ -} - -T0_DEFENTRY(br_pem_decoder_init_main, 38) - -#define T0_NEXT(t0ipp) (*(*(t0ipp)) ++) - -void -br_pem_decoder_run(void *t0ctx) -{ - uint32_t *dp, *rp; - const unsigned char *ip; - -#define T0_LOCAL(x) (*(rp - 2 - (x))) -#define T0_POP() (*-- dp) -#define T0_POPi() (*(int32_t *)(-- dp)) -#define T0_PEEK(x) (*(dp - 1 - (x))) -#define T0_PEEKi(x) (*(int32_t *)(dp - 1 - (x))) -#define T0_PUSH(v) do { *dp = (v); dp ++; } while (0) -#define T0_PUSHi(v) do { *(int32_t *)dp = (v); dp ++; } while (0) -#define T0_RPOP() (*-- rp) -#define T0_RPOPi() (*(int32_t *)(-- rp)) -#define T0_RPUSH(v) do { *rp = (v); rp ++; } while (0) -#define T0_RPUSHi(v) do { *(int32_t *)rp = (v); rp ++; } while (0) -#define T0_ROLL(x) do { \ - size_t t0len = (size_t)(x); \ - uint32_t t0tmp = *(dp - 1 - t0len); \ - memmove(dp - t0len - 1, dp - t0len, t0len * sizeof *dp); \ - *(dp - 1) = t0tmp; \ -} while (0) -#define T0_SWAP() do { \ - uint32_t t0tmp = *(dp - 2); \ - *(dp - 2) = *(dp - 1); \ - *(dp - 1) = t0tmp; \ -} while (0) -#define T0_ROT() do { \ - uint32_t t0tmp = *(dp - 3); \ - *(dp - 3) = *(dp - 2); \ - *(dp - 2) = *(dp - 1); \ - *(dp - 1) = t0tmp; \ -} while (0) -#define T0_NROT() do { \ - uint32_t t0tmp = *(dp - 1); \ - *(dp - 1) = *(dp - 2); \ - *(dp - 2) = *(dp - 3); \ - *(dp - 3) = t0tmp; \ -} while (0) -#define T0_PICK(x) do { \ - uint32_t t0depth = (x); \ - T0_PUSH(T0_PEEK(t0depth)); \ -} while (0) -#define T0_CO() do { \ - goto t0_exit; \ -} while (0) -#define T0_RET() goto t0_next - - dp = ((t0_context *)t0ctx)->dp; - rp = ((t0_context *)t0ctx)->rp; - ip = ((t0_context *)t0ctx)->ip; - goto t0_next; - for (;;) { - uint32_t t0x; - - t0_next: - t0x = T0_NEXT(&ip); - if (t0x < T0_INTERPRETED) { - switch (t0x) { - int32_t t0off; - - case 0: /* ret */ - t0x = T0_RPOP(); - rp -= (t0x >> 16); - t0x &= 0xFFFF; - if (t0x == 0) { - ip = NULL; - goto t0_exit; - } - ip = &t0_codeblock[t0x]; - break; - case 1: /* literal constant */ - T0_PUSHi(t0_parse7E_signed(&ip)); - break; - case 2: /* read local */ - T0_PUSH(T0_LOCAL(t0_parse7E_unsigned(&ip))); - break; - case 3: /* write local */ - T0_LOCAL(t0_parse7E_unsigned(&ip)) = T0_POP(); - break; - case 4: /* jump */ - t0off = t0_parse7E_signed(&ip); - ip += t0off; - break; - case 5: /* jump if */ - t0off = t0_parse7E_signed(&ip); - if (T0_POP()) { - ip += t0off; - } - break; - case 6: /* jump if not */ - t0off = t0_parse7E_signed(&ip); - if (!T0_POP()) { - ip += t0off; - } - break; - case 7: { - /* + */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(a + b); - - } - break; - case 8: { - /* - */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(a - b); - - } - break; - case 9: { - /* < */ - - int32_t b = T0_POPi(); - int32_t a = T0_POPi(); - T0_PUSH(-(uint32_t)(a < b)); - - } - break; - case 10: { - /* << */ - - int c = (int)T0_POPi(); - uint32_t x = T0_POP(); - T0_PUSH(x << c); - - } - break; - case 11: { - /* <= */ - - int32_t b = T0_POPi(); - int32_t a = T0_POPi(); - T0_PUSH(-(uint32_t)(a <= b)); - - } - break; - case 12: { - /* <> */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(-(uint32_t)(a != b)); - - } - break; - case 13: { - /* = */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(-(uint32_t)(a == b)); - - } - break; - case 14: { - /* >= */ - - int32_t b = T0_POPi(); - int32_t a = T0_POPi(); - T0_PUSH(-(uint32_t)(a >= b)); - - } - break; - case 15: { - /* >> */ - - int c = (int)T0_POPi(); - int32_t x = T0_POPi(); - T0_PUSHi(x >> c); - - } - break; - case 16: { - /* and */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(a & b); - - } - break; - case 17: { - /* co */ - T0_CO(); - } - break; - case 18: { - /* data-get8 */ - - size_t addr = T0_POP(); - T0_PUSH(t0_datablock[addr]); - - } - break; - case 19: { - /* drop */ - (void)T0_POP(); - } - break; - case 20: { - /* dup */ - T0_PUSH(T0_PEEK(0)); - } - break; - case 21: { - /* flush-buf */ - - if (CTX->ptr > 0) { - if (CTX->dest) { - CTX->dest(CTX->dest_ctx, CTX->buf, CTX->ptr); - } - CTX->ptr = 0; - } - - } - break; - case 22: { - /* from-base64 */ - - uint32_t c = T0_POP(); - uint32_t p, q, r, z; - p = c - 0x41; - q = c - 0x61; - r = c - 0x30; - - z = ((p + 2) & -LT(p, 26)) - | ((q + 28) & -LT(q, 26)) - | ((r + 54) & -LT(r, 10)) - | (64 & -EQ(c, 0x2B)) - | (65 & -EQ(c, 0x2F)) - | EQ(c, 0x3D); - T0_PUSHi((int32_t)z - 2); - - } - break; - case 23: { - /* get8 */ - - size_t addr = T0_POP(); - T0_PUSH(*((unsigned char *)CTX + addr)); - - } - break; - case 24: { - /* over */ - T0_PUSH(T0_PEEK(1)); - } - break; - case 25: { - /* read8-native */ - - if (CTX->hlen > 0) { - T0_PUSH(*CTX->hbuf ++); - CTX->hlen --; - } else { - T0_PUSHi(-1); - } - - } - break; - case 26: { - /* set8 */ - - size_t addr = T0_POP(); - unsigned x = T0_POP(); - *((unsigned char *)CTX + addr) = x; - - } - break; - case 27: { - /* swap */ - T0_SWAP(); - } - break; - case 28: { - /* write8 */ - - unsigned char x = (unsigned char)T0_POP(); - CTX->buf[CTX->ptr ++] = x; - if (CTX->ptr == sizeof CTX->buf) { - if (CTX->dest) { - CTX->dest(CTX->dest_ctx, CTX->buf, sizeof CTX->buf); - } - CTX->ptr = 0; - } - - } - break; - } - - } else { - T0_ENTER(ip, rp, t0x); - } - } -t0_exit: - ((t0_context *)t0ctx)->dp = dp; - ((t0_context *)t0ctx)->rp = rp; - ((t0_context *)t0ctx)->ip = ip; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/pemenc.c b/src/tls/bearssl/pemenc.c deleted file mode 100644 index 81c32d067..000000000 --- a/src/tls/bearssl/pemenc.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * Get the appropriate Base64 character for a numeric value in the - * 0..63 range. This is constant-time. - */ -static char -b64char(uint32_t x) -{ - /* - * Values 0 to 25 map to 0x41..0x5A ('A' to 'Z') - * Values 26 to 51 map to 0x61..0x7A ('a' to 'z') - * Values 52 to 61 map to 0x30..0x39 ('0' to '9') - * Value 62 maps to 0x2B ('+') - * Value 63 maps to 0x2F ('/') - */ - uint32_t a, b, c; - - a = x - 26; - b = x - 52; - c = x - 62; - - /* - * Looking at bits 8..15 of values a, b and c: - * - * x a b c - * --------------------- - * 0..25 FF FF FF - * 26..51 00 FF FF - * 52..61 00 00 FF - * 62..63 00 00 00 - */ - return (char)(((x + 0x41) & ((a & b & c) >> 8)) - | ((x + (0x61 - 26)) & ((~a & b & c) >> 8)) - | ((x - (52 - 0x30)) & ((~a & ~b & c) >> 8)) - | ((0x2B + ((x & 1) << 2)) & (~(a | b | c) >> 8))); -} - -/* see bearssl_pem.h */ -size_t -br_pem_encode(void *dest, const void *data, size_t len, - const char *banner, unsigned flags) -{ - size_t dlen, banner_len, lines; - char *d; - unsigned char *buf; - size_t u; - int off, lim; - - banner_len = strlen(banner); - /* FIXME: try to avoid divisions here, as they may pull - an extra libc function. */ - if ((flags & BR_PEM_LINE64) != 0) { - lines = (len + 47) / 48; - } else { - lines = (len + 56) / 57; - } - dlen = (banner_len << 1) + 30 + (((len + 2) / 3) << 2) - + lines + 2; - if ((flags & BR_PEM_CRLF) != 0) { - dlen += lines + 2; - } - - if (dest == NULL) { - return dlen; - } - - d = dest; - - /* - * We always move the source data to the end of output buffer; - * the encoding process never "catches up" except at the very - * end. This also handles all conditions of partial or total - * overlap. - */ - buf = (unsigned char *)d + dlen - len; - memmove(buf, data, len); - - memcpy(d, "-----BEGIN ", 11); - d += 11; - memcpy(d, banner, banner_len); - d += banner_len; - memcpy(d, "-----", 5); - d += 5; - if ((flags & BR_PEM_CRLF) != 0) { - *d ++ = 0x0D; - } - *d ++ = 0x0A; - - off = 0; - lim = (flags & BR_PEM_LINE64) != 0 ? 16 : 19; - for (u = 0; (u + 2) < len; u += 3) { - uint32_t w; - - w = ((uint32_t)buf[u] << 16) - | ((uint32_t)buf[u + 1] << 8) - | (uint32_t)buf[u + 2]; - *d ++ = b64char(w >> 18); - *d ++ = b64char((w >> 12) & 0x3F); - *d ++ = b64char((w >> 6) & 0x3F); - *d ++ = b64char(w & 0x3F); - if (++ off == lim) { - off = 0; - if ((flags & BR_PEM_CRLF) != 0) { - *d ++ = 0x0D; - } - *d ++ = 0x0A; - } - } - if (u < len) { - uint32_t w; - - w = (uint32_t)buf[u] << 16; - if (u + 1 < len) { - w |= (uint32_t)buf[u + 1] << 8; - } - *d ++ = b64char(w >> 18); - *d ++ = b64char((w >> 12) & 0x3F); - if (u + 1 < len) { - *d ++ = b64char((w >> 6) & 0x3F); - } else { - *d ++ = 0x3D; - } - *d ++ = 0x3D; - off ++; - } - if (off != 0) { - if ((flags & BR_PEM_CRLF) != 0) { - *d ++ = 0x0D; - } - *d ++ = 0x0A; - } - - memcpy(d, "-----END ", 9); - d += 9; - memcpy(d, banner, banner_len); - d += banner_len; - memcpy(d, "-----", 5); - d += 5; - if ((flags & BR_PEM_CRLF) != 0) { - *d ++ = 0x0D; - } - *d ++ = 0x0A; - - /* Final zero, not counted in returned length. */ - *d ++ = 0x00; - - return dlen; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/poly1305_ctmul.c b/src/tls/bearssl/poly1305_ctmul.c deleted file mode 100644 index 1ebdf82b4..000000000 --- a/src/tls/bearssl/poly1305_ctmul.c +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * Perform the inner processing of blocks for Poly1305. The accumulator - * and the r key are provided as arrays of 26-bit words (these words - * are allowed to have an extra bit, i.e. use 27 bits). - * - * On output, all accumulator words fit on 26 bits, except acc[1], which - * may be slightly larger (but by a very small amount only). - */ -static void -poly1305_inner(uint32_t *acc, const uint32_t *r, const void *data, size_t len) -{ - /* - * Implementation notes: we split the 130-bit values into five - * 26-bit words. This gives us some space for carries. - * - * This code is inspired from the public-domain code available - * on: - * https://github.com/floodyberry/poly1305-donna - * - * Since we compute modulo 2^130-5, the "upper words" become - * low words with a factor of 5; that is, x*2^130 = x*5 mod p. - */ - const unsigned char *buf; - uint32_t a0, a1, a2, a3, a4; - uint32_t r0, r1, r2, r3, r4; - uint32_t u1, u2, u3, u4; - - r0 = r[0]; - r1 = r[1]; - r2 = r[2]; - r3 = r[3]; - r4 = r[4]; - - u1 = r1 * 5; - u2 = r2 * 5; - u3 = r3 * 5; - u4 = r4 * 5; - - a0 = acc[0]; - a1 = acc[1]; - a2 = acc[2]; - a3 = acc[3]; - a4 = acc[4]; - - buf = data; - while (len > 0) { - uint64_t w0, w1, w2, w3, w4; - uint64_t c; - unsigned char tmp[16]; - - /* - * If there is a partial block, right-pad it with zeros. - */ - if (len < 16) { - memset(tmp, 0, sizeof tmp); - memcpy(tmp, buf, len); - buf = tmp; - len = 16; - } - - /* - * Decode next block and apply the "high bit"; that value - * is added to the accumulator. - */ - a0 += br_dec32le(buf) & 0x03FFFFFF; - a1 += (br_dec32le(buf + 3) >> 2) & 0x03FFFFFF; - a2 += (br_dec32le(buf + 6) >> 4) & 0x03FFFFFF; - a3 += (br_dec32le(buf + 9) >> 6) & 0x03FFFFFF; - a4 += (br_dec32le(buf + 12) >> 8) | 0x01000000; - - /* - * Compute multiplication. - */ -#define M(x, y) ((uint64_t)(x) * (uint64_t)(y)) - - w0 = M(a0, r0) + M(a1, u4) + M(a2, u3) + M(a3, u2) + M(a4, u1); - w1 = M(a0, r1) + M(a1, r0) + M(a2, u4) + M(a3, u3) + M(a4, u2); - w2 = M(a0, r2) + M(a1, r1) + M(a2, r0) + M(a3, u4) + M(a4, u3); - w3 = M(a0, r3) + M(a1, r2) + M(a2, r1) + M(a3, r0) + M(a4, u4); - w4 = M(a0, r4) + M(a1, r3) + M(a2, r2) + M(a3, r1) + M(a4, r0); - -#undef M - /* - * Perform some (partial) modular reduction. This step is - * enough to keep values in ranges such that there won't - * be carry overflows. Most of the reduction was done in - * the multiplication step (by using the 'u*' values, and - * using the fact that 2^130 = -5 mod p); here we perform - * some carry propagation. - */ - c = w0 >> 26; - a0 = (uint32_t)w0 & 0x3FFFFFF; - w1 += c; - c = w1 >> 26; - a1 = (uint32_t)w1 & 0x3FFFFFF; - w2 += c; - c = w2 >> 26; - a2 = (uint32_t)w2 & 0x3FFFFFF; - w3 += c; - c = w3 >> 26; - a3 = (uint32_t)w3 & 0x3FFFFFF; - w4 += c; - c = w4 >> 26; - a4 = (uint32_t)w4 & 0x3FFFFFF; - a0 += (uint32_t)c * 5; - a1 += a0 >> 26; - a0 &= 0x3FFFFFF; - - buf += 16; - len -= 16; - } - - acc[0] = a0; - acc[1] = a1; - acc[2] = a2; - acc[3] = a3; - acc[4] = a4; -} - -/* see bearssl_block.h */ -void -br_poly1305_ctmul_run(const void *key, const void *iv, - void *data, size_t len, const void *aad, size_t aad_len, - void *tag, br_chacha20_run ichacha, int encrypt) -{ - unsigned char pkey[32], foot[16]; - uint32_t r[5], acc[5], cc, ctl, hi; - uint64_t w; - int i; - - /* - * Compute the MAC key. The 'r' value is the first 16 bytes of - * pkey[]. - */ - memset(pkey, 0, sizeof pkey); - ichacha(key, iv, 0, pkey, sizeof pkey); - - /* - * If encrypting, ChaCha20 must run first, followed by Poly1305. - * When decrypting, the operations are reversed. - */ - if (encrypt) { - ichacha(key, iv, 1, data, len); - } - - /* - * Run Poly1305. We must process the AAD, then ciphertext, then - * the footer (with the lengths). Note that the AAD and ciphertext - * are meant to be padded with zeros up to the next multiple of 16, - * and the length of the footer is 16 bytes as well. - */ - - /* - * Decode the 'r' value into 26-bit words, with the "clamping" - * operation applied. - */ - r[0] = br_dec32le(pkey) & 0x03FFFFFF; - r[1] = (br_dec32le(pkey + 3) >> 2) & 0x03FFFF03; - r[2] = (br_dec32le(pkey + 6) >> 4) & 0x03FFC0FF; - r[3] = (br_dec32le(pkey + 9) >> 6) & 0x03F03FFF; - r[4] = (br_dec32le(pkey + 12) >> 8) & 0x000FFFFF; - - /* - * Accumulator is 0. - */ - memset(acc, 0, sizeof acc); - - /* - * Process the additional authenticated data, ciphertext, and - * footer in due order. - */ - br_enc64le(foot, (uint64_t)aad_len); - br_enc64le(foot + 8, (uint64_t)len); - poly1305_inner(acc, r, aad, aad_len); - poly1305_inner(acc, r, data, len); - poly1305_inner(acc, r, foot, sizeof foot); - - /* - * Finalise modular reduction. This is done with carry propagation - * and applying the '2^130 = -5 mod p' rule. Note that the output - * of poly1035_inner() is already mostly reduced, since only - * acc[1] may be (very slightly) above 2^26. A single loop back - * to acc[1] will be enough to make the value fit in 130 bits. - */ - cc = 0; - for (i = 1; i <= 6; i ++) { - int j; - - j = (i >= 5) ? i - 5 : i; - acc[j] += cc; - cc = acc[j] >> 26; - acc[j] &= 0x03FFFFFF; - } - - /* - * We may still have a value in the 2^130-5..2^130-1 range, in - * which case we must reduce it again. The code below selects, - * in constant-time, between 'acc' and 'acc-p', - */ - ctl = GT(acc[0], 0x03FFFFFA); - for (i = 1; i < 5; i ++) { - ctl &= EQ(acc[i], 0x03FFFFFF); - } - cc = 5; - for (i = 0; i < 5; i ++) { - uint32_t t; - - t = (acc[i] + cc); - cc = t >> 26; - t &= 0x03FFFFFF; - acc[i] = MUX(ctl, t, acc[i]); - } - - /* - * Convert back the accumulator to 32-bit words, and add the - * 's' value (second half of pkey[]). That addition is done - * modulo 2^128. - */ - w = (uint64_t)acc[0] + ((uint64_t)acc[1] << 26) + br_dec32le(pkey + 16); - br_enc32le((unsigned char *)tag, (uint32_t)w); - w = (w >> 32) + ((uint64_t)acc[2] << 20) + br_dec32le(pkey + 20); - br_enc32le((unsigned char *)tag + 4, (uint32_t)w); - w = (w >> 32) + ((uint64_t)acc[3] << 14) + br_dec32le(pkey + 24); - br_enc32le((unsigned char *)tag + 8, (uint32_t)w); - hi = (uint32_t)(w >> 32) + (acc[4] << 8) + br_dec32le(pkey + 28); - br_enc32le((unsigned char *)tag + 12, hi); - - /* - * If decrypting, then ChaCha20 runs _after_ Poly1305. - */ - if (!encrypt) { - ichacha(key, iv, 1, data, len); - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/poly1305_ctmul32.c b/src/tls/bearssl/poly1305_ctmul32.c deleted file mode 100644 index 948dd9e81..000000000 --- a/src/tls/bearssl/poly1305_ctmul32.c +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * Perform the inner processing of blocks for Poly1305. - */ -static void -poly1305_inner(uint32_t *a, const uint32_t *r, const void *data, size_t len) -{ - /* - * Implementation notes: we split the 130-bit values into ten - * 13-bit words. This gives us some space for carries and allows - * using only 32x32->32 multiplications, which are way faster than - * 32x32->64 multiplications on the ARM Cortex-M0/M0+, and also - * help in making constant-time code on the Cortex-M3. - * - * Since we compute modulo 2^130-5, the "upper words" become - * low words with a factor of 5; that is, x*2^130 = x*5 mod p. - * This has already been integrated in the r[] array, which - * is extended to the 0..18 range. - * - * In each loop iteration, a[] and r[] words are 13-bit each, - * except a[1] which may use 14 bits. - */ - const unsigned char *buf; - - buf = data; - while (len > 0) { - unsigned char tmp[16]; - uint32_t b[10]; - unsigned u, v; - uint32_t z, cc1, cc2; - - /* - * If there is a partial block, right-pad it with zeros. - */ - if (len < 16) { - memset(tmp, 0, sizeof tmp); - memcpy(tmp, buf, len); - buf = tmp; - len = 16; - } - - /* - * Decode next block and apply the "high bit"; that value - * is added to the accumulator. - */ - v = br_dec16le(buf); - a[0] += v & 0x01FFF; - v >>= 13; - v |= buf[2] << 3; - v |= buf[3] << 11; - a[1] += v & 0x01FFF; - v >>= 13; - v |= buf[4] << 6; - a[2] += v & 0x01FFF; - v >>= 13; - v |= buf[5] << 1; - v |= buf[6] << 9; - a[3] += v & 0x01FFF; - v >>= 13; - v |= buf[7] << 4; - v |= buf[8] << 12; - a[4] += v & 0x01FFF; - v >>= 13; - v |= buf[9] << 7; - a[5] += v & 0x01FFF; - v >>= 13; - v |= buf[10] << 2; - v |= buf[11] << 10; - a[6] += v & 0x01FFF; - v >>= 13; - v |= buf[12] << 5; - a[7] += v & 0x01FFF; - v = br_dec16le(buf + 13); - a[8] += v & 0x01FFF; - v >>= 13; - v |= buf[15] << 3; - a[9] += v | 0x00800; - - /* - * At that point, all a[] values fit on 14 bits, while - * all r[] values fit on 13 bits. Thus products fit on - * 27 bits, and we can accumulate up to 31 of them in - * a 32-bit word and still have some room for carries. - */ - - /* - * Now a[] contains words with values up to 14 bits each. - * We perform the multiplication with r[]. - * - * The extended words of r[] may be larger than 13 bits - * (they are 5 times a 13-bit word) so the full summation - * may yield values up to 46 times a 27-bit word, which - * does not fit on a 32-bit word. To avoid that issue, we - * must split the loop below in two, with a carry - * propagation operation in the middle. - */ - cc1 = 0; - for (u = 0; u < 10; u ++) { - uint32_t s; - - s = cc1 - + MUL15(a[0], r[u + 9 - 0]) - + MUL15(a[1], r[u + 9 - 1]) - + MUL15(a[2], r[u + 9 - 2]) - + MUL15(a[3], r[u + 9 - 3]) - + MUL15(a[4], r[u + 9 - 4]); - b[u] = s & 0x1FFF; - cc1 = s >> 13; - } - cc2 = 0; - for (u = 0; u < 10; u ++) { - uint32_t s; - - s = b[u] + cc2 - + MUL15(a[5], r[u + 9 - 5]) - + MUL15(a[6], r[u + 9 - 6]) - + MUL15(a[7], r[u + 9 - 7]) - + MUL15(a[8], r[u + 9 - 8]) - + MUL15(a[9], r[u + 9 - 9]); - b[u] = s & 0x1FFF; - cc2 = s >> 13; - } - memcpy(a, b, sizeof b); - - /* - * The two carries "loop back" with a factor of 5. We - * propagate them into a[0] and a[1]. - */ - z = cc1 + cc2; - z += (z << 2) + a[0]; - a[0] = z & 0x1FFF; - a[1] += z >> 13; - - buf += 16; - len -= 16; - } -} - -/* see bearssl_block.h */ -void -br_poly1305_ctmul32_run(const void *key, const void *iv, - void *data, size_t len, const void *aad, size_t aad_len, - void *tag, br_chacha20_run ichacha, int encrypt) -{ - unsigned char pkey[32], foot[16]; - uint32_t z, r[19], acc[10], cc, ctl; - int i; - - /* - * Compute the MAC key. The 'r' value is the first 16 bytes of - * pkey[]. - */ - memset(pkey, 0, sizeof pkey); - ichacha(key, iv, 0, pkey, sizeof pkey); - - /* - * If encrypting, ChaCha20 must run first, followed by Poly1305. - * When decrypting, the operations are reversed. - */ - if (encrypt) { - ichacha(key, iv, 1, data, len); - } - - /* - * Run Poly1305. We must process the AAD, then ciphertext, then - * the footer (with the lengths). Note that the AAD and ciphertext - * are meant to be padded with zeros up to the next multiple of 16, - * and the length of the footer is 16 bytes as well. - */ - - /* - * Decode the 'r' value into 13-bit words, with the "clamping" - * operation applied. - */ - z = br_dec32le(pkey) & 0x03FFFFFF; - r[9] = z & 0x1FFF; - r[10] = z >> 13; - z = (br_dec32le(pkey + 3) >> 2) & 0x03FFFF03; - r[11] = z & 0x1FFF; - r[12] = z >> 13; - z = (br_dec32le(pkey + 6) >> 4) & 0x03FFC0FF; - r[13] = z & 0x1FFF; - r[14] = z >> 13; - z = (br_dec32le(pkey + 9) >> 6) & 0x03F03FFF; - r[15] = z & 0x1FFF; - r[16] = z >> 13; - z = (br_dec32le(pkey + 12) >> 8) & 0x000FFFFF; - r[17] = z & 0x1FFF; - r[18] = z >> 13; - - /* - * Extend r[] with the 5x factor pre-applied. - */ - for (i = 0; i < 9; i ++) { - r[i] = MUL15(5, r[i + 10]); - } - - /* - * Accumulator is 0. - */ - memset(acc, 0, sizeof acc); - - /* - * Process the additional authenticated data, ciphertext, and - * footer in due order. - */ - br_enc64le(foot, (uint64_t)aad_len); - br_enc64le(foot + 8, (uint64_t)len); - poly1305_inner(acc, r, aad, aad_len); - poly1305_inner(acc, r, data, len); - poly1305_inner(acc, r, foot, sizeof foot); - - /* - * Finalise modular reduction. This is done with carry propagation - * and applying the '2^130 = -5 mod p' rule. Note that the output - * of poly1035_inner() is already mostly reduced, since only - * acc[1] may be (very slightly) above 2^13. A single loop back - * to acc[1] will be enough to make the value fit in 130 bits. - */ - cc = 0; - for (i = 1; i < 10; i ++) { - z = acc[i] + cc; - acc[i] = z & 0x1FFF; - cc = z >> 13; - } - z = acc[0] + cc + (cc << 2); - acc[0] = z & 0x1FFF; - acc[1] += z >> 13; - - /* - * We may still have a value in the 2^130-5..2^130-1 range, in - * which case we must reduce it again. The code below selects, - * in constant-time, between 'acc' and 'acc-p', - */ - ctl = GT(acc[0], 0x1FFA); - for (i = 1; i < 10; i ++) { - ctl &= EQ(acc[i], 0x1FFF); - } - acc[0] = MUX(ctl, acc[0] - 0x1FFB, acc[0]); - for (i = 1; i < 10; i ++) { - acc[i] &= ~(-ctl); - } - - /* - * Convert back the accumulator to 32-bit words, and add the - * 's' value (second half of pkey[]). That addition is done - * modulo 2^128. - */ - z = acc[0] + (acc[1] << 13) + br_dec16le(pkey + 16); - br_enc16le((unsigned char *)tag, z & 0xFFFF); - z = (z >> 16) + (acc[2] << 10) + br_dec16le(pkey + 18); - br_enc16le((unsigned char *)tag + 2, z & 0xFFFF); - z = (z >> 16) + (acc[3] << 7) + br_dec16le(pkey + 20); - br_enc16le((unsigned char *)tag + 4, z & 0xFFFF); - z = (z >> 16) + (acc[4] << 4) + br_dec16le(pkey + 22); - br_enc16le((unsigned char *)tag + 6, z & 0xFFFF); - z = (z >> 16) + (acc[5] << 1) + (acc[6] << 14) + br_dec16le(pkey + 24); - br_enc16le((unsigned char *)tag + 8, z & 0xFFFF); - z = (z >> 16) + (acc[7] << 11) + br_dec16le(pkey + 26); - br_enc16le((unsigned char *)tag + 10, z & 0xFFFF); - z = (z >> 16) + (acc[8] << 8) + br_dec16le(pkey + 28); - br_enc16le((unsigned char *)tag + 12, z & 0xFFFF); - z = (z >> 16) + (acc[9] << 5) + br_dec16le(pkey + 30); - br_enc16le((unsigned char *)tag + 14, z & 0xFFFF); - - /* - * If decrypting, then ChaCha20 runs _after_ Poly1305. - */ - if (!encrypt) { - ichacha(key, iv, 1, data, len); - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/poly1305_ctmulq.c b/src/tls/bearssl/poly1305_ctmulq.c deleted file mode 100644 index b4426e528..000000000 --- a/src/tls/bearssl/poly1305_ctmulq.c +++ /dev/null @@ -1,480 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -#if BR_INT128 || BR_UMUL128 - -#if BR_INT128 - -#define MUL128(hi, lo, x, y) do { \ - unsigned __int128 mul128tmp; \ - mul128tmp = (unsigned __int128)(x) * (unsigned __int128)(y); \ - (hi) = (uint64_t)(mul128tmp >> 64); \ - (lo) = (uint64_t)mul128tmp; \ - } while (0) - -#elif BR_UMUL128 - -#include - -#define MUL128(hi, lo, x, y) do { \ - (lo) = _umul128((x), (y), &(hi)); \ - } while (0) - -#endif - -#define MASK42 ((uint64_t)0x000003FFFFFFFFFF) -#define MASK44 ((uint64_t)0x00000FFFFFFFFFFF) - -/* - * The "accumulator" word is nominally a 130-bit value. We split it into - * words of 44 bits, each held in a 64-bit variable. - * - * If the current accumulator is a = a0 + a1*W + a2*W^2 (where W = 2^44) - * and r = r0 + r1*W + r2*W^2, then: - * - * a*r = (a0*r0) - * + (a0*r1 + a1*r0) * W - * + (a0*r2 + a1*r1 + a2*r0) * W^2 - * + (a1*r2 + a2*r1) * W^3 - * + (a2*r2) * W^4 - * - * We want to reduce that value modulo p = 2^130-5, so W^3 = 20 mod p, - * and W^4 = 20*W mod p. Thus, if we define u1 = 20*r1 and u2 = 20*r2, - * then the equations above become: - * - * b0 = a0*r0 + a1*u2 + a2*u1 - * b1 = a0*r1 + a1*r0 + a2*u2 - * b2 = a0*r2 + a1*r1 + a2*r0 - * - * In order to make u1 fit in 44 bits, we can change these equations - * into: - * - * b0 = a0*r0 + a1*u2 + a2*t1 - * b1 = a0*r1 + a1*r0 + a2*t2 - * b2 = a0*r2 + a1*r1 + a2*r0 - * - * Where t1 is u1 truncated to 44 bits, and t2 is u2 added to the extra - * bits of u1. Note that since r is clamped down to a 124-bit value, the - * values u2 and t2 fit on 44 bits too. - * - * The bx values are larger than 44 bits, so we may split them into a - * lower half (cx, 44 bits) and an upper half (dx). The new values for - * the accumulator are then: - * - * e0 = c0 + 20*d2 - * e1 = c1 + d0 - * e2 = c2 + d1 - * - * The equations allow for some room, i.e. the ax values may be larger - * than 44 bits. Similarly, the ex values will usually be larger than - * the ax. Thus, some sort of carry propagation must be done regularly, - * though not necessarily at each iteration. In particular, we do not - * need to compute the additions (for the bx values) over 128-bit - * quantities; we can stick to 64-bit computations. - * - * - * Since the 128-bit result of a 64x64 multiplication is actually - * represented over two 64-bit registers, it is cheaper to arrange for - * any split that happens between the "high" and "low" halves to be on - * that 64-bit boundary. This is done by left shifting the rx, ux and tx - * by 20 bits (since they all fit on 44 bits each, this shift is - * always possible). - */ - -static void -poly1305_inner_big(uint64_t *acc, uint64_t *r, const void *data, size_t len) -{ - -#define MX(hi, lo, m0, m1, m2) do { \ - uint64_t mxhi, mxlo; \ - MUL128(mxhi, mxlo, a0, m0); \ - (hi) = mxhi; \ - (lo) = mxlo >> 20; \ - MUL128(mxhi, mxlo, a1, m1); \ - (hi) += mxhi; \ - (lo) += mxlo >> 20; \ - MUL128(mxhi, mxlo, a2, m2); \ - (hi) += mxhi; \ - (lo) += mxlo >> 20; \ - } while (0) - - const unsigned char *buf; - uint64_t a0, a1, a2; - uint64_t r0, r1, r2, t1, t2, u2; - - r0 = r[0]; - r1 = r[1]; - r2 = r[2]; - t1 = r[3]; - t2 = r[4]; - u2 = r[5]; - a0 = acc[0]; - a1 = acc[1]; - a2 = acc[2]; - buf = data; - - while (len > 0) { - uint64_t v0, v1, v2; - uint64_t c0, c1, c2, d0, d1, d2; - - v0 = br_dec64le(buf + 0); - v1 = br_dec64le(buf + 8); - v2 = v1 >> 24; - v1 = ((v0 >> 44) | (v1 << 20)) & MASK44; - v0 &= MASK44; - a0 += v0; - a1 += v1; - a2 += v2 + ((uint64_t)1 << 40); - MX(d0, c0, r0, u2, t1); - MX(d1, c1, r1, r0, t2); - MX(d2, c2, r2, r1, r0); - a0 = c0 + 20 * d2; - a1 = c1 + d0; - a2 = c2 + d1; - - v0 = br_dec64le(buf + 16); - v1 = br_dec64le(buf + 24); - v2 = v1 >> 24; - v1 = ((v0 >> 44) | (v1 << 20)) & MASK44; - v0 &= MASK44; - a0 += v0; - a1 += v1; - a2 += v2 + ((uint64_t)1 << 40); - MX(d0, c0, r0, u2, t1); - MX(d1, c1, r1, r0, t2); - MX(d2, c2, r2, r1, r0); - a0 = c0 + 20 * d2; - a1 = c1 + d0; - a2 = c2 + d1; - - v0 = br_dec64le(buf + 32); - v1 = br_dec64le(buf + 40); - v2 = v1 >> 24; - v1 = ((v0 >> 44) | (v1 << 20)) & MASK44; - v0 &= MASK44; - a0 += v0; - a1 += v1; - a2 += v2 + ((uint64_t)1 << 40); - MX(d0, c0, r0, u2, t1); - MX(d1, c1, r1, r0, t2); - MX(d2, c2, r2, r1, r0); - a0 = c0 + 20 * d2; - a1 = c1 + d0; - a2 = c2 + d1; - - v0 = br_dec64le(buf + 48); - v1 = br_dec64le(buf + 56); - v2 = v1 >> 24; - v1 = ((v0 >> 44) | (v1 << 20)) & MASK44; - v0 &= MASK44; - a0 += v0; - a1 += v1; - a2 += v2 + ((uint64_t)1 << 40); - MX(d0, c0, r0, u2, t1); - MX(d1, c1, r1, r0, t2); - MX(d2, c2, r2, r1, r0); - a0 = c0 + 20 * d2; - a1 = c1 + d0; - a2 = c2 + d1; - - a1 += a0 >> 44; - a0 &= MASK44; - a2 += a1 >> 44; - a1 &= MASK44; - a0 += 20 * (a2 >> 44); - a2 &= MASK44; - - buf += 64; - len -= 64; - } - acc[0] = a0; - acc[1] = a1; - acc[2] = a2; - -#undef MX -} - -static void -poly1305_inner_small(uint64_t *acc, uint64_t *r, const void *data, size_t len) -{ - const unsigned char *buf; - uint64_t a0, a1, a2; - uint64_t r0, r1, r2, t1, t2, u2; - - r0 = r[0]; - r1 = r[1]; - r2 = r[2]; - t1 = r[3]; - t2 = r[4]; - u2 = r[5]; - a0 = acc[0]; - a1 = acc[1]; - a2 = acc[2]; - buf = data; - - while (len > 0) { - uint64_t v0, v1, v2; - uint64_t c0, c1, c2, d0, d1, d2; - unsigned char tmp[16]; - - if (len < 16) { - memcpy(tmp, buf, len); - memset(tmp + len, 0, (sizeof tmp) - len); - buf = tmp; - len = 16; - } - v0 = br_dec64le(buf + 0); - v1 = br_dec64le(buf + 8); - - v2 = v1 >> 24; - v1 = ((v0 >> 44) | (v1 << 20)) & MASK44; - v0 &= MASK44; - - a0 += v0; - a1 += v1; - a2 += v2 + ((uint64_t)1 << 40); - -#define MX(hi, lo, m0, m1, m2) do { \ - uint64_t mxhi, mxlo; \ - MUL128(mxhi, mxlo, a0, m0); \ - (hi) = mxhi; \ - (lo) = mxlo >> 20; \ - MUL128(mxhi, mxlo, a1, m1); \ - (hi) += mxhi; \ - (lo) += mxlo >> 20; \ - MUL128(mxhi, mxlo, a2, m2); \ - (hi) += mxhi; \ - (lo) += mxlo >> 20; \ - } while (0) - - MX(d0, c0, r0, u2, t1); - MX(d1, c1, r1, r0, t2); - MX(d2, c2, r2, r1, r0); - -#undef MX - - a0 = c0 + 20 * d2; - a1 = c1 + d0; - a2 = c2 + d1; - - a1 += a0 >> 44; - a0 &= MASK44; - a2 += a1 >> 44; - a1 &= MASK44; - a0 += 20 * (a2 >> 44); - a2 &= MASK44; - - buf += 16; - len -= 16; - } - acc[0] = a0; - acc[1] = a1; - acc[2] = a2; -} - -static inline void -poly1305_inner(uint64_t *acc, uint64_t *r, const void *data, size_t len) -{ - if (len >= 64) { - size_t len2; - - len2 = len & ~(size_t)63; - poly1305_inner_big(acc, r, data, len2); - data = (const unsigned char *)data + len2; - len -= len2; - } - if (len > 0) { - poly1305_inner_small(acc, r, data, len); - } -} - -/* see bearssl_block.h */ -void -br_poly1305_ctmulq_run(const void *key, const void *iv, - void *data, size_t len, const void *aad, size_t aad_len, - void *tag, br_chacha20_run ichacha, int encrypt) -{ - unsigned char pkey[32], foot[16]; - uint64_t r[6], acc[3], r0, r1; - uint32_t v0, v1, v2, v3, v4; - uint64_t w0, w1, w2, w3; - uint32_t ctl; - - /* - * Compute the MAC key. The 'r' value is the first 16 bytes of - * pkey[]. - */ - memset(pkey, 0, sizeof pkey); - ichacha(key, iv, 0, pkey, sizeof pkey); - - /* - * If encrypting, ChaCha20 must run first, followed by Poly1305. - * When decrypting, the operations are reversed. - */ - if (encrypt) { - ichacha(key, iv, 1, data, len); - } - - /* - * Run Poly1305. We must process the AAD, then ciphertext, then - * the footer (with the lengths). Note that the AAD and ciphertext - * are meant to be padded with zeros up to the next multiple of 16, - * and the length of the footer is 16 bytes as well. - */ - - /* - * Apply the "clamping" on r. - */ - pkey[ 3] &= 0x0F; - pkey[ 4] &= 0xFC; - pkey[ 7] &= 0x0F; - pkey[ 8] &= 0xFC; - pkey[11] &= 0x0F; - pkey[12] &= 0xFC; - pkey[15] &= 0x0F; - - /* - * Decode the 'r' value into 44-bit words, left-shifted by 20 bits. - * Also compute the u1 and u2 values. - */ - r0 = br_dec64le(pkey + 0); - r1 = br_dec64le(pkey + 8); - r[0] = r0 << 20; - r[1] = ((r0 >> 24) | (r1 << 40)) & ~(uint64_t)0xFFFFF; - r[2] = (r1 >> 4) & ~(uint64_t)0xFFFFF; - r1 = 20 * (r[1] >> 20); - r[3] = r1 << 20; - r[5] = 20 * r[2]; - r[4] = (r[5] + (r1 >> 24)) & ~(uint64_t)0xFFFFF; - - /* - * Accumulator is 0. - */ - acc[0] = 0; - acc[1] = 0; - acc[2] = 0; - - /* - * Process the additional authenticated data, ciphertext, and - * footer in due order. - */ - br_enc64le(foot, (uint64_t)aad_len); - br_enc64le(foot + 8, (uint64_t)len); - poly1305_inner(acc, r, aad, aad_len); - poly1305_inner(acc, r, data, len); - poly1305_inner_small(acc, r, foot, sizeof foot); - - /* - * Finalise modular reduction. At that point, the value consists - * in three 44-bit values (the lowest one might be slightly above - * 2^44). Two loops shall be sufficient. - */ - acc[1] += (acc[0] >> 44); - acc[0] &= MASK44; - acc[2] += (acc[1] >> 44); - acc[1] &= MASK44; - acc[0] += 5 * (acc[2] >> 42); - acc[2] &= MASK42; - acc[1] += (acc[0] >> 44); - acc[0] &= MASK44; - acc[2] += (acc[1] >> 44); - acc[1] &= MASK44; - acc[0] += 5 * (acc[2] >> 42); - acc[2] &= MASK42; - - /* - * The value may still fall in the 2^130-5..2^130-1 range, in - * which case we must reduce it again. The code below selects, - * in constant-time, between 'acc' and 'acc-p'. We encode the - * value over four 32-bit integers to finish the operation. - */ - v0 = (uint32_t)acc[0]; - v1 = (uint32_t)(acc[0] >> 32) | ((uint32_t)acc[1] << 12); - v2 = (uint32_t)(acc[1] >> 20) | ((uint32_t)acc[2] << 24); - v3 = (uint32_t)(acc[2] >> 8); - v4 = (uint32_t)(acc[2] >> 40); - - ctl = GT(v0, 0xFFFFFFFA); - ctl &= EQ(v1, 0xFFFFFFFF); - ctl &= EQ(v2, 0xFFFFFFFF); - ctl &= EQ(v3, 0xFFFFFFFF); - ctl &= EQ(v4, 0x00000003); - v0 = MUX(ctl, v0 + 5, v0); - v1 = MUX(ctl, 0, v1); - v2 = MUX(ctl, 0, v2); - v3 = MUX(ctl, 0, v3); - - /* - * Add the "s" value. This is done modulo 2^128. Don't forget - * carry propagation... - */ - w0 = (uint64_t)v0 + (uint64_t)br_dec32le(pkey + 16); - w1 = (uint64_t)v1 + (uint64_t)br_dec32le(pkey + 20) + (w0 >> 32); - w2 = (uint64_t)v2 + (uint64_t)br_dec32le(pkey + 24) + (w1 >> 32); - w3 = (uint64_t)v3 + (uint64_t)br_dec32le(pkey + 28) + (w2 >> 32); - v0 = (uint32_t)w0; - v1 = (uint32_t)w1; - v2 = (uint32_t)w2; - v3 = (uint32_t)w3; - - /* - * Encode the tag. - */ - br_enc32le((unsigned char *)tag + 0, v0); - br_enc32le((unsigned char *)tag + 4, v1); - br_enc32le((unsigned char *)tag + 8, v2); - br_enc32le((unsigned char *)tag + 12, v3); - - /* - * If decrypting, then ChaCha20 runs _after_ Poly1305. - */ - if (!encrypt) { - ichacha(key, iv, 1, data, len); - } -} - -/* see bearssl_block.h */ -br_poly1305_run -br_poly1305_ctmulq_get(void) -{ - return &br_poly1305_ctmulq_run; -} - -#else - -/* see bearssl_block.h */ -br_poly1305_run -br_poly1305_ctmulq_get(void) -{ - return 0; -} - -#endif - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/poly1305_i15.c b/src/tls/bearssl/poly1305_i15.c deleted file mode 100644 index 519ddc592..000000000 --- a/src/tls/bearssl/poly1305_i15.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * This is a "reference" implementation of Poly1305 that uses the - * generic "i15" code for big integers. It is slow, but it handles all - * big-integer operations with generic code, thereby avoiding most - * tricky situations with carry propagation and modular reduction. - */ - -/* - * Modulus: 2^130-5. - */ -static const uint16_t P1305[] = { - 0x008A, - 0x7FFB, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x03FF -}; - -/* - * -p mod 2^15. - */ -#define P0I 0x4CCD - -/* - * R^2 mod p, for conversion to Montgomery representation (R = 2^135, - * since we use 9 words of 15 bits each, and 15*9 = 135). - */ -static const uint16_t R2[] = { - 0x008A, - 0x6400, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 -}; - -/* - * Perform the inner processing of blocks for Poly1305. The "r" array - * is in Montgomery representation, while the "a" array is not. - */ -static void -poly1305_inner(uint16_t *a, const uint16_t *r, const void *data, size_t len) -{ - const unsigned char *buf; - - buf = data; - while (len > 0) { - unsigned char tmp[16], rev[16]; - uint16_t b[10]; - uint32_t ctl; - int i; - - /* - * If there is a partial block, right-pad it with zeros. - */ - if (len < 16) { - memset(tmp, 0, sizeof tmp); - memcpy(tmp, buf, len); - buf = tmp; - len = 16; - } - - /* - * Decode next block and apply the "high bit". Since - * decoding is little-endian, we must byte-swap the buffer. - */ - for (i = 0; i < 16; i ++) { - rev[i] = buf[15 - i]; - } - br_i15_decode_mod(b, rev, sizeof rev, P1305); - b[9] |= 0x0100; - - /* - * Add the accumulator to the decoded block (modular - * addition). - */ - ctl = br_i15_add(b, a, 1); - ctl |= NOT(br_i15_sub(b, P1305, 0)); - br_i15_sub(b, P1305, ctl); - - /* - * Multiply by r, result is the new accumulator value. - */ - br_i15_montymul(a, b, r, P1305, P0I); - - buf += 16; - len -= 16; - } -} - -/* - * Byteswap a 16-byte value. - */ -static void -byteswap16(unsigned char *buf) -{ - int i; - - for (i = 0; i < 8; i ++) { - unsigned x; - - x = buf[i]; - buf[i] = buf[15 - i]; - buf[15 - i] = x; - } -} - -/* see bearssl_block.h */ -void -br_poly1305_i15_run(const void *key, const void *iv, - void *data, size_t len, const void *aad, size_t aad_len, - void *tag, br_chacha20_run ichacha, int encrypt) -{ - unsigned char pkey[32], foot[16]; - uint16_t t[10], r[10], acc[10]; - - /* - * Compute the MAC key. The 'r' value is the first 16 bytes of - * pkey[]. - */ - memset(pkey, 0, sizeof pkey); - ichacha(key, iv, 0, pkey, sizeof pkey); - - /* - * If encrypting, ChaCha20 must run first, followed by Poly1305. - * When decrypting, the operations are reversed. - */ - if (encrypt) { - ichacha(key, iv, 1, data, len); - } - - /* - * Run Poly1305. We must process the AAD, then ciphertext, then - * the footer (with the lengths). Note that the AAD and ciphertext - * are meant to be padded with zeros up to the next multiple of 16, - * and the length of the footer is 16 bytes as well. - */ - - /* - * Apply the "clamping" operation on the encoded 'r' value. - */ - pkey[ 3] &= 0x0F; - pkey[ 7] &= 0x0F; - pkey[11] &= 0x0F; - pkey[15] &= 0x0F; - pkey[ 4] &= 0xFC; - pkey[ 8] &= 0xFC; - pkey[12] &= 0xFC; - - /* - * Decode the clamped 'r' value. Decoding should use little-endian - * so we must byteswap the value first. - */ - byteswap16(pkey); - br_i15_decode_mod(t, pkey, 16, P1305); - - /* - * Convert 'r' to Montgomery representation. - */ - br_i15_montymul(r, t, R2, P1305, P0I); - - /* - * Accumulator is 0. - */ - br_i15_zero(acc, 0x8A); - - /* - * Process the additional authenticated data, ciphertext, and - * footer in due order. - */ - br_enc64le(foot, (uint64_t)aad_len); - br_enc64le(foot + 8, (uint64_t)len); - poly1305_inner(acc, r, aad, aad_len); - poly1305_inner(acc, r, data, len); - poly1305_inner(acc, r, foot, sizeof foot); - - /* - * Decode the value 's'. Again, a byteswap is needed. - */ - byteswap16(pkey + 16); - br_i15_decode_mod(t, pkey + 16, 16, P1305); - - /* - * Add the value 's' to the accumulator. That addition is done - * modulo 2^128, so we just ignore the carry. - */ - br_i15_add(acc, t, 1); - - /* - * Encode the result (128 low bits) to the tag. Encoding should - * be little-endian. - */ - br_i15_encode(tag, 16, acc); - byteswap16(tag); - - /* - * If decrypting, then ChaCha20 runs _after_ Poly1305. - */ - if (!encrypt) { - ichacha(key, iv, 1, data, len); - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/prf.c b/src/tls/bearssl/prf.c deleted file mode 100644 index d690438a2..000000000 --- a/src/tls/bearssl/prf.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -void -br_tls_phash(void *dst, size_t len, - const br_hash_class *dig, - const void *secret, size_t secret_len, const char *label, - size_t seed_num, const br_tls_prf_seed_chunk *seed) -{ - unsigned char *buf; - unsigned char tmp[64], a[64]; - br_hmac_key_context kc; - br_hmac_context hc; - size_t label_len, hlen, u; - - if (len == 0) { - return; - } - buf = dst; - for (label_len = 0; label[label_len]; label_len ++); - hlen = br_digest_size(dig); - br_hmac_key_init(&kc, dig, secret, secret_len); - br_hmac_init(&hc, &kc, 0); - br_hmac_update(&hc, label, label_len); - for (u = 0; u < seed_num; u ++) { - br_hmac_update(&hc, seed[u].data, seed[u].len); - } - br_hmac_out(&hc, a); - for (;;) { - br_hmac_init(&hc, &kc, 0); - br_hmac_update(&hc, a, hlen); - br_hmac_update(&hc, label, label_len); - for (u = 0; u < seed_num; u ++) { - br_hmac_update(&hc, seed[u].data, seed[u].len); - } - br_hmac_out(&hc, tmp); - for (u = 0; u < hlen && u < len; u ++) { - buf[u] ^= tmp[u]; - } - buf += u; - len -= u; - if (len == 0) { - return; - } - br_hmac_init(&hc, &kc, 0); - br_hmac_update(&hc, a, hlen); - br_hmac_out(&hc, a); - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/prf_md5sha1.c b/src/tls/bearssl/prf_md5sha1.c deleted file mode 100644 index 602f71f4e..000000000 --- a/src/tls/bearssl/prf_md5sha1.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl.h */ -void -br_tls10_prf(void *dst, size_t len, - const void *secret, size_t secret_len, const char *label, - size_t seed_num, const br_tls_prf_seed_chunk *seed) -{ - const unsigned char *s1; - size_t slen; - - s1 = secret; - slen = (secret_len + 1) >> 1; - memset(dst, 0, len); - br_tls_phash(dst, len, &br_md5_vtable, - s1, slen, label, seed_num, seed); - br_tls_phash(dst, len, &br_sha1_vtable, - s1 + secret_len - slen, slen, label, seed_num, seed); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/prf_sha256.c b/src/tls/bearssl/prf_sha256.c deleted file mode 100644 index 3a1926ff4..000000000 --- a/src/tls/bearssl/prf_sha256.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl.h */ -void -br_tls12_sha256_prf(void *dst, size_t len, - const void *secret, size_t secret_len, const char *label, - size_t seed_num, const br_tls_prf_seed_chunk *seed) -{ - memset(dst, 0, len); - br_tls_phash(dst, len, &br_sha256_vtable, - secret, secret_len, label, seed_num, seed); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/prf_sha384.c b/src/tls/bearssl/prf_sha384.c deleted file mode 100644 index 9bbf27b3b..000000000 --- a/src/tls/bearssl/prf_sha384.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl.h */ -void -br_tls12_sha384_prf(void *dst, size_t len, - const void *secret, size_t secret_len, const char *label, - size_t seed_num, const br_tls_prf_seed_chunk *seed) -{ - memset(dst, 0, len); - br_tls_phash(dst, len, &br_sha384_vtable, - secret, secret_len, label, seed_num, seed); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_default_keygen.c b/src/tls/bearssl/rsa_default_keygen.c deleted file mode 100644 index 701cf48c2..000000000 --- a/src/tls/bearssl/rsa_default_keygen.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_rsa.h */ -br_rsa_keygen -br_rsa_keygen_get_default(void) -{ -#if BR_INT128 || BR_UMUL128 - return &br_rsa_i62_keygen; -#elif BR_LOMUL - return &br_rsa_i15_keygen; -#else - return &br_rsa_i31_keygen; -#endif -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_default_modulus.c b/src/tls/bearssl/rsa_default_modulus.c deleted file mode 100644 index 5f0ad407d..000000000 --- a/src/tls/bearssl/rsa_default_modulus.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_rsa.h */ -br_rsa_compute_modulus -br_rsa_compute_modulus_get_default(void) -{ -#if BR_LOMUL - return &br_rsa_i15_compute_modulus; -#else - return &br_rsa_i31_compute_modulus; -#endif -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_default_oaep_decrypt.c b/src/tls/bearssl/rsa_default_oaep_decrypt.c deleted file mode 100644 index 5de28e898..000000000 --- a/src/tls/bearssl/rsa_default_oaep_decrypt.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_rsa.h */ -br_rsa_oaep_decrypt -br_rsa_oaep_decrypt_get_default(void) -{ -#if BR_INT128 || BR_UMUL128 - return &br_rsa_i62_oaep_decrypt; -#elif BR_LOMUL - return &br_rsa_i15_oaep_decrypt; -#else - return &br_rsa_i31_oaep_decrypt; -#endif -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_default_oaep_encrypt.c b/src/tls/bearssl/rsa_default_oaep_encrypt.c deleted file mode 100644 index 7dd768557..000000000 --- a/src/tls/bearssl/rsa_default_oaep_encrypt.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_rsa.h */ -br_rsa_oaep_encrypt -br_rsa_oaep_encrypt_get_default(void) -{ -#if BR_INT128 || BR_UMUL128 - return &br_rsa_i62_oaep_encrypt; -#elif BR_LOMUL - return &br_rsa_i15_oaep_encrypt; -#else - return &br_rsa_i31_oaep_encrypt; -#endif -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_default_pkcs1_sign.c b/src/tls/bearssl/rsa_default_pkcs1_sign.c deleted file mode 100644 index bcdfae3c1..000000000 --- a/src/tls/bearssl/rsa_default_pkcs1_sign.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_rsa.h */ -br_rsa_pkcs1_sign -br_rsa_pkcs1_sign_get_default(void) -{ -#if BR_INT128 || BR_UMUL128 - return &br_rsa_i62_pkcs1_sign; -#elif BR_LOMUL - return &br_rsa_i15_pkcs1_sign; -#else - return &br_rsa_i31_pkcs1_sign; -#endif -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_default_pkcs1_vrfy.c b/src/tls/bearssl/rsa_default_pkcs1_vrfy.c deleted file mode 100644 index 75761ae62..000000000 --- a/src/tls/bearssl/rsa_default_pkcs1_vrfy.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_rsa.h */ -br_rsa_pkcs1_vrfy -br_rsa_pkcs1_vrfy_get_default(void) -{ -#if BR_INT128 || BR_UMUL128 - return &br_rsa_i62_pkcs1_vrfy; -#elif BR_LOMUL - return &br_rsa_i15_pkcs1_vrfy; -#else - return &br_rsa_i31_pkcs1_vrfy; -#endif -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_default_priv.c b/src/tls/bearssl/rsa_default_priv.c deleted file mode 100644 index cba2d6252..000000000 --- a/src/tls/bearssl/rsa_default_priv.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_rsa.h */ -br_rsa_private -br_rsa_private_get_default(void) -{ -#if BR_INT128 || BR_UMUL128 - return &br_rsa_i62_private; -#elif BR_LOMUL - return &br_rsa_i15_private; -#else - return &br_rsa_i31_private; -#endif -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_default_privexp.c b/src/tls/bearssl/rsa_default_privexp.c deleted file mode 100644 index f6441ec27..000000000 --- a/src/tls/bearssl/rsa_default_privexp.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_rsa.h */ -br_rsa_compute_privexp -br_rsa_compute_privexp_get_default(void) -{ -#if BR_LOMUL - return &br_rsa_i15_compute_privexp; -#else - return &br_rsa_i31_compute_privexp; -#endif -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_default_pub.c b/src/tls/bearssl/rsa_default_pub.c deleted file mode 100644 index 2a88efba7..000000000 --- a/src/tls/bearssl/rsa_default_pub.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_rsa.h */ -br_rsa_public -br_rsa_public_get_default(void) -{ -#if BR_INT128 || BR_UMUL128 - return &br_rsa_i62_public; -#elif BR_LOMUL - return &br_rsa_i15_public; -#else - return &br_rsa_i31_public; -#endif -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_default_pubexp.c b/src/tls/bearssl/rsa_default_pubexp.c deleted file mode 100644 index 63f05ec15..000000000 --- a/src/tls/bearssl/rsa_default_pubexp.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_rsa.h */ -br_rsa_compute_pubexp -br_rsa_compute_pubexp_get_default(void) -{ -#if BR_LOMUL - return &br_rsa_i15_compute_pubexp; -#else - return &br_rsa_i31_compute_pubexp; -#endif -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_i15_keygen.c b/src/tls/bearssl/rsa_i15_keygen.c deleted file mode 100644 index b602bd8a4..000000000 --- a/src/tls/bearssl/rsa_i15_keygen.c +++ /dev/null @@ -1,588 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * Make a random integer of the provided size. The size is encoded. - * The header word is untouched. - */ -static void -mkrand(const br_prng_class **rng, uint16_t *x, uint32_t esize) -{ - size_t u, len; - unsigned m; - - len = (esize + 15) >> 4; - (*rng)->generate(rng, x + 1, len * sizeof(uint16_t)); - for (u = 1; u < len; u ++) { - x[u] &= 0x7FFF; - } - m = esize & 15; - if (m == 0) { - x[len] &= 0x7FFF; - } else { - x[len] &= 0x7FFF >> (15 - m); - } -} - -/* - * This is the big-endian unsigned representation of the product of - * all small primes from 13 to 1481. - */ -static const unsigned char SMALL_PRIMES[] = { - 0x2E, 0xAB, 0x92, 0xD1, 0x8B, 0x12, 0x47, 0x31, 0x54, 0x0A, - 0x99, 0x5D, 0x25, 0x5E, 0xE2, 0x14, 0x96, 0x29, 0x1E, 0xB7, - 0x78, 0x70, 0xCC, 0x1F, 0xA5, 0xAB, 0x8D, 0x72, 0x11, 0x37, - 0xFB, 0xD8, 0x1E, 0x3F, 0x5B, 0x34, 0x30, 0x17, 0x8B, 0xE5, - 0x26, 0x28, 0x23, 0xA1, 0x8A, 0xA4, 0x29, 0xEA, 0xFD, 0x9E, - 0x39, 0x60, 0x8A, 0xF3, 0xB5, 0xA6, 0xEB, 0x3F, 0x02, 0xB6, - 0x16, 0xC3, 0x96, 0x9D, 0x38, 0xB0, 0x7D, 0x82, 0x87, 0x0C, - 0xF7, 0xBE, 0x24, 0xE5, 0x5F, 0x41, 0x04, 0x79, 0x76, 0x40, - 0xE7, 0x00, 0x22, 0x7E, 0xB5, 0x85, 0x7F, 0x8D, 0x01, 0x50, - 0xE9, 0xD3, 0x29, 0x42, 0x08, 0xB3, 0x51, 0x40, 0x7B, 0xD7, - 0x8D, 0xCC, 0x10, 0x01, 0x64, 0x59, 0x28, 0xB6, 0x53, 0xF3, - 0x50, 0x4E, 0xB1, 0xF2, 0x58, 0xCD, 0x6E, 0xF5, 0x56, 0x3E, - 0x66, 0x2F, 0xD7, 0x07, 0x7F, 0x52, 0x4C, 0x13, 0x24, 0xDC, - 0x8E, 0x8D, 0xCC, 0xED, 0x77, 0xC4, 0x21, 0xD2, 0xFD, 0x08, - 0xEA, 0xD7, 0xC0, 0x5C, 0x13, 0x82, 0x81, 0x31, 0x2F, 0x2B, - 0x08, 0xE4, 0x80, 0x04, 0x7A, 0x0C, 0x8A, 0x3C, 0xDC, 0x22, - 0xE4, 0x5A, 0x7A, 0xB0, 0x12, 0x5E, 0x4A, 0x76, 0x94, 0x77, - 0xC2, 0x0E, 0x92, 0xBA, 0x8A, 0xA0, 0x1F, 0x14, 0x51, 0x1E, - 0x66, 0x6C, 0x38, 0x03, 0x6C, 0xC7, 0x4A, 0x4B, 0x70, 0x80, - 0xAF, 0xCA, 0x84, 0x51, 0xD8, 0xD2, 0x26, 0x49, 0xF5, 0xA8, - 0x5E, 0x35, 0x4B, 0xAC, 0xCE, 0x29, 0x92, 0x33, 0xB7, 0xA2, - 0x69, 0x7D, 0x0C, 0xE0, 0x9C, 0xDB, 0x04, 0xD6, 0xB4, 0xBC, - 0x39, 0xD7, 0x7F, 0x9E, 0x9D, 0x78, 0x38, 0x7F, 0x51, 0x54, - 0x50, 0x8B, 0x9E, 0x9C, 0x03, 0x6C, 0xF5, 0x9D, 0x2C, 0x74, - 0x57, 0xF0, 0x27, 0x2A, 0xC3, 0x47, 0xCA, 0xB9, 0xD7, 0x5C, - 0xFF, 0xC2, 0xAC, 0x65, 0x4E, 0xBD -}; - -/* - * We need temporary values for at least 7 integers of the same size - * as a factor (including header word); more space helps with performance - * (in modular exponentiations), but we much prefer to remain under - * 2 kilobytes in total, to save stack space. The macro TEMPS below - * exceeds 1024 (which is a count in 16-bit words) when BR_MAX_RSA_SIZE - * is greater than 4350 (default value is 4096, so the 2-kB limit is - * maintained unless BR_MAX_RSA_SIZE was modified). - */ -#define MAX(x, y) ((x) > (y) ? (x) : (y)) -#define TEMPS MAX(1024, 7 * ((((BR_MAX_RSA_SIZE + 1) >> 1) + 29) / 15)) - -/* - * Perform trial division on a candidate prime. This computes - * y = SMALL_PRIMES mod x, then tries to compute y/y mod x. The - * br_i15_moddiv() function will report an error if y is not invertible - * modulo x. Returned value is 1 on success (none of the small primes - * divides x), 0 on error (a non-trivial GCD is obtained). - * - * This function assumes that x is odd. - */ -static uint32_t -trial_divisions(const uint16_t *x, uint16_t *t) -{ - uint16_t *y; - uint16_t x0i; - - y = t; - t += 1 + ((x[0] + 15) >> 4); - x0i = br_i15_ninv15(x[1]); - br_i15_decode_reduce(y, SMALL_PRIMES, sizeof SMALL_PRIMES, x); - return br_i15_moddiv(y, y, x, x0i, t); -} - -/* - * Perform n rounds of Miller-Rabin on the candidate prime x. This - * function assumes that x = 3 mod 4. - * - * Returned value is 1 on success (all rounds completed successfully), - * 0 otherwise. - */ -static uint32_t -miller_rabin(const br_prng_class **rng, const uint16_t *x, int n, - uint16_t *t, size_t tlen) -{ - /* - * Since x = 3 mod 4, the Miller-Rabin test is simple: - * - get a random base a (such that 1 < a < x-1) - * - compute z = a^((x-1)/2) mod x - * - if z != 1 and z != x-1, the number x is composite - * - * We generate bases 'a' randomly with a size which is - * one bit less than x, which ensures that a < x-1. It - * is not useful to verify that a > 1 because the probability - * that we get a value a equal to 0 or 1 is much smaller - * than the probability of our Miller-Rabin tests not to - * detect a composite, which is already quite smaller than the - * probability of the hardware misbehaving and return a - * composite integer because of some glitch (e.g. bad RAM - * or ill-timed cosmic ray). - */ - unsigned char *xm1d2; - size_t xlen, xm1d2_len, xm1d2_len_u16, u; - uint32_t asize; - unsigned cc; - uint16_t x0i; - - /* - * Compute (x-1)/2 (encoded). - */ - xm1d2 = (unsigned char *)t; - xm1d2_len = ((x[0] - (x[0] >> 4)) + 7) >> 3; - br_i15_encode(xm1d2, xm1d2_len, x); - cc = 0; - for (u = 0; u < xm1d2_len; u ++) { - unsigned w; - - w = xm1d2[u]; - xm1d2[u] = (unsigned char)((w >> 1) | cc); - cc = w << 7; - } - - /* - * We used some words of the provided buffer for (x-1)/2. - */ - xm1d2_len_u16 = (xm1d2_len + 1) >> 1; - t += xm1d2_len_u16; - tlen -= xm1d2_len_u16; - - xlen = (x[0] + 15) >> 4; - asize = x[0] - 1 - EQ0(x[0] & 15); - x0i = br_i15_ninv15(x[1]); - while (n -- > 0) { - uint16_t *a; - uint32_t eq1, eqm1; - - /* - * Generate a random base. We don't need the base to be - * really uniform modulo x, so we just get a random - * number which is one bit shorter than x. - */ - a = t; - a[0] = x[0]; - a[xlen] = 0; - mkrand(rng, a, asize); - - /* - * Compute a^((x-1)/2) mod x. We assume here that the - * function will not fail (the temporary array is large - * enough). - */ - br_i15_modpow_opt(a, xm1d2, xm1d2_len, - x, x0i, t + 1 + xlen, tlen - 1 - xlen); - - /* - * We must obtain either 1 or x-1. Note that x is odd, - * hence x-1 differs from x only in its low word (no - * carry). - */ - eq1 = a[1] ^ 1; - eqm1 = a[1] ^ (x[1] - 1); - for (u = 2; u <= xlen; u ++) { - eq1 |= a[u]; - eqm1 |= a[u] ^ x[u]; - } - - if ((EQ0(eq1) | EQ0(eqm1)) == 0) { - return 0; - } - } - return 1; -} - -/* - * Create a random prime of the provided size. 'size' is the _encoded_ - * bit length. The two top bits and the two bottom bits are set to 1. - */ -static void -mkprime(const br_prng_class **rng, uint16_t *x, uint32_t esize, - uint32_t pubexp, uint16_t *t, size_t tlen) -{ - size_t len; - - x[0] = esize; - len = (esize + 15) >> 4; - for (;;) { - size_t u; - uint32_t m3, m5, m7, m11; - int rounds; - - /* - * Generate random bits. We force the two top bits and the - * two bottom bits to 1. - */ - mkrand(rng, x, esize); - if ((esize & 15) == 0) { - x[len] |= 0x6000; - } else if ((esize & 15) == 1) { - x[len] |= 0x0001; - x[len - 1] |= 0x4000; - } else { - x[len] |= 0x0003 << ((esize & 15) - 2); - } - x[1] |= 0x0003; - - /* - * Trial division with low primes (3, 5, 7 and 11). We - * use the following properties: - * - * 2^2 = 1 mod 3 - * 2^4 = 1 mod 5 - * 2^3 = 1 mod 7 - * 2^10 = 1 mod 11 - */ - m3 = 0; - m5 = 0; - m7 = 0; - m11 = 0; - for (u = 0; u < len; u ++) { - uint32_t w; - - w = x[1 + u]; - m3 += w << (u & 1); - m3 = (m3 & 0xFF) + (m3 >> 8); - m5 += w << ((4 - u) & 3); - m5 = (m5 & 0xFF) + (m5 >> 8); - m7 += w; - m7 = (m7 & 0x1FF) + (m7 >> 9); - m11 += w << (5 & -(u & 1)); - m11 = (m11 & 0x3FF) + (m11 >> 10); - } - - /* - * Maximum values of m* at this point: - * m3: 511 - * m5: 2310 - * m7: 510 - * m11: 2047 - * We use the same properties to make further reductions. - */ - - m3 = (m3 & 0x0F) + (m3 >> 4); /* max: 46 */ - m3 = (m3 & 0x0F) + (m3 >> 4); /* max: 16 */ - m3 = ((m3 * 43) >> 5) & 3; - - m5 = (m5 & 0xFF) + (m5 >> 8); /* max: 263 */ - m5 = (m5 & 0x0F) + (m5 >> 4); /* max: 30 */ - m5 = (m5 & 0x0F) + (m5 >> 4); /* max: 15 */ - m5 -= 10 & -GT(m5, 9); - m5 -= 5 & -GT(m5, 4); - - m7 = (m7 & 0x3F) + (m7 >> 6); /* max: 69 */ - m7 = (m7 & 7) + (m7 >> 3); /* max: 14 */ - m7 = ((m7 * 147) >> 7) & 7; - - /* - * 2^5 = 32 = -1 mod 11. - */ - m11 = (m11 & 0x1F) + 66 - (m11 >> 5); /* max: 97 */ - m11 -= 88 & -GT(m11, 87); - m11 -= 44 & -GT(m11, 43); - m11 -= 22 & -GT(m11, 21); - m11 -= 11 & -GT(m11, 10); - - /* - * If any of these modulo is 0, then the candidate is - * not prime. Also, if pubexp is 3, 5, 7 or 11, and the - * corresponding modulus is 1, then the candidate must - * be rejected, because we need e to be invertible - * modulo p-1. We can use simple comparisons here - * because they won't leak information on a candidate - * that we keep, only on one that we reject (and is thus - * not secret). - */ - if (m3 == 0 || m5 == 0 || m7 == 0 || m11 == 0) { - continue; - } - if ((pubexp == 3 && m3 == 1) - || (pubexp == 5 && m5 == 5) - || (pubexp == 7 && m5 == 7) - || (pubexp == 11 && m5 == 11)) - { - continue; - } - - /* - * More trial divisions. - */ - if (!trial_divisions(x, t)) { - continue; - } - - /* - * Miller-Rabin algorithm. Since we selected a random - * integer, not a maliciously crafted integer, we can use - * relatively few rounds to lower the risk of a false - * positive (i.e. declaring prime a non-prime) under - * 2^(-80). It is not useful to lower the probability much - * below that, since that would be substantially below - * the probability of the hardware misbehaving. Sufficient - * numbers of rounds are extracted from the Handbook of - * Applied Cryptography, note 4.49 (page 149). - * - * Since we work on the encoded size (esize), we need to - * compare with encoded thresholds. - */ - if (esize < 320) { - rounds = 12; - } else if (esize < 480) { - rounds = 9; - } else if (esize < 693) { - rounds = 6; - } else if (esize < 906) { - rounds = 4; - } else if (esize < 1386) { - rounds = 3; - } else { - rounds = 2; - } - - if (miller_rabin(rng, x, rounds, t, tlen)) { - return; - } - } -} - -/* - * Let p be a prime (p > 2^33, p = 3 mod 4). Let m = (p-1)/2, provided - * as parameter (with announced bit length equal to that of p). This - * function computes d = 1/e mod p-1 (for an odd integer e). Returned - * value is 1 on success, 0 on error (an error is reported if e is not - * invertible modulo p-1). - * - * The temporary buffer (t) must have room for at least 4 integers of - * the size of p. - */ -static uint32_t -invert_pubexp(uint16_t *d, const uint16_t *m, uint32_t e, uint16_t *t) -{ - uint16_t *f; - uint32_t r; - - f = t; - t += 1 + ((m[0] + 15) >> 4); - - /* - * Compute d = 1/e mod m. Since p = 3 mod 4, m is odd. - */ - br_i15_zero(d, m[0]); - d[1] = 1; - br_i15_zero(f, m[0]); - f[1] = e & 0x7FFF; - f[2] = (e >> 15) & 0x7FFF; - f[3] = e >> 30; - r = br_i15_moddiv(d, f, m, br_i15_ninv15(m[1]), t); - - /* - * We really want d = 1/e mod p-1, with p = 2m. By the CRT, - * the result is either the d we got, or d + m. - * - * Let's write e*d = 1 + k*m, for some integer k. Integers e - * and m are odd. If d is odd, then e*d is odd, which implies - * that k must be even; in that case, e*d = 1 + (k/2)*2m, and - * thus d is already fine. Conversely, if d is even, then k - * is odd, and we must add m to d in order to get the correct - * result. - */ - br_i15_add(d, m, (uint32_t)(1 - (d[1] & 1))); - - return r; -} - -/* - * Swap two buffers in RAM. They must be disjoint. - */ -static void -bufswap(void *b1, void *b2, size_t len) -{ - size_t u; - unsigned char *buf1, *buf2; - - buf1 = b1; - buf2 = b2; - for (u = 0; u < len; u ++) { - unsigned w; - - w = buf1[u]; - buf1[u] = buf2[u]; - buf2[u] = w; - } -} - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i15_keygen(const br_prng_class **rng, - br_rsa_private_key *sk, void *kbuf_priv, - br_rsa_public_key *pk, void *kbuf_pub, - unsigned size, uint32_t pubexp) -{ - uint32_t esize_p, esize_q; - size_t plen, qlen, tlen; - uint16_t *p, *q, *t; - uint16_t tmp[TEMPS]; - uint32_t r; - - if (size < BR_MIN_RSA_SIZE || size > BR_MAX_RSA_SIZE) { - return 0; - } - if (pubexp == 0) { - pubexp = 3; - } else if (pubexp == 1 || (pubexp & 1) == 0) { - return 0; - } - - esize_p = (size + 1) >> 1; - esize_q = size - esize_p; - sk->n_bitlen = size; - sk->p = kbuf_priv; - sk->plen = (esize_p + 7) >> 3; - sk->q = sk->p + sk->plen; - sk->qlen = (esize_q + 7) >> 3; - sk->dp = sk->q + sk->qlen; - sk->dplen = sk->plen; - sk->dq = sk->dp + sk->dplen; - sk->dqlen = sk->qlen; - sk->iq = sk->dq + sk->dqlen; - sk->iqlen = sk->plen; - - if (pk != NULL) { - pk->n = kbuf_pub; - pk->nlen = (size + 7) >> 3; - pk->e = pk->n + pk->nlen; - pk->elen = 4; - br_enc32be(pk->e, pubexp); - while (*pk->e == 0) { - pk->e ++; - pk->elen --; - } - } - - /* - * We now switch to encoded sizes. - * - * floor((x * 17477) / (2^18)) is equal to floor(x/15) for all - * integers x from 0 to 23833. - */ - esize_p += MUL15(esize_p, 17477) >> 18; - esize_q += MUL15(esize_q, 17477) >> 18; - plen = (esize_p + 15) >> 4; - qlen = (esize_q + 15) >> 4; - p = tmp; - q = p + 1 + plen; - t = q + 1 + qlen; - tlen = ((sizeof tmp) / sizeof(uint16_t)) - (2 + plen + qlen); - - /* - * When looking for primes p and q, we temporarily divide - * candidates by 2, in order to compute the inverse of the - * public exponent. - */ - - for (;;) { - mkprime(rng, p, esize_p, pubexp, t, tlen); - br_i15_rshift(p, 1); - if (invert_pubexp(t, p, pubexp, t + 1 + plen)) { - br_i15_add(p, p, 1); - p[1] |= 1; - br_i15_encode(sk->p, sk->plen, p); - br_i15_encode(sk->dp, sk->dplen, t); - break; - } - } - - for (;;) { - mkprime(rng, q, esize_q, pubexp, t, tlen); - br_i15_rshift(q, 1); - if (invert_pubexp(t, q, pubexp, t + 1 + qlen)) { - br_i15_add(q, q, 1); - q[1] |= 1; - br_i15_encode(sk->q, sk->qlen, q); - br_i15_encode(sk->dq, sk->dqlen, t); - break; - } - } - - /* - * If p and q have the same size, then it is possible that q > p - * (when the target modulus size is odd, we generate p with a - * greater bit length than q). If q > p, we want to swap p and q - * (and also dp and dq) for two reasons: - * - The final step below (inversion of q modulo p) is easier if - * p > q. - * - While BearSSL's RSA code is perfectly happy with RSA keys such - * that p < q, some other implementations have restrictions and - * require p > q. - * - * Note that we can do a simple non-constant-time swap here, - * because the only information we leak here is that we insist on - * returning p and q such that p > q, which is not a secret. - */ - if (esize_p == esize_q && br_i15_sub(p, q, 0) == 1) { - bufswap(p, q, (1 + plen) * sizeof *p); - bufswap(sk->p, sk->q, sk->plen); - bufswap(sk->dp, sk->dq, sk->dplen); - } - - /* - * We have produced p, q, dp and dq. We can now compute iq = 1/d mod p. - * - * We ensured that p >= q, so this is just a matter of updating the - * header word for q (and possibly adding an extra word). - * - * Theoretically, the call below may fail, in case we were - * extraordinarily unlucky, and p = q. Another failure case is if - * Miller-Rabin failed us _twice_, and p and q are non-prime and - * have a factor is common. We report the error mostly because it - * is cheap and we can, but in practice this never happens (or, at - * least, it happens way less often than hardware glitches). - */ - q[0] = p[0]; - if (plen > qlen) { - q[plen] = 0; - t ++; - tlen --; - } - br_i15_zero(t, p[0]); - t[1] = 1; - r = br_i15_moddiv(t, q, p, br_i15_ninv15(p[1]), t + 1 + plen); - br_i15_encode(sk->iq, sk->iqlen, t); - - /* - * Compute the public modulus too, if required. - */ - if (pk != NULL) { - br_i15_zero(t, p[0]); - br_i15_mulacc(t, p, q); - br_i15_encode(pk->n, pk->nlen, t); - } - - return r; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_i15_modulus.c b/src/tls/bearssl/rsa_i15_modulus.c deleted file mode 100644 index 3f572fbdc..000000000 --- a/src/tls/bearssl/rsa_i15_modulus.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_rsa.h */ -size_t -br_rsa_i15_compute_modulus(void *n, const br_rsa_private_key *sk) -{ - uint16_t tmp[2 * ((BR_MAX_RSA_SIZE + 14) / 15) + 5]; - uint16_t *t, *p, *q; - const unsigned char *pbuf, *qbuf; - size_t nlen, plen, qlen, tlen; - - /* - * Compute actual byte and lengths for p and q. - */ - pbuf = sk->p; - plen = sk->plen; - while (plen > 0 && *pbuf == 0) { - pbuf ++; - plen --; - } - qbuf = sk->q; - qlen = sk->qlen; - while (qlen > 0 && *qbuf == 0) { - qbuf ++; - qlen --; - } - - t = tmp; - tlen = (sizeof tmp) / (sizeof tmp[0]); - - /* - * Decode p. - */ - if ((15 * tlen) < (plen << 3) + 15) { - return 0; - } - br_i15_decode(t, pbuf, plen); - p = t; - plen = (p[0] + 31) >> 4; - t += plen; - tlen -= plen; - - /* - * Decode q. - */ - if ((15 * tlen) < (qlen << 3) + 15) { - return 0; - } - br_i15_decode(t, qbuf, qlen); - q = t; - qlen = (q[0] + 31) >> 4; - t += qlen; - tlen -= qlen; - - /* - * Computation can proceed only if we have enough room for the - * modulus. - */ - if (tlen < (plen + qlen + 1)) { - return 0; - } - - /* - * Private key already contains the modulus bit length, from which - * we can infer the output length. Even if n is NULL, we still had - * to decode p and q to make sure that the product can be computed. - */ - nlen = (sk->n_bitlen + 7) >> 3; - if (n != NULL) { - br_i15_zero(t, p[0]); - br_i15_mulacc(t, p, q); - br_i15_encode(n, nlen, t); - } - return nlen; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_i15_oaep_decrypt.c b/src/tls/bearssl/rsa_i15_oaep_decrypt.c deleted file mode 100644 index dd578797f..000000000 --- a/src/tls/bearssl/rsa_i15_oaep_decrypt.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i15_oaep_decrypt(const br_hash_class *dig, - const void *label, size_t label_len, - const br_rsa_private_key *sk, void *data, size_t *len) -{ - uint32_t r; - - if (*len != ((sk->n_bitlen + 7) >> 3)) { - return 0; - } - r = br_rsa_i15_private(data, sk); - r &= br_rsa_oaep_unpad(dig, label, label_len, data, len); - return r; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_i15_oaep_encrypt.c b/src/tls/bearssl/rsa_i15_oaep_encrypt.c deleted file mode 100644 index 6a3bb53f5..000000000 --- a/src/tls/bearssl/rsa_i15_oaep_encrypt.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_rsa.h */ -size_t -br_rsa_i15_oaep_encrypt( - const br_prng_class **rnd, const br_hash_class *dig, - const void *label, size_t label_len, - const br_rsa_public_key *pk, - void *dst, size_t dst_max_len, - const void *src, size_t src_len) -{ - size_t dlen; - - dlen = br_rsa_oaep_pad(rnd, dig, label, label_len, - pk, dst, dst_max_len, src, src_len); - if (dlen == 0) { - return 0; - } - return dlen & -(size_t)br_rsa_i15_public(dst, dlen, pk); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_i15_pkcs1_sign.c b/src/tls/bearssl/rsa_i15_pkcs1_sign.c deleted file mode 100644 index d4ef09fd6..000000000 --- a/src/tls/bearssl/rsa_i15_pkcs1_sign.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i15_pkcs1_sign(const unsigned char *hash_oid, - const unsigned char *hash, size_t hash_len, - const br_rsa_private_key *sk, unsigned char *x) -{ - if (!br_rsa_pkcs1_sig_pad(hash_oid, hash, hash_len, sk->n_bitlen, x)) { - return 0; - } - return br_rsa_i15_private(x, sk); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_i15_pkcs1_vrfy.c b/src/tls/bearssl/rsa_i15_pkcs1_vrfy.c deleted file mode 100644 index 840cc440a..000000000 --- a/src/tls/bearssl/rsa_i15_pkcs1_vrfy.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i15_pkcs1_vrfy(const unsigned char *x, size_t xlen, - const unsigned char *hash_oid, size_t hash_len, - const br_rsa_public_key *pk, unsigned char *hash_out) -{ - unsigned char sig[BR_MAX_RSA_SIZE >> 3]; - - if (xlen > (sizeof sig)) { - return 0; - } - memcpy(sig, x, xlen); - if (!br_rsa_i15_public(sig, xlen, pk)) { - return 0; - } - return br_rsa_pkcs1_sig_unpad(sig, xlen, hash_oid, hash_len, hash_out); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_i15_priv.c b/src/tls/bearssl/rsa_i15_priv.c deleted file mode 100644 index 1c50fba88..000000000 --- a/src/tls/bearssl/rsa_i15_priv.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -#define U (2 + ((BR_MAX_RSA_FACTOR + 14) / 15)) -#define TLEN (8 * U) - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i15_private(unsigned char *x, const br_rsa_private_key *sk) -{ - const unsigned char *p, *q; - size_t plen, qlen; - size_t fwlen; - uint16_t p0i, q0i; - size_t xlen, u; - uint16_t tmp[1 + TLEN]; - long z; - uint16_t *mp, *mq, *s1, *s2, *t1, *t2, *t3; - uint32_t r; - - /* - * Compute the actual lengths of p and q, in bytes. - * These lengths are not considered secret (we cannot really hide - * them anyway in constant-time code). - */ - p = sk->p; - plen = sk->plen; - while (plen > 0 && *p == 0) { - p ++; - plen --; - } - q = sk->q; - qlen = sk->qlen; - while (qlen > 0 && *q == 0) { - q ++; - qlen --; - } - - /* - * Compute the maximum factor length, in words. - */ - z = (long)(plen > qlen ? plen : qlen) << 3; - fwlen = 1; - while (z > 0) { - z -= 15; - fwlen ++; - } - /* - * Round up the word length to an even number. - */ - fwlen += (fwlen & 1); - - /* - * We need to fit at least 6 values in the stack buffer. - */ - if (6 * fwlen > TLEN) { - return 0; - } - - /* - * Compute signature length (in bytes). - */ - xlen = (sk->n_bitlen + 7) >> 3; - - /* - * Ensure 32-bit alignment for value words. - */ - mq = tmp; - if (((uintptr_t)mq & 2) == 0) { - mq ++; - } - - /* - * Decode q. - */ - br_i15_decode(mq, q, qlen); - - /* - * Decode p. - */ - t1 = mq + fwlen; - br_i15_decode(t1, p, plen); - - /* - * Compute the modulus (product of the two factors), to compare - * it with the source value. We use br_i15_mulacc(), since it's - * already used later on. - */ - t2 = mq + 2 * fwlen; - br_i15_zero(t2, mq[0]); - br_i15_mulacc(t2, mq, t1); - - /* - * We encode the modulus into bytes, to perform the comparison - * with bytes. We know that the product length, in bytes, is - * exactly xlen. - * The comparison actually computes the carry when subtracting - * the modulus from the source value; that carry must be 1 for - * a value in the correct range. We keep it in r, which is our - * accumulator for the error code. - */ - t3 = mq + 4 * fwlen; - br_i15_encode(t3, xlen, t2); - u = xlen; - r = 0; - while (u > 0) { - uint32_t wn, wx; - - u --; - wn = ((unsigned char *)t3)[u]; - wx = x[u]; - r = ((wx - (wn + r)) >> 8) & 1; - } - - /* - * Move the decoded p to another temporary buffer. - */ - mp = mq + 2 * fwlen; - memmove(mp, t1, fwlen * sizeof *t1); - - /* - * Compute s2 = x^dq mod q. - */ - q0i = br_i15_ninv15(mq[1]); - s2 = mq + fwlen; - br_i15_decode_reduce(s2, x, xlen, mq); - r &= br_i15_modpow_opt(s2, sk->dq, sk->dqlen, mq, q0i, - mq + 3 * fwlen, TLEN - 3 * fwlen); - - /* - * Compute s1 = x^dq mod q. - */ - p0i = br_i15_ninv15(mp[1]); - s1 = mq + 3 * fwlen; - br_i15_decode_reduce(s1, x, xlen, mp); - r &= br_i15_modpow_opt(s1, sk->dp, sk->dplen, mp, p0i, - mq + 4 * fwlen, TLEN - 4 * fwlen); - - /* - * Compute: - * h = (s1 - s2)*(1/q) mod p - * s1 is an integer modulo p, but s2 is modulo q. PKCS#1 is - * unclear about whether p may be lower than q (some existing, - * widely deployed implementations of RSA don't tolerate p < q), - * but we want to support that occurrence, so we need to use the - * reduction function. - * - * Since we use br_i15_decode_reduce() for iq (purportedly, the - * inverse of q modulo p), we also tolerate improperly large - * values for this parameter. - */ - t1 = mq + 4 * fwlen; - t2 = mq + 5 * fwlen; - br_i15_reduce(t2, s2, mp); - br_i15_add(s1, mp, br_i15_sub(s1, t2, 1)); - br_i15_to_monty(s1, mp); - br_i15_decode_reduce(t1, sk->iq, sk->iqlen, mp); - br_i15_montymul(t2, s1, t1, mp, p0i); - - /* - * h is now in t2. We compute the final result: - * s = s2 + q*h - * All these operations are non-modular. - * - * We need mq, s2 and t2. We use the t3 buffer as destination. - * The buffers mp, s1 and t1 are no longer needed, so we can - * reuse them for t3. Moreover, the first step of the computation - * is to copy s2 into t3, after which s2 is not needed. Right - * now, mq is in slot 0, s2 is in slot 1, and t2 in slot 5. - * Therefore, we have ample room for t3 by simply using s2. - */ - t3 = s2; - br_i15_mulacc(t3, mq, t2); - - /* - * Encode the result. Since we already checked the value of xlen, - * we can just use it right away. - */ - br_i15_encode(x, xlen, t3); - - /* - * The only error conditions remaining at that point are invalid - * values for p and q (even integers). - */ - return p0i & q0i & r; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_i15_privexp.c b/src/tls/bearssl/rsa_i15_privexp.c deleted file mode 100644 index ec740b357..000000000 --- a/src/tls/bearssl/rsa_i15_privexp.c +++ /dev/null @@ -1,325 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_rsa.h */ -size_t -br_rsa_i15_compute_privexp(void *d, - const br_rsa_private_key *sk, uint32_t e) -{ - /* - * We want to invert e modulo phi = (p-1)(q-1). This first - * requires computing phi, which is easy since we have the factors - * p and q in the private key structure. - * - * Since p = 3 mod 4 and q = 3 mod 4, phi/4 is an odd integer. - * We could invert e modulo phi/4 then patch the result to - * modulo phi, but this would involve assembling three modulus-wide - * values (phi/4, 1 and e) and calling moddiv, that requires - * three more temporaries, for a total of six big integers, or - * slightly more than 3 kB of stack space for RSA-4096. This - * exceeds our stack requirements. - * - * Instead, we first use one step of the extended GCD: - * - * - We compute phi = k*e + r (Euclidean division of phi by e). - * If public exponent e is correct, then r != 0 (e must be - * invertible modulo phi). We also have k != 0 since we - * enforce non-ridiculously-small factors. - * - * - We find small u, v such that u*e - v*r = 1 (using a - * binary GCD; we can arrange for u < r and v < e, i.e. all - * values fit on 32 bits). - * - * - Solution is: d = u + v*k - * This last computation is exact: since u < r and v < e, - * the above implies d < r + e*((phi-r)/e) = phi - */ - - uint16_t tmp[4 * ((BR_MAX_RSA_FACTOR + 14) / 15) + 12]; - uint16_t *p, *q, *k, *m, *z, *phi; - const unsigned char *pbuf, *qbuf; - size_t plen, qlen, u, len, dlen; - uint32_t r, a, b, u0, v0, u1, v1, he, hr; - int i; - - /* - * Check that e is correct. - */ - if (e < 3 || (e & 1) == 0) { - return 0; - } - - /* - * Check lengths of p and q, and that they are both odd. - */ - pbuf = sk->p; - plen = sk->plen; - while (plen > 0 && *pbuf == 0) { - pbuf ++; - plen --; - } - if (plen < 5 || plen > (BR_MAX_RSA_FACTOR / 8) - || (pbuf[plen - 1] & 1) != 1) - { - return 0; - } - qbuf = sk->q; - qlen = sk->qlen; - while (qlen > 0 && *qbuf == 0) { - qbuf ++; - qlen --; - } - if (qlen < 5 || qlen > (BR_MAX_RSA_FACTOR / 8) - || (qbuf[qlen - 1] & 1) != 1) - { - return 0; - } - - /* - * Output length is that of the modulus. - */ - dlen = (sk->n_bitlen + 7) >> 3; - if (d == NULL) { - return dlen; - } - - p = tmp; - br_i15_decode(p, pbuf, plen); - plen = (p[0] + 15) >> 4; - q = p + 1 + plen; - br_i15_decode(q, qbuf, qlen); - qlen = (q[0] + 15) >> 4; - - /* - * Compute phi = (p-1)*(q-1), then move it over p-1 and q-1 (that - * we do not need anymore). The mulacc function sets the announced - * bit length of t to be the sum of the announced bit lengths of - * p-1 and q-1, which is usually exact but may overshoot by one 1 - * bit in some cases; we readjust it to its true length. - */ - p[1] --; - q[1] --; - phi = q + 1 + qlen; - br_i15_zero(phi, p[0]); - br_i15_mulacc(phi, p, q); - len = (phi[0] + 15) >> 4; - memmove(tmp, phi, (1 + len) * sizeof *phi); - phi = tmp; - phi[0] = br_i15_bit_length(phi + 1, len); - len = (phi[0] + 15) >> 4; - - /* - * Divide phi by public exponent e. The final remainder r must be - * non-zero (otherwise, the key is invalid). The quotient is k, - * which we write over phi, since we don't need phi after that. - */ - r = 0; - for (u = len; u >= 1; u --) { - /* - * Upon entry, r < e, and phi[u] < 2^15; hence, - * hi:lo < e*2^15. Thus, the produced word k[u] - * must be lower than 2^15, and the new remainder r - * is lower than e. - */ - uint32_t hi, lo; - - hi = r >> 17; - lo = (r << 15) + phi[u]; - phi[u] = br_divrem(hi, lo, e, &r); - } - if (r == 0) { - return 0; - } - k = phi; - - /* - * Compute u and v such that u*e - v*r = GCD(e,r). We use - * a binary GCD algorithm, with 6 extra integers a, b, - * u0, u1, v0 and v1. Initial values are: - * a = e u0 = 1 v0 = 0 - * b = r u1 = r v1 = e-1 - * The following invariants are maintained: - * a = u0*e - v0*r - * b = u1*e - v1*r - * 0 < a <= e - * 0 < b <= r - * 0 <= u0 <= r - * 0 <= v0 <= e - * 0 <= u1 <= r - * 0 <= v1 <= e - * - * At each iteration, we reduce either a or b by one bit, and - * adjust u0, u1, v0 and v1 to maintain the invariants: - * - if a is even, then a <- a/2 - * - otherwise, if b is even, then b <- b/2 - * - otherwise, if a > b, then a <- (a-b)/2 - * - otherwise, if b > a, then b <- (b-a)/2 - * Algorithm stops when a = b. At that point, the common value - * is the GCD of e and r; it must be 1 (otherwise, the private - * key or public exponent is not valid). The (u0,v0) or (u1,v1) - * pairs are the solution we are looking for. - * - * Since either a or b is reduced by at least 1 bit at each - * iteration, 62 iterations are enough to reach the end - * condition. - * - * To maintain the invariants, we must compute the same operations - * on the u* and v* values that we do on a and b: - * - When a is divided by 2, u0 and v0 must be divided by 2. - * - When b is divided by 2, u1 and v1 must be divided by 2. - * - When b is subtracted from a, u1 and v1 are subtracted from - * u0 and v0, respectively. - * - When a is subtracted from b, u0 and v0 are subtracted from - * u1 and v1, respectively. - * - * However, we want to keep the u* and v* values in their proper - * ranges. The following remarks apply: - * - * - When a is divided by 2, then a is even. Therefore: - * - * * If r is odd, then u0 and v0 must have the same parity; - * if they are both odd, then adding r to u0 and e to v0 - * makes them both even, and the division by 2 brings them - * back to the proper range. - * - * * If r is even, then u0 must be even; if v0 is odd, then - * adding r to u0 and e to v0 makes them both even, and the - * division by 2 brings them back to the proper range. - * - * Thus, all we need to do is to look at the parity of v0, - * and add (r,e) to (u0,v0) when v0 is odd. In order to avoid - * a 32-bit overflow, we can add ((r+1)/2,(e/2)+1) after the - * division (r+1 does not overflow since r < e; and (e/2)+1 - * is equal to (e+1)/2 since e is odd). - * - * - When we subtract b from a, three cases may occur: - * - * * u1 <= u0 and v1 <= v0: just do the subtractions - * - * * u1 > u0 and v1 > v0: compute: - * (u0, v0) <- (u0 + r - u1, v0 + e - v1) - * - * * u1 <= u0 and v1 > v0: compute: - * (u0, v0) <- (u0 + r - u1, v0 + e - v1) - * - * The fourth case (u1 > u0 and v1 <= v0) is not possible - * because it would contradict "b < a" (which is the reason - * why we subtract b from a). - * - * The tricky case is the third one: from the equations, it - * seems that u0 may go out of range. However, the invariants - * and ranges of other values imply that, in that case, the - * new u0 does not actually exceed the range. - * - * We can thus handle the subtraction by adding (r,e) based - * solely on the comparison between v0 and v1. - */ - a = e; - b = r; - u0 = 1; - v0 = 0; - u1 = r; - v1 = e - 1; - hr = (r + 1) >> 1; - he = (e >> 1) + 1; - for (i = 0; i < 62; i ++) { - uint32_t oa, ob, agtb, bgta; - uint32_t sab, sba, da, db; - uint32_t ctl; - - oa = a & 1; /* 1 if a is odd */ - ob = b & 1; /* 1 if b is odd */ - agtb = GT(a, b); /* 1 if a > b */ - bgta = GT(b, a); /* 1 if b > a */ - - sab = oa & ob & agtb; /* 1 if a <- a-b */ - sba = oa & ob & bgta; /* 1 if b <- b-a */ - - /* a <- a-b, u0 <- u0-u1, v0 <- v0-v1 */ - ctl = GT(v1, v0); - a -= b & -sab; - u0 -= (u1 - (r & -ctl)) & -sab; - v0 -= (v1 - (e & -ctl)) & -sab; - - /* b <- b-a, u1 <- u1-u0 mod r, v1 <- v1-v0 mod e */ - ctl = GT(v0, v1); - b -= a & -sba; - u1 -= (u0 - (r & -ctl)) & -sba; - v1 -= (v0 - (e & -ctl)) & -sba; - - da = NOT(oa) | sab; /* 1 if a <- a/2 */ - db = (oa & NOT(ob)) | sba; /* 1 if b <- b/2 */ - - /* a <- a/2, u0 <- u0/2, v0 <- v0/2 */ - ctl = v0 & 1; - a ^= (a ^ (a >> 1)) & -da; - u0 ^= (u0 ^ ((u0 >> 1) + (hr & -ctl))) & -da; - v0 ^= (v0 ^ ((v0 >> 1) + (he & -ctl))) & -da; - - /* b <- b/2, u1 <- u1/2 mod r, v1 <- v1/2 mod e */ - ctl = v1 & 1; - b ^= (b ^ (b >> 1)) & -db; - u1 ^= (u1 ^ ((u1 >> 1) + (hr & -ctl))) & -db; - v1 ^= (v1 ^ ((v1 >> 1) + (he & -ctl))) & -db; - } - - /* - * Check that the GCD is indeed 1. If not, then the key is invalid - * (and there's no harm in leaking that piece of information). - */ - if (a != 1) { - return 0; - } - - /* - * Now we have u0*e - v0*r = 1. Let's compute the result as: - * d = u0 + v0*k - * We still have k in the tmp[] array, and its announced bit - * length is that of phi. - */ - m = k + 1 + len; - m[0] = (2 << 4) + 2; /* bit length is 32 bits, encoded */ - m[1] = v0 & 0x7FFF; - m[2] = (v0 >> 15) & 0x7FFF; - m[3] = v0 >> 30; - z = m + 4; - br_i15_zero(z, k[0]); - z[1] = u0 & 0x7FFF; - z[2] = (u0 >> 15) & 0x7FFF; - z[3] = u0 >> 30; - br_i15_mulacc(z, k, m); - - /* - * Encode the result. - */ - br_i15_encode(d, dlen, z); - return dlen; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_i15_pub.c b/src/tls/bearssl/rsa_i15_pub.c deleted file mode 100644 index ad07d409a..000000000 --- a/src/tls/bearssl/rsa_i15_pub.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * As a strict minimum, we need four buffers that can hold a - * modular integer. - */ -#define TLEN (4 * (2 + ((BR_MAX_RSA_SIZE + 14) / 15))) - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i15_public(unsigned char *x, size_t xlen, - const br_rsa_public_key *pk) -{ - const unsigned char *n; - size_t nlen; - uint16_t tmp[1 + TLEN]; - uint16_t *m, *a, *t; - size_t fwlen; - long z; - uint16_t m0i; - uint32_t r; - - /* - * Get the actual length of the modulus, and see if it fits within - * our stack buffer. We also check that the length of x[] is valid. - */ - n = pk->n; - nlen = pk->nlen; - while (nlen > 0 && *n == 0) { - n ++; - nlen --; - } - if (nlen == 0 || nlen > (BR_MAX_RSA_SIZE >> 3) || xlen != nlen) { - return 0; - } - z = (long)nlen << 3; - fwlen = 1; - while (z > 0) { - z -= 15; - fwlen ++; - } - /* - * Round up length to an even number. - */ - fwlen += (fwlen & 1); - - /* - * The modulus gets decoded into m[]. - * The value to exponentiate goes into a[]. - * The temporaries for modular exponentiations are in t[]. - * - * We want the first value word of each integer to be aligned - * on a 32-bit boundary. - */ - m = tmp; - if (((uintptr_t)m & 2) == 0) { - m ++; - } - a = m + fwlen; - t = m + 2 * fwlen; - - /* - * Decode the modulus. - */ - br_i15_decode(m, n, nlen); - m0i = br_i15_ninv15(m[1]); - - /* - * Note: if m[] is even, then m0i == 0. Otherwise, m0i must be - * an odd integer. - */ - r = m0i & 1; - - /* - * Decode x[] into a[]; we also check that its value is proper. - */ - r &= br_i15_decode_mod(a, x, xlen, m); - - /* - * Compute the modular exponentiation. - */ - br_i15_modpow_opt(a, pk->e, pk->elen, m, m0i, t, TLEN - 2 * fwlen); - - /* - * Encode the result. - */ - br_i15_encode(x, xlen, a); - return r; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_i15_pubexp.c b/src/tls/bearssl/rsa_i15_pubexp.c deleted file mode 100644 index 7a4434251..000000000 --- a/src/tls/bearssl/rsa_i15_pubexp.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * Recompute public exponent, based on factor p and reduced private - * exponent dp. - */ -static uint32_t -get_pubexp(const unsigned char *pbuf, size_t plen, - const unsigned char *dpbuf, size_t dplen) -{ - /* - * dp is the inverse of e modulo p-1. If p = 3 mod 4, then - * p-1 = 2*((p-1)/2). Taken modulo 2, e is odd and has inverse 1; - * thus, dp must be odd. - * - * We compute the inverse of dp modulo (p-1)/2. This requires - * first reducing dp modulo (p-1)/2 (this can be done with a - * conditional subtract, no need to use the generic modular - * reduction function); then, we use moddiv. - */ - - uint16_t tmp[6 * ((BR_MAX_RSA_FACTOR + 29) / 15)]; - uint16_t *p, *dp, *x; - size_t len; - uint32_t e; - - /* - * Compute actual factor length (in bytes) and check that it fits - * under our size constraints. - */ - while (plen > 0 && *pbuf == 0) { - pbuf ++; - plen --; - } - if (plen == 0 || plen < 5 || plen > (BR_MAX_RSA_FACTOR / 8)) { - return 0; - } - - /* - * Compute actual reduced exponent length (in bytes) and check that - * it is not longer than p. - */ - while (dplen > 0 && *dpbuf == 0) { - dpbuf ++; - dplen --; - } - if (dplen > plen || dplen == 0 - || (dplen == plen && dpbuf[0] > pbuf[0])) - { - return 0; - } - - /* - * Verify that p = 3 mod 4 and that dp is odd. - */ - if ((pbuf[plen - 1] & 3) != 3 || (dpbuf[dplen - 1] & 1) != 1) { - return 0; - } - - /* - * Decode p and compute (p-1)/2. - */ - p = tmp; - br_i15_decode(p, pbuf, plen); - len = (p[0] + 31) >> 4; - br_i15_rshift(p, 1); - - /* - * Decode dp and make sure its announced bit length matches that of - * p (we already know that the size of dp, in bits, does not exceed - * the size of p, so we just have to copy the header word). - */ - dp = p + len; - memset(dp, 0, len * sizeof *dp); - br_i15_decode(dp, dpbuf, dplen); - dp[0] = p[0]; - - /* - * Subtract (p-1)/2 from dp if necessary. - */ - br_i15_sub(dp, p, NOT(br_i15_sub(dp, p, 0))); - - /* - * If another subtraction is needed, then this means that the - * value was invalid. We don't care to leak information about - * invalid keys. - */ - if (br_i15_sub(dp, p, 0) == 0) { - return 0; - } - - /* - * Invert dp modulo (p-1)/2. If the inversion fails, then the - * key value was invalid. - */ - x = dp + len; - br_i15_zero(x, p[0]); - x[1] = 1; - if (br_i15_moddiv(x, dp, p, br_i15_ninv15(p[1]), x + len) == 0) { - return 0; - } - - /* - * We now have an inverse. We must set it to zero (error) if its - * length is greater than 32 bits and/or if it is an even integer. - * Take care that the bit_length function returns an encoded - * bit length. - */ - e = (uint32_t)x[1] | ((uint32_t)x[2] << 15) | ((uint32_t)x[3] << 30); - e &= -LT(br_i15_bit_length(x + 1, len - 1), 35); - e &= -(e & 1); - return e; -} - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i15_compute_pubexp(const br_rsa_private_key *sk) -{ - /* - * Get the public exponent from both p and q. This is the right - * exponent if we get twice the same value. - */ - uint32_t ep, eq; - - ep = get_pubexp(sk->p, sk->plen, sk->dp, sk->dplen); - eq = get_pubexp(sk->q, sk->qlen, sk->dq, sk->dqlen); - return ep & -EQ(ep, eq); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_i31_keygen.c b/src/tls/bearssl/rsa_i31_keygen.c deleted file mode 100644 index ff60cbbb8..000000000 --- a/src/tls/bearssl/rsa_i31_keygen.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i31_keygen(const br_prng_class **rng, - br_rsa_private_key *sk, void *kbuf_priv, - br_rsa_public_key *pk, void *kbuf_pub, - unsigned size, uint32_t pubexp) -{ - return br_rsa_i31_keygen_inner(rng, - sk, kbuf_priv, pk, kbuf_pub, size, pubexp, - &br_i31_modpow_opt); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_i31_keygen_inner.c b/src/tls/bearssl/rsa_i31_keygen_inner.c deleted file mode 100644 index 8ede237ec..000000000 --- a/src/tls/bearssl/rsa_i31_keygen_inner.c +++ /dev/null @@ -1,613 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * Make a random integer of the provided size. The size is encoded. - * The header word is untouched. - */ -static void -mkrand(const br_prng_class **rng, uint32_t *x, uint32_t esize) -{ - size_t u, len; - unsigned m; - - len = (esize + 31) >> 5; - (*rng)->generate(rng, x + 1, len * sizeof(uint32_t)); - for (u = 1; u < len; u ++) { - x[u] &= 0x7FFFFFFF; - } - m = esize & 31; - if (m == 0) { - x[len] &= 0x7FFFFFFF; - } else { - x[len] &= 0x7FFFFFFF >> (31 - m); - } -} - -/* - * This is the big-endian unsigned representation of the product of - * all small primes from 13 to 1481. - */ -static const unsigned char SMALL_PRIMES[] = { - 0x2E, 0xAB, 0x92, 0xD1, 0x8B, 0x12, 0x47, 0x31, 0x54, 0x0A, - 0x99, 0x5D, 0x25, 0x5E, 0xE2, 0x14, 0x96, 0x29, 0x1E, 0xB7, - 0x78, 0x70, 0xCC, 0x1F, 0xA5, 0xAB, 0x8D, 0x72, 0x11, 0x37, - 0xFB, 0xD8, 0x1E, 0x3F, 0x5B, 0x34, 0x30, 0x17, 0x8B, 0xE5, - 0x26, 0x28, 0x23, 0xA1, 0x8A, 0xA4, 0x29, 0xEA, 0xFD, 0x9E, - 0x39, 0x60, 0x8A, 0xF3, 0xB5, 0xA6, 0xEB, 0x3F, 0x02, 0xB6, - 0x16, 0xC3, 0x96, 0x9D, 0x38, 0xB0, 0x7D, 0x82, 0x87, 0x0C, - 0xF7, 0xBE, 0x24, 0xE5, 0x5F, 0x41, 0x04, 0x79, 0x76, 0x40, - 0xE7, 0x00, 0x22, 0x7E, 0xB5, 0x85, 0x7F, 0x8D, 0x01, 0x50, - 0xE9, 0xD3, 0x29, 0x42, 0x08, 0xB3, 0x51, 0x40, 0x7B, 0xD7, - 0x8D, 0xCC, 0x10, 0x01, 0x64, 0x59, 0x28, 0xB6, 0x53, 0xF3, - 0x50, 0x4E, 0xB1, 0xF2, 0x58, 0xCD, 0x6E, 0xF5, 0x56, 0x3E, - 0x66, 0x2F, 0xD7, 0x07, 0x7F, 0x52, 0x4C, 0x13, 0x24, 0xDC, - 0x8E, 0x8D, 0xCC, 0xED, 0x77, 0xC4, 0x21, 0xD2, 0xFD, 0x08, - 0xEA, 0xD7, 0xC0, 0x5C, 0x13, 0x82, 0x81, 0x31, 0x2F, 0x2B, - 0x08, 0xE4, 0x80, 0x04, 0x7A, 0x0C, 0x8A, 0x3C, 0xDC, 0x22, - 0xE4, 0x5A, 0x7A, 0xB0, 0x12, 0x5E, 0x4A, 0x76, 0x94, 0x77, - 0xC2, 0x0E, 0x92, 0xBA, 0x8A, 0xA0, 0x1F, 0x14, 0x51, 0x1E, - 0x66, 0x6C, 0x38, 0x03, 0x6C, 0xC7, 0x4A, 0x4B, 0x70, 0x80, - 0xAF, 0xCA, 0x84, 0x51, 0xD8, 0xD2, 0x26, 0x49, 0xF5, 0xA8, - 0x5E, 0x35, 0x4B, 0xAC, 0xCE, 0x29, 0x92, 0x33, 0xB7, 0xA2, - 0x69, 0x7D, 0x0C, 0xE0, 0x9C, 0xDB, 0x04, 0xD6, 0xB4, 0xBC, - 0x39, 0xD7, 0x7F, 0x9E, 0x9D, 0x78, 0x38, 0x7F, 0x51, 0x54, - 0x50, 0x8B, 0x9E, 0x9C, 0x03, 0x6C, 0xF5, 0x9D, 0x2C, 0x74, - 0x57, 0xF0, 0x27, 0x2A, 0xC3, 0x47, 0xCA, 0xB9, 0xD7, 0x5C, - 0xFF, 0xC2, 0xAC, 0x65, 0x4E, 0xBD -}; - -/* - * We need temporary values for at least 7 integers of the same size - * as a factor (including header word); more space helps with performance - * (in modular exponentiations), but we much prefer to remain under - * 2 kilobytes in total, to save stack space. The macro TEMPS below - * exceeds 512 (which is a count in 32-bit words) when BR_MAX_RSA_SIZE - * is greater than 4464 (default value is 4096, so the 2-kB limit is - * maintained unless BR_MAX_RSA_SIZE was modified). - */ -#define MAX(x, y) ((x) > (y) ? (x) : (y)) -#define ROUND2(x) ((((x) + 1) >> 1) << 1) - -#define TEMPS MAX(512, ROUND2(7 * ((((BR_MAX_RSA_SIZE + 1) >> 1) + 61) / 31))) - -/* - * Perform trial division on a candidate prime. This computes - * y = SMALL_PRIMES mod x, then tries to compute y/y mod x. The - * br_i31_moddiv() function will report an error if y is not invertible - * modulo x. Returned value is 1 on success (none of the small primes - * divides x), 0 on error (a non-trivial GCD is obtained). - * - * This function assumes that x is odd. - */ -static uint32_t -trial_divisions(const uint32_t *x, uint32_t *t) -{ - uint32_t *y; - uint32_t x0i; - - y = t; - t += 1 + ((x[0] + 31) >> 5); - x0i = br_i31_ninv31(x[1]); - br_i31_decode_reduce(y, SMALL_PRIMES, sizeof SMALL_PRIMES, x); - return br_i31_moddiv(y, y, x, x0i, t); -} - -/* - * Perform n rounds of Miller-Rabin on the candidate prime x. This - * function assumes that x = 3 mod 4. - * - * Returned value is 1 on success (all rounds completed successfully), - * 0 otherwise. - */ -static uint32_t -miller_rabin(const br_prng_class **rng, const uint32_t *x, int n, - uint32_t *t, size_t tlen, br_i31_modpow_opt_type mp31) -{ - /* - * Since x = 3 mod 4, the Miller-Rabin test is simple: - * - get a random base a (such that 1 < a < x-1) - * - compute z = a^((x-1)/2) mod x - * - if z != 1 and z != x-1, the number x is composite - * - * We generate bases 'a' randomly with a size which is - * one bit less than x, which ensures that a < x-1. It - * is not useful to verify that a > 1 because the probability - * that we get a value a equal to 0 or 1 is much smaller - * than the probability of our Miller-Rabin tests not to - * detect a composite, which is already quite smaller than the - * probability of the hardware misbehaving and return a - * composite integer because of some glitch (e.g. bad RAM - * or ill-timed cosmic ray). - */ - unsigned char *xm1d2; - size_t xlen, xm1d2_len, xm1d2_len_u32, u; - uint32_t asize; - unsigned cc; - uint32_t x0i; - - /* - * Compute (x-1)/2 (encoded). - */ - xm1d2 = (unsigned char *)t; - xm1d2_len = ((x[0] - (x[0] >> 5)) + 7) >> 3; - br_i31_encode(xm1d2, xm1d2_len, x); - cc = 0; - for (u = 0; u < xm1d2_len; u ++) { - unsigned w; - - w = xm1d2[u]; - xm1d2[u] = (unsigned char)((w >> 1) | cc); - cc = w << 7; - } - - /* - * We used some words of the provided buffer for (x-1)/2. - */ - xm1d2_len_u32 = (xm1d2_len + 3) >> 2; - t += xm1d2_len_u32; - tlen -= xm1d2_len_u32; - - xlen = (x[0] + 31) >> 5; - asize = x[0] - 1 - EQ0(x[0] & 31); - x0i = br_i31_ninv31(x[1]); - while (n -- > 0) { - uint32_t *a, *t2; - uint32_t eq1, eqm1; - size_t t2len; - - /* - * Generate a random base. We don't need the base to be - * really uniform modulo x, so we just get a random - * number which is one bit shorter than x. - */ - a = t; - a[0] = x[0]; - a[xlen] = 0; - mkrand(rng, a, asize); - - /* - * Compute a^((x-1)/2) mod x. We assume here that the - * function will not fail (the temporary array is large - * enough). - */ - t2 = t + 1 + xlen; - t2len = tlen - 1 - xlen; - if ((t2len & 1) != 0) { - /* - * Since the source array is 64-bit aligned and - * has an even number of elements (TEMPS), we - * can use the parity of the remaining length to - * detect and adjust alignment. - */ - t2 ++; - t2len --; - } - mp31(a, xm1d2, xm1d2_len, x, x0i, t2, t2len); - - /* - * We must obtain either 1 or x-1. Note that x is odd, - * hence x-1 differs from x only in its low word (no - * carry). - */ - eq1 = a[1] ^ 1; - eqm1 = a[1] ^ (x[1] - 1); - for (u = 2; u <= xlen; u ++) { - eq1 |= a[u]; - eqm1 |= a[u] ^ x[u]; - } - - if ((EQ0(eq1) | EQ0(eqm1)) == 0) { - return 0; - } - } - return 1; -} - -/* - * Create a random prime of the provided size. 'size' is the _encoded_ - * bit length. The two top bits and the two bottom bits are set to 1. - */ -static void -mkprime(const br_prng_class **rng, uint32_t *x, uint32_t esize, - uint32_t pubexp, uint32_t *t, size_t tlen, br_i31_modpow_opt_type mp31) -{ - size_t len; - - x[0] = esize; - len = (esize + 31) >> 5; - for (;;) { - size_t u; - uint32_t m3, m5, m7, m11; - int rounds, s7, s11; - - /* - * Generate random bits. We force the two top bits and the - * two bottom bits to 1. - */ - mkrand(rng, x, esize); - if ((esize & 31) == 0) { - x[len] |= 0x60000000; - } else if ((esize & 31) == 1) { - x[len] |= 0x00000001; - x[len - 1] |= 0x40000000; - } else { - x[len] |= 0x00000003 << ((esize & 31) - 2); - } - x[1] |= 0x00000003; - - /* - * Trial division with low primes (3, 5, 7 and 11). We - * use the following properties: - * - * 2^2 = 1 mod 3 - * 2^4 = 1 mod 5 - * 2^3 = 1 mod 7 - * 2^10 = 1 mod 11 - */ - m3 = 0; - m5 = 0; - m7 = 0; - m11 = 0; - s7 = 0; - s11 = 0; - for (u = 0; u < len; u ++) { - uint32_t w, w3, w5, w7, w11; - - w = x[1 + u]; - w3 = (w & 0xFFFF) + (w >> 16); /* max: 98302 */ - w5 = (w & 0xFFFF) + (w >> 16); /* max: 98302 */ - w7 = (w & 0x7FFF) + (w >> 15); /* max: 98302 */ - w11 = (w & 0xFFFFF) + (w >> 20); /* max: 1050622 */ - - m3 += w3 << (u & 1); - m3 = (m3 & 0xFF) + (m3 >> 8); /* max: 1025 */ - - m5 += w5 << ((4 - u) & 3); - m5 = (m5 & 0xFFF) + (m5 >> 12); /* max: 4479 */ - - m7 += w7 << s7; - m7 = (m7 & 0x1FF) + (m7 >> 9); /* max: 1280 */ - if (++ s7 == 3) { - s7 = 0; - } - - m11 += w11 << s11; - if (++ s11 == 10) { - s11 = 0; - } - m11 = (m11 & 0x3FF) + (m11 >> 10); /* max: 526847 */ - } - - m3 = (m3 & 0x3F) + (m3 >> 6); /* max: 78 */ - m3 = (m3 & 0x0F) + (m3 >> 4); /* max: 18 */ - m3 = ((m3 * 43) >> 5) & 3; - - m5 = (m5 & 0xFF) + (m5 >> 8); /* max: 271 */ - m5 = (m5 & 0x0F) + (m5 >> 4); /* max: 31 */ - m5 -= 20 & -GT(m5, 19); - m5 -= 10 & -GT(m5, 9); - m5 -= 5 & -GT(m5, 4); - - m7 = (m7 & 0x3F) + (m7 >> 6); /* max: 82 */ - m7 = (m7 & 0x07) + (m7 >> 3); /* max: 16 */ - m7 = ((m7 * 147) >> 7) & 7; - - /* - * 2^5 = 32 = -1 mod 11. - */ - m11 = (m11 & 0x3FF) + (m11 >> 10); /* max: 1536 */ - m11 = (m11 & 0x3FF) + (m11 >> 10); /* max: 1023 */ - m11 = (m11 & 0x1F) + 33 - (m11 >> 5); /* max: 64 */ - m11 -= 44 & -GT(m11, 43); - m11 -= 22 & -GT(m11, 21); - m11 -= 11 & -GT(m11, 10); - - /* - * If any of these modulo is 0, then the candidate is - * not prime. Also, if pubexp is 3, 5, 7 or 11, and the - * corresponding modulus is 1, then the candidate must - * be rejected, because we need e to be invertible - * modulo p-1. We can use simple comparisons here - * because they won't leak information on a candidate - * that we keep, only on one that we reject (and is thus - * not secret). - */ - if (m3 == 0 || m5 == 0 || m7 == 0 || m11 == 0) { - continue; - } - if ((pubexp == 3 && m3 == 1) - || (pubexp == 5 && m5 == 5) - || (pubexp == 7 && m5 == 7) - || (pubexp == 11 && m5 == 11)) - { - continue; - } - - /* - * More trial divisions. - */ - if (!trial_divisions(x, t)) { - continue; - } - - /* - * Miller-Rabin algorithm. Since we selected a random - * integer, not a maliciously crafted integer, we can use - * relatively few rounds to lower the risk of a false - * positive (i.e. declaring prime a non-prime) under - * 2^(-80). It is not useful to lower the probability much - * below that, since that would be substantially below - * the probability of the hardware misbehaving. Sufficient - * numbers of rounds are extracted from the Handbook of - * Applied Cryptography, note 4.49 (page 149). - * - * Since we work on the encoded size (esize), we need to - * compare with encoded thresholds. - */ - if (esize < 309) { - rounds = 12; - } else if (esize < 464) { - rounds = 9; - } else if (esize < 670) { - rounds = 6; - } else if (esize < 877) { - rounds = 4; - } else if (esize < 1341) { - rounds = 3; - } else { - rounds = 2; - } - - if (miller_rabin(rng, x, rounds, t, tlen, mp31)) { - return; - } - } -} - -/* - * Let p be a prime (p > 2^33, p = 3 mod 4). Let m = (p-1)/2, provided - * as parameter (with announced bit length equal to that of p). This - * function computes d = 1/e mod p-1 (for an odd integer e). Returned - * value is 1 on success, 0 on error (an error is reported if e is not - * invertible modulo p-1). - * - * The temporary buffer (t) must have room for at least 4 integers of - * the size of p. - */ -static uint32_t -invert_pubexp(uint32_t *d, const uint32_t *m, uint32_t e, uint32_t *t) -{ - uint32_t *f; - uint32_t r; - - f = t; - t += 1 + ((m[0] + 31) >> 5); - - /* - * Compute d = 1/e mod m. Since p = 3 mod 4, m is odd. - */ - br_i31_zero(d, m[0]); - d[1] = 1; - br_i31_zero(f, m[0]); - f[1] = e & 0x7FFFFFFF; - f[2] = e >> 31; - r = br_i31_moddiv(d, f, m, br_i31_ninv31(m[1]), t); - - /* - * We really want d = 1/e mod p-1, with p = 2m. By the CRT, - * the result is either the d we got, or d + m. - * - * Let's write e*d = 1 + k*m, for some integer k. Integers e - * and m are odd. If d is odd, then e*d is odd, which implies - * that k must be even; in that case, e*d = 1 + (k/2)*2m, and - * thus d is already fine. Conversely, if d is even, then k - * is odd, and we must add m to d in order to get the correct - * result. - */ - br_i31_add(d, m, (uint32_t)(1 - (d[1] & 1))); - - return r; -} - -/* - * Swap two buffers in RAM. They must be disjoint. - */ -static void -bufswap(void *b1, void *b2, size_t len) -{ - size_t u; - unsigned char *buf1, *buf2; - - buf1 = b1; - buf2 = b2; - for (u = 0; u < len; u ++) { - unsigned w; - - w = buf1[u]; - buf1[u] = buf2[u]; - buf2[u] = w; - } -} - -/* see inner.h */ -uint32_t -br_rsa_i31_keygen_inner(const br_prng_class **rng, - br_rsa_private_key *sk, void *kbuf_priv, - br_rsa_public_key *pk, void *kbuf_pub, - unsigned size, uint32_t pubexp, br_i31_modpow_opt_type mp31) -{ - uint32_t esize_p, esize_q; - size_t plen, qlen, tlen; - uint32_t *p, *q, *t; - union { - uint32_t t32[TEMPS]; - uint64_t t64[TEMPS >> 1]; /* for 64-bit alignment */ - } tmp; - uint32_t r; - - if (size < BR_MIN_RSA_SIZE || size > BR_MAX_RSA_SIZE) { - return 0; - } - if (pubexp == 0) { - pubexp = 3; - } else if (pubexp == 1 || (pubexp & 1) == 0) { - return 0; - } - - esize_p = (size + 1) >> 1; - esize_q = size - esize_p; - sk->n_bitlen = size; - sk->p = kbuf_priv; - sk->plen = (esize_p + 7) >> 3; - sk->q = sk->p + sk->plen; - sk->qlen = (esize_q + 7) >> 3; - sk->dp = sk->q + sk->qlen; - sk->dplen = sk->plen; - sk->dq = sk->dp + sk->dplen; - sk->dqlen = sk->qlen; - sk->iq = sk->dq + sk->dqlen; - sk->iqlen = sk->plen; - - if (pk != NULL) { - pk->n = kbuf_pub; - pk->nlen = (size + 7) >> 3; - pk->e = pk->n + pk->nlen; - pk->elen = 4; - br_enc32be(pk->e, pubexp); - while (*pk->e == 0) { - pk->e ++; - pk->elen --; - } - } - - /* - * We now switch to encoded sizes. - * - * floor((x * 16913) / (2^19)) is equal to floor(x/31) for all - * integers x from 0 to 34966; the intermediate product fits on - * 30 bits, thus we can use MUL31(). - */ - esize_p += MUL31(esize_p, 16913) >> 19; - esize_q += MUL31(esize_q, 16913) >> 19; - plen = (esize_p + 31) >> 5; - qlen = (esize_q + 31) >> 5; - p = tmp.t32; - q = p + 1 + plen; - t = q + 1 + qlen; - tlen = ((sizeof tmp.t32) / sizeof(uint32_t)) - (2 + plen + qlen); - - /* - * When looking for primes p and q, we temporarily divide - * candidates by 2, in order to compute the inverse of the - * public exponent. - */ - - for (;;) { - mkprime(rng, p, esize_p, pubexp, t, tlen, mp31); - br_i31_rshift(p, 1); - if (invert_pubexp(t, p, pubexp, t + 1 + plen)) { - br_i31_add(p, p, 1); - p[1] |= 1; - br_i31_encode(sk->p, sk->plen, p); - br_i31_encode(sk->dp, sk->dplen, t); - break; - } - } - - for (;;) { - mkprime(rng, q, esize_q, pubexp, t, tlen, mp31); - br_i31_rshift(q, 1); - if (invert_pubexp(t, q, pubexp, t + 1 + qlen)) { - br_i31_add(q, q, 1); - q[1] |= 1; - br_i31_encode(sk->q, sk->qlen, q); - br_i31_encode(sk->dq, sk->dqlen, t); - break; - } - } - - /* - * If p and q have the same size, then it is possible that q > p - * (when the target modulus size is odd, we generate p with a - * greater bit length than q). If q > p, we want to swap p and q - * (and also dp and dq) for two reasons: - * - The final step below (inversion of q modulo p) is easier if - * p > q. - * - While BearSSL's RSA code is perfectly happy with RSA keys such - * that p < q, some other implementations have restrictions and - * require p > q. - * - * Note that we can do a simple non-constant-time swap here, - * because the only information we leak here is that we insist on - * returning p and q such that p > q, which is not a secret. - */ - if (esize_p == esize_q && br_i31_sub(p, q, 0) == 1) { - bufswap(p, q, (1 + plen) * sizeof *p); - bufswap(sk->p, sk->q, sk->plen); - bufswap(sk->dp, sk->dq, sk->dplen); - } - - /* - * We have produced p, q, dp and dq. We can now compute iq = 1/d mod p. - * - * We ensured that p >= q, so this is just a matter of updating the - * header word for q (and possibly adding an extra word). - * - * Theoretically, the call below may fail, in case we were - * extraordinarily unlucky, and p = q. Another failure case is if - * Miller-Rabin failed us _twice_, and p and q are non-prime and - * have a factor is common. We report the error mostly because it - * is cheap and we can, but in practice this never happens (or, at - * least, it happens way less often than hardware glitches). - */ - q[0] = p[0]; - if (plen > qlen) { - q[plen] = 0; - t ++; - tlen --; - } - br_i31_zero(t, p[0]); - t[1] = 1; - r = br_i31_moddiv(t, q, p, br_i31_ninv31(p[1]), t + 1 + plen); - br_i31_encode(sk->iq, sk->iqlen, t); - - /* - * Compute the public modulus too, if required. - */ - if (pk != NULL) { - br_i31_zero(t, p[0]); - br_i31_mulacc(t, p, q); - br_i31_encode(pk->n, pk->nlen, t); - } - - return r; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_i31_modulus.c b/src/tls/bearssl/rsa_i31_modulus.c deleted file mode 100644 index 1a98fdc07..000000000 --- a/src/tls/bearssl/rsa_i31_modulus.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_rsa.h */ -size_t -br_rsa_i31_compute_modulus(void *n, const br_rsa_private_key *sk) -{ - uint32_t tmp[2 * ((BR_MAX_RSA_SIZE + 30) / 31) + 5]; - uint32_t *t, *p, *q; - const unsigned char *pbuf, *qbuf; - size_t nlen, plen, qlen, tlen; - - /* - * Compute actual byte and lengths for p and q. - */ - pbuf = sk->p; - plen = sk->plen; - while (plen > 0 && *pbuf == 0) { - pbuf ++; - plen --; - } - qbuf = sk->q; - qlen = sk->qlen; - while (qlen > 0 && *qbuf == 0) { - qbuf ++; - qlen --; - } - - t = tmp; - tlen = (sizeof tmp) / (sizeof tmp[0]); - - /* - * Decode p. - */ - if ((31 * tlen) < (plen << 3) + 31) { - return 0; - } - br_i31_decode(t, pbuf, plen); - p = t; - plen = (p[0] + 63) >> 5; - t += plen; - tlen -= plen; - - /* - * Decode q. - */ - if ((31 * tlen) < (qlen << 3) + 31) { - return 0; - } - br_i31_decode(t, qbuf, qlen); - q = t; - qlen = (q[0] + 63) >> 5; - t += qlen; - tlen -= qlen; - - /* - * Computation can proceed only if we have enough room for the - * modulus. - */ - if (tlen < (plen + qlen + 1)) { - return 0; - } - - /* - * Private key already contains the modulus bit length, from which - * we can infer the output length. Even if n is NULL, we still had - * to decode p and q to make sure that the product can be computed. - */ - nlen = (sk->n_bitlen + 7) >> 3; - if (n != NULL) { - br_i31_zero(t, p[0]); - br_i31_mulacc(t, p, q); - br_i31_encode(n, nlen, t); - } - return nlen; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_i31_oaep_decrypt.c b/src/tls/bearssl/rsa_i31_oaep_decrypt.c deleted file mode 100644 index 5f9f2dee1..000000000 --- a/src/tls/bearssl/rsa_i31_oaep_decrypt.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i31_oaep_decrypt(const br_hash_class *dig, - const void *label, size_t label_len, - const br_rsa_private_key *sk, void *data, size_t *len) -{ - uint32_t r; - - if (*len != ((sk->n_bitlen + 7) >> 3)) { - return 0; - } - r = br_rsa_i31_private(data, sk); - r &= br_rsa_oaep_unpad(dig, label, label_len, data, len); - return r; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_i31_oaep_encrypt.c b/src/tls/bearssl/rsa_i31_oaep_encrypt.c deleted file mode 100644 index 771463751..000000000 --- a/src/tls/bearssl/rsa_i31_oaep_encrypt.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_rsa.h */ -size_t -br_rsa_i31_oaep_encrypt( - const br_prng_class **rnd, const br_hash_class *dig, - const void *label, size_t label_len, - const br_rsa_public_key *pk, - void *dst, size_t dst_max_len, - const void *src, size_t src_len) -{ - size_t dlen; - - dlen = br_rsa_oaep_pad(rnd, dig, label, label_len, - pk, dst, dst_max_len, src, src_len); - if (dlen == 0) { - return 0; - } - return dlen & -(size_t)br_rsa_i31_public(dst, dlen, pk); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_i31_pkcs1_sign.c b/src/tls/bearssl/rsa_i31_pkcs1_sign.c deleted file mode 100644 index 5b5766c1e..000000000 --- a/src/tls/bearssl/rsa_i31_pkcs1_sign.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i31_pkcs1_sign(const unsigned char *hash_oid, - const unsigned char *hash, size_t hash_len, - const br_rsa_private_key *sk, unsigned char *x) -{ - if (!br_rsa_pkcs1_sig_pad(hash_oid, hash, hash_len, sk->n_bitlen, x)) { - return 0; - } - return br_rsa_i31_private(x, sk); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_i31_pkcs1_vrfy.c b/src/tls/bearssl/rsa_i31_pkcs1_vrfy.c deleted file mode 100644 index 0df7fbe27..000000000 --- a/src/tls/bearssl/rsa_i31_pkcs1_vrfy.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i31_pkcs1_vrfy(const unsigned char *x, size_t xlen, - const unsigned char *hash_oid, size_t hash_len, - const br_rsa_public_key *pk, unsigned char *hash_out) -{ - unsigned char sig[BR_MAX_RSA_SIZE >> 3]; - - if (xlen > (sizeof sig)) { - return 0; - } - memcpy(sig, x, xlen); - if (!br_rsa_i31_public(sig, xlen, pk)) { - return 0; - } - return br_rsa_pkcs1_sig_unpad(sig, xlen, hash_oid, hash_len, hash_out); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_i31_priv.c b/src/tls/bearssl/rsa_i31_priv.c deleted file mode 100644 index 68d1d6743..000000000 --- a/src/tls/bearssl/rsa_i31_priv.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -#define U (2 + ((BR_MAX_RSA_FACTOR + 30) / 31)) -#define TLEN (8 * U) - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i31_private(unsigned char *x, const br_rsa_private_key *sk) -{ - const unsigned char *p, *q; - size_t plen, qlen; - size_t fwlen; - uint32_t p0i, q0i; - size_t xlen, u; - uint32_t tmp[1 + TLEN]; - long z; - uint32_t *mp, *mq, *s1, *s2, *t1, *t2, *t3; - uint32_t r; - - /* - * Compute the actual lengths of p and q, in bytes. - * These lengths are not considered secret (we cannot really hide - * them anyway in constant-time code). - */ - p = sk->p; - plen = sk->plen; - while (plen > 0 && *p == 0) { - p ++; - plen --; - } - q = sk->q; - qlen = sk->qlen; - while (qlen > 0 && *q == 0) { - q ++; - qlen --; - } - - /* - * Compute the maximum factor length, in words. - */ - z = (long)(plen > qlen ? plen : qlen) << 3; - fwlen = 1; - while (z > 0) { - z -= 31; - fwlen ++; - } - - /* - * Round up the word length to an even number. - */ - fwlen += (fwlen & 1); - - /* - * We need to fit at least 6 values in the stack buffer. - */ - if (6 * fwlen > TLEN) { - return 0; - } - - /* - * Compute modulus length (in bytes). - */ - xlen = (sk->n_bitlen + 7) >> 3; - - /* - * Decode q. - */ - mq = tmp; - br_i31_decode(mq, q, qlen); - - /* - * Decode p. - */ - t1 = mq + fwlen; - br_i31_decode(t1, p, plen); - - /* - * Compute the modulus (product of the two factors), to compare - * it with the source value. We use br_i31_mulacc(), since it's - * already used later on. - */ - t2 = mq + 2 * fwlen; - br_i31_zero(t2, mq[0]); - br_i31_mulacc(t2, mq, t1); - - /* - * We encode the modulus into bytes, to perform the comparison - * with bytes. We know that the product length, in bytes, is - * exactly xlen. - * The comparison actually computes the carry when subtracting - * the modulus from the source value; that carry must be 1 for - * a value in the correct range. We keep it in r, which is our - * accumulator for the error code. - */ - t3 = mq + 4 * fwlen; - br_i31_encode(t3, xlen, t2); - u = xlen; - r = 0; - while (u > 0) { - uint32_t wn, wx; - - u --; - wn = ((unsigned char *)t3)[u]; - wx = x[u]; - r = ((wx - (wn + r)) >> 8) & 1; - } - - /* - * Move the decoded p to another temporary buffer. - */ - mp = mq + 2 * fwlen; - memmove(mp, t1, fwlen * sizeof *t1); - - /* - * Compute s2 = x^dq mod q. - */ - q0i = br_i31_ninv31(mq[1]); - s2 = mq + fwlen; - br_i31_decode_reduce(s2, x, xlen, mq); - r &= br_i31_modpow_opt(s2, sk->dq, sk->dqlen, mq, q0i, - mq + 3 * fwlen, TLEN - 3 * fwlen); - - /* - * Compute s1 = x^dp mod p. - */ - p0i = br_i31_ninv31(mp[1]); - s1 = mq + 3 * fwlen; - br_i31_decode_reduce(s1, x, xlen, mp); - r &= br_i31_modpow_opt(s1, sk->dp, sk->dplen, mp, p0i, - mq + 4 * fwlen, TLEN - 4 * fwlen); - - /* - * Compute: - * h = (s1 - s2)*(1/q) mod p - * s1 is an integer modulo p, but s2 is modulo q. PKCS#1 is - * unclear about whether p may be lower than q (some existing, - * widely deployed implementations of RSA don't tolerate p < q), - * but we want to support that occurrence, so we need to use the - * reduction function. - * - * Since we use br_i31_decode_reduce() for iq (purportedly, the - * inverse of q modulo p), we also tolerate improperly large - * values for this parameter. - */ - t1 = mq + 4 * fwlen; - t2 = mq + 5 * fwlen; - br_i31_reduce(t2, s2, mp); - br_i31_add(s1, mp, br_i31_sub(s1, t2, 1)); - br_i31_to_monty(s1, mp); - br_i31_decode_reduce(t1, sk->iq, sk->iqlen, mp); - br_i31_montymul(t2, s1, t1, mp, p0i); - - /* - * h is now in t2. We compute the final result: - * s = s2 + q*h - * All these operations are non-modular. - * - * We need mq, s2 and t2. We use the t3 buffer as destination. - * The buffers mp, s1 and t1 are no longer needed, so we can - * reuse them for t3. Moreover, the first step of the computation - * is to copy s2 into t3, after which s2 is not needed. Right - * now, mq is in slot 0, s2 is in slot 1, and t2 is in slot 5. - * Therefore, we have ample room for t3 by simply using s2. - */ - t3 = s2; - br_i31_mulacc(t3, mq, t2); - - /* - * Encode the result. Since we already checked the value of xlen, - * we can just use it right away. - */ - br_i31_encode(x, xlen, t3); - - /* - * The only error conditions remaining at that point are invalid - * values for p and q (even integers). - */ - return p0i & q0i & r; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_i31_privexp.c b/src/tls/bearssl/rsa_i31_privexp.c deleted file mode 100644 index 563eb2dbe..000000000 --- a/src/tls/bearssl/rsa_i31_privexp.c +++ /dev/null @@ -1,323 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_rsa.h */ -size_t -br_rsa_i31_compute_privexp(void *d, - const br_rsa_private_key *sk, uint32_t e) -{ - /* - * We want to invert e modulo phi = (p-1)(q-1). This first - * requires computing phi, which is easy since we have the factors - * p and q in the private key structure. - * - * Since p = 3 mod 4 and q = 3 mod 4, phi/4 is an odd integer. - * We could invert e modulo phi/4 then patch the result to - * modulo phi, but this would involve assembling three modulus-wide - * values (phi/4, 1 and e) and calling moddiv, that requires - * three more temporaries, for a total of six big integers, or - * slightly more than 3 kB of stack space for RSA-4096. This - * exceeds our stack requirements. - * - * Instead, we first use one step of the extended GCD: - * - * - We compute phi = k*e + r (Euclidean division of phi by e). - * If public exponent e is correct, then r != 0 (e must be - * invertible modulo phi). We also have k != 0 since we - * enforce non-ridiculously-small factors. - * - * - We find small u, v such that u*e - v*r = 1 (using a - * binary GCD; we can arrange for u < r and v < e, i.e. all - * values fit on 32 bits). - * - * - Solution is: d = u + v*k - * This last computation is exact: since u < r and v < e, - * the above implies d < r + e*((phi-r)/e) = phi - */ - - uint32_t tmp[4 * ((BR_MAX_RSA_FACTOR + 30) / 31) + 12]; - uint32_t *p, *q, *k, *m, *z, *phi; - const unsigned char *pbuf, *qbuf; - size_t plen, qlen, u, len, dlen; - uint32_t r, a, b, u0, v0, u1, v1, he, hr; - int i; - - /* - * Check that e is correct. - */ - if (e < 3 || (e & 1) == 0) { - return 0; - } - - /* - * Check lengths of p and q, and that they are both odd. - */ - pbuf = sk->p; - plen = sk->plen; - while (plen > 0 && *pbuf == 0) { - pbuf ++; - plen --; - } - if (plen < 5 || plen > (BR_MAX_RSA_FACTOR / 8) - || (pbuf[plen - 1] & 1) != 1) - { - return 0; - } - qbuf = sk->q; - qlen = sk->qlen; - while (qlen > 0 && *qbuf == 0) { - qbuf ++; - qlen --; - } - if (qlen < 5 || qlen > (BR_MAX_RSA_FACTOR / 8) - || (qbuf[qlen - 1] & 1) != 1) - { - return 0; - } - - /* - * Output length is that of the modulus. - */ - dlen = (sk->n_bitlen + 7) >> 3; - if (d == NULL) { - return dlen; - } - - p = tmp; - br_i31_decode(p, pbuf, plen); - plen = (p[0] + 31) >> 5; - q = p + 1 + plen; - br_i31_decode(q, qbuf, qlen); - qlen = (q[0] + 31) >> 5; - - /* - * Compute phi = (p-1)*(q-1), then move it over p-1 and q-1 (that - * we do not need anymore). The mulacc function sets the announced - * bit length of t to be the sum of the announced bit lengths of - * p-1 and q-1, which is usually exact but may overshoot by one 1 - * bit in some cases; we readjust it to its true length. - */ - p[1] --; - q[1] --; - phi = q + 1 + qlen; - br_i31_zero(phi, p[0]); - br_i31_mulacc(phi, p, q); - len = (phi[0] + 31) >> 5; - memmove(tmp, phi, (1 + len) * sizeof *phi); - phi = tmp; - phi[0] = br_i31_bit_length(phi + 1, len); - len = (phi[0] + 31) >> 5; - - /* - * Divide phi by public exponent e. The final remainder r must be - * non-zero (otherwise, the key is invalid). The quotient is k, - * which we write over phi, since we don't need phi after that. - */ - r = 0; - for (u = len; u >= 1; u --) { - /* - * Upon entry, r < e, and phi[u] < 2^31; hence, - * hi:lo < e*2^31. Thus, the produced word k[u] - * must be lower than 2^31, and the new remainder r - * is lower than e. - */ - uint32_t hi, lo; - - hi = r >> 1; - lo = (r << 31) + phi[u]; - phi[u] = br_divrem(hi, lo, e, &r); - } - if (r == 0) { - return 0; - } - k = phi; - - /* - * Compute u and v such that u*e - v*r = GCD(e,r). We use - * a binary GCD algorithm, with 6 extra integers a, b, - * u0, u1, v0 and v1. Initial values are: - * a = e u0 = 1 v0 = 0 - * b = r u1 = r v1 = e-1 - * The following invariants are maintained: - * a = u0*e - v0*r - * b = u1*e - v1*r - * 0 < a <= e - * 0 < b <= r - * 0 <= u0 <= r - * 0 <= v0 <= e - * 0 <= u1 <= r - * 0 <= v1 <= e - * - * At each iteration, we reduce either a or b by one bit, and - * adjust u0, u1, v0 and v1 to maintain the invariants: - * - if a is even, then a <- a/2 - * - otherwise, if b is even, then b <- b/2 - * - otherwise, if a > b, then a <- (a-b)/2 - * - otherwise, if b > a, then b <- (b-a)/2 - * Algorithm stops when a = b. At that point, the common value - * is the GCD of e and r; it must be 1 (otherwise, the private - * key or public exponent is not valid). The (u0,v0) or (u1,v1) - * pairs are the solution we are looking for. - * - * Since either a or b is reduced by at least 1 bit at each - * iteration, 62 iterations are enough to reach the end - * condition. - * - * To maintain the invariants, we must compute the same operations - * on the u* and v* values that we do on a and b: - * - When a is divided by 2, u0 and v0 must be divided by 2. - * - When b is divided by 2, u1 and v1 must be divided by 2. - * - When b is subtracted from a, u1 and v1 are subtracted from - * u0 and v0, respectively. - * - When a is subtracted from b, u0 and v0 are subtracted from - * u1 and v1, respectively. - * - * However, we want to keep the u* and v* values in their proper - * ranges. The following remarks apply: - * - * - When a is divided by 2, then a is even. Therefore: - * - * * If r is odd, then u0 and v0 must have the same parity; - * if they are both odd, then adding r to u0 and e to v0 - * makes them both even, and the division by 2 brings them - * back to the proper range. - * - * * If r is even, then u0 must be even; if v0 is odd, then - * adding r to u0 and e to v0 makes them both even, and the - * division by 2 brings them back to the proper range. - * - * Thus, all we need to do is to look at the parity of v0, - * and add (r,e) to (u0,v0) when v0 is odd. In order to avoid - * a 32-bit overflow, we can add ((r+1)/2,(e/2)+1) after the - * division (r+1 does not overflow since r < e; and (e/2)+1 - * is equal to (e+1)/2 since e is odd). - * - * - When we subtract b from a, three cases may occur: - * - * * u1 <= u0 and v1 <= v0: just do the subtractions - * - * * u1 > u0 and v1 > v0: compute: - * (u0, v0) <- (u0 + r - u1, v0 + e - v1) - * - * * u1 <= u0 and v1 > v0: compute: - * (u0, v0) <- (u0 + r - u1, v0 + e - v1) - * - * The fourth case (u1 > u0 and v1 <= v0) is not possible - * because it would contradict "b < a" (which is the reason - * why we subtract b from a). - * - * The tricky case is the third one: from the equations, it - * seems that u0 may go out of range. However, the invariants - * and ranges of other values imply that, in that case, the - * new u0 does not actually exceed the range. - * - * We can thus handle the subtraction by adding (r,e) based - * solely on the comparison between v0 and v1. - */ - a = e; - b = r; - u0 = 1; - v0 = 0; - u1 = r; - v1 = e - 1; - hr = (r + 1) >> 1; - he = (e >> 1) + 1; - for (i = 0; i < 62; i ++) { - uint32_t oa, ob, agtb, bgta; - uint32_t sab, sba, da, db; - uint32_t ctl; - - oa = a & 1; /* 1 if a is odd */ - ob = b & 1; /* 1 if b is odd */ - agtb = GT(a, b); /* 1 if a > b */ - bgta = GT(b, a); /* 1 if b > a */ - - sab = oa & ob & agtb; /* 1 if a <- a-b */ - sba = oa & ob & bgta; /* 1 if b <- b-a */ - - /* a <- a-b, u0 <- u0-u1, v0 <- v0-v1 */ - ctl = GT(v1, v0); - a -= b & -sab; - u0 -= (u1 - (r & -ctl)) & -sab; - v0 -= (v1 - (e & -ctl)) & -sab; - - /* b <- b-a, u1 <- u1-u0 mod r, v1 <- v1-v0 mod e */ - ctl = GT(v0, v1); - b -= a & -sba; - u1 -= (u0 - (r & -ctl)) & -sba; - v1 -= (v0 - (e & -ctl)) & -sba; - - da = NOT(oa) | sab; /* 1 if a <- a/2 */ - db = (oa & NOT(ob)) | sba; /* 1 if b <- b/2 */ - - /* a <- a/2, u0 <- u0/2, v0 <- v0/2 */ - ctl = v0 & 1; - a ^= (a ^ (a >> 1)) & -da; - u0 ^= (u0 ^ ((u0 >> 1) + (hr & -ctl))) & -da; - v0 ^= (v0 ^ ((v0 >> 1) + (he & -ctl))) & -da; - - /* b <- b/2, u1 <- u1/2 mod r, v1 <- v1/2 mod e */ - ctl = v1 & 1; - b ^= (b ^ (b >> 1)) & -db; - u1 ^= (u1 ^ ((u1 >> 1) + (hr & -ctl))) & -db; - v1 ^= (v1 ^ ((v1 >> 1) + (he & -ctl))) & -db; - } - - /* - * Check that the GCD is indeed 1. If not, then the key is invalid - * (and there's no harm in leaking that piece of information). - */ - if (a != 1) { - return 0; - } - - /* - * Now we have u0*e - v0*r = 1. Let's compute the result as: - * d = u0 + v0*k - * We still have k in the tmp[] array, and its announced bit - * length is that of phi. - */ - m = k + 1 + len; - m[0] = (1 << 5) + 1; /* bit length is 32 bits, encoded */ - m[1] = v0 & 0x7FFFFFFF; - m[2] = v0 >> 31; - z = m + 3; - br_i31_zero(z, k[0]); - z[1] = u0 & 0x7FFFFFFF; - z[2] = u0 >> 31; - br_i31_mulacc(z, k, m); - - /* - * Encode the result. - */ - br_i31_encode(d, dlen, z); - return dlen; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_i31_pub.c b/src/tls/bearssl/rsa_i31_pub.c deleted file mode 100644 index 5de019938..000000000 --- a/src/tls/bearssl/rsa_i31_pub.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * As a strict minimum, we need four buffers that can hold a - * modular integer. - */ -#define TLEN (4 * (2 + ((BR_MAX_RSA_SIZE + 30) / 31))) - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i31_public(unsigned char *x, size_t xlen, - const br_rsa_public_key *pk) -{ - const unsigned char *n; - size_t nlen; - uint32_t tmp[1 + TLEN]; - uint32_t *m, *a, *t; - size_t fwlen; - long z; - uint32_t m0i, r; - - /* - * Get the actual length of the modulus, and see if it fits within - * our stack buffer. We also check that the length of x[] is valid. - */ - n = pk->n; - nlen = pk->nlen; - while (nlen > 0 && *n == 0) { - n ++; - nlen --; - } - if (nlen == 0 || nlen > (BR_MAX_RSA_SIZE >> 3) || xlen != nlen) { - return 0; - } - z = (long)nlen << 3; - fwlen = 1; - while (z > 0) { - z -= 31; - fwlen ++; - } - /* - * Round up length to an even number. - */ - fwlen += (fwlen & 1); - - /* - * The modulus gets decoded into m[]. - * The value to exponentiate goes into a[]. - * The temporaries for modular exponentiation are in t[]. - */ - m = tmp; - a = m + fwlen; - t = m + 2 * fwlen; - - /* - * Decode the modulus. - */ - br_i31_decode(m, n, nlen); - m0i = br_i31_ninv31(m[1]); - - /* - * Note: if m[] is even, then m0i == 0. Otherwise, m0i must be - * an odd integer. - */ - r = m0i & 1; - - /* - * Decode x[] into a[]; we also check that its value is proper. - */ - r &= br_i31_decode_mod(a, x, xlen, m); - - /* - * Compute the modular exponentiation. - */ - br_i31_modpow_opt(a, pk->e, pk->elen, m, m0i, t, TLEN - 2 * fwlen); - - /* - * Encode the result. - */ - br_i31_encode(x, xlen, a); - return r; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_i31_pubexp.c b/src/tls/bearssl/rsa_i31_pubexp.c deleted file mode 100644 index 5df1b34e9..000000000 --- a/src/tls/bearssl/rsa_i31_pubexp.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * Recompute public exponent, based on factor p and reduced private - * exponent dp. - */ -static uint32_t -get_pubexp(const unsigned char *pbuf, size_t plen, - const unsigned char *dpbuf, size_t dplen) -{ - /* - * dp is the inverse of e modulo p-1. If p = 3 mod 4, then - * p-1 = 2*((p-1)/2). Taken modulo 2, e is odd and has inverse 1; - * thus, dp must be odd. - * - * We compute the inverse of dp modulo (p-1)/2. This requires - * first reducing dp modulo (p-1)/2 (this can be done with a - * conditional subtract, no need to use the generic modular - * reduction function); then, we use moddiv. - */ - - uint32_t tmp[6 * ((BR_MAX_RSA_FACTOR + 61) / 31)]; - uint32_t *p, *dp, *x; - size_t len; - uint32_t e; - - /* - * Compute actual factor length (in bytes) and check that it fits - * under our size constraints. - */ - while (plen > 0 && *pbuf == 0) { - pbuf ++; - plen --; - } - if (plen == 0 || plen < 5 || plen > (BR_MAX_RSA_FACTOR / 8)) { - return 0; - } - - /* - * Compute actual reduced exponent length (in bytes) and check that - * it is not longer than p. - */ - while (dplen > 0 && *dpbuf == 0) { - dpbuf ++; - dplen --; - } - if (dplen > plen || dplen == 0 - || (dplen == plen && dpbuf[0] > pbuf[0])) - { - return 0; - } - - /* - * Verify that p = 3 mod 4 and that dp is odd. - */ - if ((pbuf[plen - 1] & 3) != 3 || (dpbuf[dplen - 1] & 1) != 1) { - return 0; - } - - /* - * Decode p and compute (p-1)/2. - */ - p = tmp; - br_i31_decode(p, pbuf, plen); - len = (p[0] + 63) >> 5; - br_i31_rshift(p, 1); - - /* - * Decode dp and make sure its announced bit length matches that of - * p (we already know that the size of dp, in bits, does not exceed - * the size of p, so we just have to copy the header word). - */ - dp = p + len; - memset(dp, 0, len * sizeof *dp); - br_i31_decode(dp, dpbuf, dplen); - dp[0] = p[0]; - - /* - * Subtract (p-1)/2 from dp if necessary. - */ - br_i31_sub(dp, p, NOT(br_i31_sub(dp, p, 0))); - - /* - * If another subtraction is needed, then this means that the - * value was invalid. We don't care to leak information about - * invalid keys. - */ - if (br_i31_sub(dp, p, 0) == 0) { - return 0; - } - - /* - * Invert dp modulo (p-1)/2. If the inversion fails, then the - * key value was invalid. - */ - x = dp + len; - br_i31_zero(x, p[0]); - x[1] = 1; - if (br_i31_moddiv(x, dp, p, br_i31_ninv31(p[1]), x + len) == 0) { - return 0; - } - - /* - * We now have an inverse. We must set it to zero (error) if its - * length is greater than 32 bits and/or if it is an even integer. - * Take care that the bit_length function returns an encoded - * bit length. - */ - e = (uint32_t)x[1] | ((uint32_t)x[2] << 31); - e &= -LT(br_i31_bit_length(x + 1, len - 1), 34); - e &= -(e & 1); - return e; -} - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i31_compute_pubexp(const br_rsa_private_key *sk) -{ - /* - * Get the public exponent from both p and q. This is the right - * exponent if we get twice the same value. - */ - uint32_t ep, eq; - - ep = get_pubexp(sk->p, sk->plen, sk->dp, sk->dplen); - eq = get_pubexp(sk->q, sk->qlen, sk->dq, sk->dqlen); - return ep & -EQ(ep, eq); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_i32_oaep_decrypt.c b/src/tls/bearssl/rsa_i32_oaep_decrypt.c deleted file mode 100644 index f6575dcf7..000000000 --- a/src/tls/bearssl/rsa_i32_oaep_decrypt.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i32_oaep_decrypt(const br_hash_class *dig, - const void *label, size_t label_len, - const br_rsa_private_key *sk, void *data, size_t *len) -{ - uint32_t r; - - if (*len != ((sk->n_bitlen + 7) >> 3)) { - return 0; - } - r = br_rsa_i32_private(data, sk); - r &= br_rsa_oaep_unpad(dig, label, label_len, data, len); - return r; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_i32_oaep_encrypt.c b/src/tls/bearssl/rsa_i32_oaep_encrypt.c deleted file mode 100644 index dcedb3a80..000000000 --- a/src/tls/bearssl/rsa_i32_oaep_encrypt.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_rsa.h */ -size_t -br_rsa_i32_oaep_encrypt( - const br_prng_class **rnd, const br_hash_class *dig, - const void *label, size_t label_len, - const br_rsa_public_key *pk, - void *dst, size_t dst_max_len, - const void *src, size_t src_len) -{ - size_t dlen; - - dlen = br_rsa_oaep_pad(rnd, dig, label, label_len, - pk, dst, dst_max_len, src, src_len); - if (dlen == 0) { - return 0; - } - return dlen & -(size_t)br_rsa_i32_public(dst, dlen, pk); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_i32_pkcs1_sign.c b/src/tls/bearssl/rsa_i32_pkcs1_sign.c deleted file mode 100644 index 6655aa34c..000000000 --- a/src/tls/bearssl/rsa_i32_pkcs1_sign.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i32_pkcs1_sign(const unsigned char *hash_oid, - const unsigned char *hash, size_t hash_len, - const br_rsa_private_key *sk, unsigned char *x) -{ - if (!br_rsa_pkcs1_sig_pad(hash_oid, hash, hash_len, sk->n_bitlen, x)) { - return 0; - } - return br_rsa_i32_private(x, sk); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_i32_pkcs1_vrfy.c b/src/tls/bearssl/rsa_i32_pkcs1_vrfy.c deleted file mode 100644 index eeecc97e3..000000000 --- a/src/tls/bearssl/rsa_i32_pkcs1_vrfy.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i32_pkcs1_vrfy(const unsigned char *x, size_t xlen, - const unsigned char *hash_oid, size_t hash_len, - const br_rsa_public_key *pk, unsigned char *hash_out) -{ - unsigned char sig[BR_MAX_RSA_SIZE >> 3]; - - if (xlen > (sizeof sig)) { - return 0; - } - memcpy(sig, x, xlen); - if (!br_rsa_i32_public(sig, xlen, pk)) { - return 0; - } - return br_rsa_pkcs1_sig_unpad(sig, xlen, hash_oid, hash_len, hash_out); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_i32_priv.c b/src/tls/bearssl/rsa_i32_priv.c deleted file mode 100644 index 5ed1537a1..000000000 --- a/src/tls/bearssl/rsa_i32_priv.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -#define U (1 + (BR_MAX_RSA_FACTOR >> 5)) - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i32_private(unsigned char *x, const br_rsa_private_key *sk) -{ - const unsigned char *p, *q; - size_t plen, qlen; - uint32_t tmp[6 * U]; - uint32_t *mp, *mq, *s1, *s2, *t1, *t2, *t3; - uint32_t p0i, q0i; - size_t xlen, u; - uint32_t r; - - /* - * All our temporary buffers are from the tmp[] array. - * - * The mp, mq, s1, s2, t1 and t2 buffers are large enough to - * contain a RSA factor. The t3 buffer can contain a complete - * RSA modulus. t3 shares its storage space with s2, s1 and t1, - * in that order (this is important, see below). - */ - mq = tmp; - mp = tmp + U; - t2 = tmp + 2 * U; - s2 = tmp + 3 * U; - s1 = tmp + 4 * U; - t1 = tmp + 5 * U; - t3 = s2; - - /* - * Compute the actual lengths (in bytes) of p and q, and check - * that they fit within our stack buffers. - */ - p = sk->p; - plen = sk->plen; - while (plen > 0 && *p == 0) { - p ++; - plen --; - } - q = sk->q; - qlen = sk->qlen; - while (qlen > 0 && *q == 0) { - q ++; - qlen --; - } - if (plen > (BR_MAX_RSA_FACTOR >> 3) - || qlen > (BR_MAX_RSA_FACTOR >> 3)) - { - return 0; - } - - /* - * Decode p and q. - */ - br_i32_decode(mp, p, plen); - br_i32_decode(mq, q, qlen); - - /* - * Recompute modulus, to compare with the source value. - */ - br_i32_zero(t2, mp[0]); - br_i32_mulacc(t2, mp, mq); - xlen = (sk->n_bitlen + 7) >> 3; - br_i32_encode(t2 + 2 * U, xlen, t2); - u = xlen; - r = 0; - while (u > 0) { - uint32_t wn, wx; - - u --; - wn = ((unsigned char *)(t2 + 2 * U))[u]; - wx = x[u]; - r = ((wx - (wn + r)) >> 8) & 1; - } - - /* - * Compute s1 = x^dp mod p. - */ - p0i = br_i32_ninv32(mp[1]); - br_i32_decode_reduce(s1, x, xlen, mp); - br_i32_modpow(s1, sk->dp, sk->dplen, mp, p0i, t1, t2); - - /* - * Compute s2 = x^dq mod q. - */ - q0i = br_i32_ninv32(mq[1]); - br_i32_decode_reduce(s2, x, xlen, mq); - br_i32_modpow(s2, sk->dq, sk->dqlen, mq, q0i, t1, t2); - - /* - * Compute: - * h = (s1 - s2)*(1/q) mod p - * s1 is an integer modulo p, but s2 is modulo q. PKCS#1 is - * unclear about whether p may be lower than q (some existing, - * widely deployed implementations of RSA don't tolerate p < q), - * but we want to support that occurrence, so we need to use the - * reduction function. - * - * Since we use br_i32_decode_reduce() for iq (purportedly, the - * inverse of q modulo p), we also tolerate improperly large - * values for this parameter. - */ - br_i32_reduce(t2, s2, mp); - br_i32_add(s1, mp, br_i32_sub(s1, t2, 1)); - br_i32_to_monty(s1, mp); - br_i32_decode_reduce(t1, sk->iq, sk->iqlen, mp); - br_i32_montymul(t2, s1, t1, mp, p0i); - - /* - * h is now in t2. We compute the final result: - * s = s2 + q*h - * All these operations are non-modular. - * - * We need mq, s2 and t2. We use the t3 buffer as destination. - * The buffers mp, s1 and t1 are no longer needed. Moreover, - * the first step is to copy s2 into the destination buffer t3. - * We thus arranged for t3 to actually share space with s2, and - * to be followed by the space formerly used by s1 and t1. - */ - br_i32_mulacc(t3, mq, t2); - - /* - * Encode the result. Since we already checked the value of xlen, - * we can just use it right away. - */ - br_i32_encode(x, xlen, t3); - - /* - * The only error conditions remaining at that point are invalid - * values for p and q (even integers). - */ - return p0i & q0i & r; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_i32_pub.c b/src/tls/bearssl/rsa_i32_pub.c deleted file mode 100644 index 2101b2e04..000000000 --- a/src/tls/bearssl/rsa_i32_pub.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i32_public(unsigned char *x, size_t xlen, - const br_rsa_public_key *pk) -{ - const unsigned char *n; - size_t nlen; - uint32_t m[1 + (BR_MAX_RSA_SIZE >> 5)]; - uint32_t a[1 + (BR_MAX_RSA_SIZE >> 5)]; - uint32_t t1[1 + (BR_MAX_RSA_SIZE >> 5)]; - uint32_t t2[1 + (BR_MAX_RSA_SIZE >> 5)]; - uint32_t m0i, r; - - /* - * Get the actual length of the modulus, and see if it fits within - * our stack buffer. We also check that the length of x[] is valid. - */ - n = pk->n; - nlen = pk->nlen; - while (nlen > 0 && *n == 0) { - n ++; - nlen --; - } - if (nlen == 0 || nlen > (BR_MAX_RSA_SIZE >> 3) || xlen != nlen) { - return 0; - } - br_i32_decode(m, n, nlen); - m0i = br_i32_ninv32(m[1]); - - /* - * Note: if m[] is even, then m0i == 0. Otherwise, m0i must be - * an odd integer. - */ - r = m0i & 1; - - /* - * Decode x[] into a[]; we also check that its value is proper. - */ - r &= br_i32_decode_mod(a, x, xlen, m); - - /* - * Compute the modular exponentiation. - */ - br_i32_modpow(a, pk->e, pk->elen, m, m0i, t1, t2); - - /* - * Encode the result. - */ - br_i32_encode(x, xlen, a); - return r; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_i62_keygen.c b/src/tls/bearssl/rsa_i62_keygen.c deleted file mode 100644 index 72adab443..000000000 --- a/src/tls/bearssl/rsa_i62_keygen.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -#if BR_INT128 || BR_UMUL128 - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i62_keygen(const br_prng_class **rng, - br_rsa_private_key *sk, void *kbuf_priv, - br_rsa_public_key *pk, void *kbuf_pub, - unsigned size, uint32_t pubexp) -{ - return br_rsa_i31_keygen_inner(rng, - sk, kbuf_priv, pk, kbuf_pub, size, pubexp, - &br_i62_modpow_opt_as_i31); -} - -/* see bearssl_rsa.h */ -br_rsa_keygen -br_rsa_i62_keygen_get() -{ - return &br_rsa_i62_keygen; -} - -#else - -/* see bearssl_rsa.h */ -br_rsa_keygen -br_rsa_i62_keygen_get() -{ - return 0; -} - -#endif - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_i62_oaep_decrypt.c b/src/tls/bearssl/rsa_i62_oaep_decrypt.c deleted file mode 100644 index 8dcee5c7c..000000000 --- a/src/tls/bearssl/rsa_i62_oaep_decrypt.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -#if BR_INT128 || BR_UMUL128 - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i62_oaep_decrypt(const br_hash_class *dig, - const void *label, size_t label_len, - const br_rsa_private_key *sk, void *data, size_t *len) -{ - uint32_t r; - - if (*len != ((sk->n_bitlen + 7) >> 3)) { - return 0; - } - r = br_rsa_i62_private(data, sk); - r &= br_rsa_oaep_unpad(dig, label, label_len, data, len); - return r; -} - -/* see bearssl_rsa.h */ -br_rsa_oaep_decrypt -br_rsa_i62_oaep_decrypt_get(void) -{ - return &br_rsa_i62_oaep_decrypt; -} - -#else - -/* see bearssl_rsa.h */ -br_rsa_oaep_decrypt -br_rsa_i62_oaep_decrypt_get(void) -{ - return 0; -} - -#endif - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_i62_oaep_encrypt.c b/src/tls/bearssl/rsa_i62_oaep_encrypt.c deleted file mode 100644 index ecf873e3f..000000000 --- a/src/tls/bearssl/rsa_i62_oaep_encrypt.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -#if BR_INT128 || BR_UMUL128 - -/* see bearssl_rsa.h */ -size_t -br_rsa_i62_oaep_encrypt( - const br_prng_class **rnd, const br_hash_class *dig, - const void *label, size_t label_len, - const br_rsa_public_key *pk, - void *dst, size_t dst_max_len, - const void *src, size_t src_len) -{ - size_t dlen; - - dlen = br_rsa_oaep_pad(rnd, dig, label, label_len, - pk, dst, dst_max_len, src, src_len); - if (dlen == 0) { - return 0; - } - return dlen & -(size_t)br_rsa_i62_public(dst, dlen, pk); -} - -/* see bearssl_rsa.h */ -br_rsa_oaep_encrypt -br_rsa_i62_oaep_encrypt_get(void) -{ - return &br_rsa_i62_oaep_encrypt; -} - -#else - -/* see bearssl_rsa.h */ -br_rsa_oaep_encrypt -br_rsa_i62_oaep_encrypt_get(void) -{ - return 0; -} - -#endif - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_i62_pkcs1_sign.c b/src/tls/bearssl/rsa_i62_pkcs1_sign.c deleted file mode 100644 index df31d406a..000000000 --- a/src/tls/bearssl/rsa_i62_pkcs1_sign.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -#if BR_INT128 || BR_UMUL128 - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i62_pkcs1_sign(const unsigned char *hash_oid, - const unsigned char *hash, size_t hash_len, - const br_rsa_private_key *sk, unsigned char *x) -{ - if (!br_rsa_pkcs1_sig_pad(hash_oid, hash, hash_len, sk->n_bitlen, x)) { - return 0; - } - return br_rsa_i62_private(x, sk); -} - -/* see bearssl_rsa.h */ -br_rsa_pkcs1_sign -br_rsa_i62_pkcs1_sign_get(void) -{ - return &br_rsa_i62_pkcs1_sign; -} - -#else - -/* see bearssl_rsa.h */ -br_rsa_pkcs1_sign -br_rsa_i62_pkcs1_sign_get(void) -{ - return 0; -} - -#endif - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_i62_pkcs1_vrfy.c b/src/tls/bearssl/rsa_i62_pkcs1_vrfy.c deleted file mode 100644 index a9cc3125e..000000000 --- a/src/tls/bearssl/rsa_i62_pkcs1_vrfy.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -#if BR_INT128 || BR_UMUL128 - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i62_pkcs1_vrfy(const unsigned char *x, size_t xlen, - const unsigned char *hash_oid, size_t hash_len, - const br_rsa_public_key *pk, unsigned char *hash_out) -{ - unsigned char sig[BR_MAX_RSA_SIZE >> 3]; - - if (xlen > (sizeof sig)) { - return 0; - } - memcpy(sig, x, xlen); - if (!br_rsa_i62_public(sig, xlen, pk)) { - return 0; - } - return br_rsa_pkcs1_sig_unpad(sig, xlen, hash_oid, hash_len, hash_out); -} - -/* see bearssl_rsa.h */ -br_rsa_pkcs1_vrfy -br_rsa_i62_pkcs1_vrfy_get(void) -{ - return &br_rsa_i62_pkcs1_vrfy; -} - -#else - -/* see bearssl_rsa.h */ -br_rsa_pkcs1_vrfy -br_rsa_i62_pkcs1_vrfy_get(void) -{ - return 0; -} - -#endif - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_i62_priv.c b/src/tls/bearssl/rsa_i62_priv.c deleted file mode 100644 index 4f21d6732..000000000 --- a/src/tls/bearssl/rsa_i62_priv.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -#if BR_INT128 || BR_UMUL128 - -#define U (2 + ((BR_MAX_RSA_FACTOR + 30) / 31)) -#define TLEN (4 * U) /* TLEN is counted in 64-bit words */ - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i62_private(unsigned char *x, const br_rsa_private_key *sk) -{ - const unsigned char *p, *q; - size_t plen, qlen; - size_t fwlen; - uint32_t p0i, q0i; - size_t xlen, u; - uint64_t tmp[TLEN]; - long z; - uint32_t *mp, *mq, *s1, *s2, *t1, *t2, *t3; - uint32_t r; - - /* - * Compute the actual lengths of p and q, in bytes. - * These lengths are not considered secret (we cannot really hide - * them anyway in constant-time code). - */ - p = sk->p; - plen = sk->plen; - while (plen > 0 && *p == 0) { - p ++; - plen --; - } - q = sk->q; - qlen = sk->qlen; - while (qlen > 0 && *q == 0) { - q ++; - qlen --; - } - - /* - * Compute the maximum factor length, in words. - */ - z = (long)(plen > qlen ? plen : qlen) << 3; - fwlen = 1; - while (z > 0) { - z -= 31; - fwlen ++; - } - - /* - * Convert size to 62-bit words. - */ - fwlen = (fwlen + 1) >> 1; - - /* - * We need to fit at least 6 values in the stack buffer. - */ - if (6 * fwlen > TLEN) { - return 0; - } - - /* - * Compute signature length (in bytes). - */ - xlen = (sk->n_bitlen + 7) >> 3; - - /* - * Decode q. - */ - mq = (uint32_t *)tmp; - br_i31_decode(mq, q, qlen); - - /* - * Decode p. - */ - t1 = (uint32_t *)(tmp + fwlen); - br_i31_decode(t1, p, plen); - - /* - * Compute the modulus (product of the two factors), to compare - * it with the source value. We use br_i31_mulacc(), since it's - * already used later on. - */ - t2 = (uint32_t *)(tmp + 2 * fwlen); - br_i31_zero(t2, mq[0]); - br_i31_mulacc(t2, mq, t1); - - /* - * We encode the modulus into bytes, to perform the comparison - * with bytes. We know that the product length, in bytes, is - * exactly xlen. - * The comparison actually computes the carry when subtracting - * the modulus from the source value; that carry must be 1 for - * a value in the correct range. We keep it in r, which is our - * accumulator for the error code. - */ - t3 = (uint32_t *)(tmp + 4 * fwlen); - br_i31_encode(t3, xlen, t2); - u = xlen; - r = 0; - while (u > 0) { - uint32_t wn, wx; - - u --; - wn = ((unsigned char *)t3)[u]; - wx = x[u]; - r = ((wx - (wn + r)) >> 8) & 1; - } - - /* - * Move the decoded p to another temporary buffer. - */ - mp = (uint32_t *)(tmp + 2 * fwlen); - memmove(mp, t1, 2 * fwlen * sizeof *t1); - - /* - * Compute s2 = x^dq mod q. - */ - q0i = br_i31_ninv31(mq[1]); - s2 = (uint32_t *)(tmp + fwlen); - br_i31_decode_reduce(s2, x, xlen, mq); - r &= br_i62_modpow_opt(s2, sk->dq, sk->dqlen, mq, q0i, - tmp + 3 * fwlen, TLEN - 3 * fwlen); - - /* - * Compute s1 = x^dp mod p. - */ - p0i = br_i31_ninv31(mp[1]); - s1 = (uint32_t *)(tmp + 3 * fwlen); - br_i31_decode_reduce(s1, x, xlen, mp); - r &= br_i62_modpow_opt(s1, sk->dp, sk->dplen, mp, p0i, - tmp + 4 * fwlen, TLEN - 4 * fwlen); - - /* - * Compute: - * h = (s1 - s2)*(1/q) mod p - * s1 is an integer modulo p, but s2 is modulo q. PKCS#1 is - * unclear about whether p may be lower than q (some existing, - * widely deployed implementations of RSA don't tolerate p < q), - * but we want to support that occurrence, so we need to use the - * reduction function. - * - * Since we use br_i31_decode_reduce() for iq (purportedly, the - * inverse of q modulo p), we also tolerate improperly large - * values for this parameter. - */ - t1 = (uint32_t *)(tmp + 4 * fwlen); - t2 = (uint32_t *)(tmp + 5 * fwlen); - br_i31_reduce(t2, s2, mp); - br_i31_add(s1, mp, br_i31_sub(s1, t2, 1)); - br_i31_to_monty(s1, mp); - br_i31_decode_reduce(t1, sk->iq, sk->iqlen, mp); - br_i31_montymul(t2, s1, t1, mp, p0i); - - /* - * h is now in t2. We compute the final result: - * s = s2 + q*h - * All these operations are non-modular. - * - * We need mq, s2 and t2. We use the t3 buffer as destination. - * The buffers mp, s1 and t1 are no longer needed, so we can - * reuse them for t3. Moreover, the first step of the computation - * is to copy s2 into t3, after which s2 is not needed. Right - * now, mq is in slot 0, s2 is in slot 1, and t2 is in slot 5. - * Therefore, we have ample room for t3 by simply using s2. - */ - t3 = s2; - br_i31_mulacc(t3, mq, t2); - - /* - * Encode the result. Since we already checked the value of xlen, - * we can just use it right away. - */ - br_i31_encode(x, xlen, t3); - - /* - * The only error conditions remaining at that point are invalid - * values for p and q (even integers). - */ - return p0i & q0i & r; -} - -/* see bearssl_rsa.h */ -br_rsa_private -br_rsa_i62_private_get(void) -{ - return &br_rsa_i62_private; -} - -#else - -/* see bearssl_rsa.h */ -br_rsa_private -br_rsa_i62_private_get(void) -{ - return 0; -} - -#endif - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_i62_pub.c b/src/tls/bearssl/rsa_i62_pub.c deleted file mode 100644 index 69644640d..000000000 --- a/src/tls/bearssl/rsa_i62_pub.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -#if BR_INT128 || BR_UMUL128 - -/* - * As a strict minimum, we need four buffers that can hold a - * modular integer. But TLEN is expressed in 64-bit words. - */ -#define TLEN (2 * (2 + ((BR_MAX_RSA_SIZE + 30) / 31))) - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i62_public(unsigned char *x, size_t xlen, - const br_rsa_public_key *pk) -{ - const unsigned char *n; - size_t nlen; - uint64_t tmp[TLEN]; - uint32_t *m, *a; - size_t fwlen; - long z; - uint32_t m0i, r; - - /* - * Get the actual length of the modulus, and see if it fits within - * our stack buffer. We also check that the length of x[] is valid. - */ - n = pk->n; - nlen = pk->nlen; - while (nlen > 0 && *n == 0) { - n ++; - nlen --; - } - if (nlen == 0 || nlen > (BR_MAX_RSA_SIZE >> 3) || xlen != nlen) { - return 0; - } - z = (long)nlen << 3; - fwlen = 1; - while (z > 0) { - z -= 31; - fwlen ++; - } - /* - * Convert fwlen to a count in 62-bit words. - */ - fwlen = (fwlen + 1) >> 1; - - /* - * The modulus gets decoded into m[]. - * The value to exponentiate goes into a[]. - */ - m = (uint32_t *)tmp; - a = (uint32_t *)(tmp + fwlen); - - /* - * Decode the modulus. - */ - br_i31_decode(m, n, nlen); - m0i = br_i31_ninv31(m[1]); - - /* - * Note: if m[] is even, then m0i == 0. Otherwise, m0i must be - * an odd integer. - */ - r = m0i & 1; - - /* - * Decode x[] into a[]; we also check that its value is proper. - */ - r &= br_i31_decode_mod(a, x, xlen, m); - - /* - * Compute the modular exponentiation. - */ - br_i62_modpow_opt(a, pk->e, pk->elen, m, m0i, - tmp + 2 * fwlen, TLEN - 2 * fwlen); - - /* - * Encode the result. - */ - br_i31_encode(x, xlen, a); - return r; -} - -/* see bearssl_rsa.h */ -br_rsa_public -br_rsa_i62_public_get(void) -{ - return &br_rsa_i62_public; -} - -#else - -/* see bearssl_rsa.h */ -br_rsa_public -br_rsa_i62_public_get(void) -{ - return 0; -} - -#endif - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_oaep_pad.c b/src/tls/bearssl/rsa_oaep_pad.c deleted file mode 100644 index fe6daaff0..000000000 --- a/src/tls/bearssl/rsa_oaep_pad.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * Hash some data. This is put as a separate function so that stack - * allocation of the hash function context is done only for the duration - * of the hash. - */ -static void -hash_data(const br_hash_class *dig, void *dst, const void *src, size_t len) -{ - br_hash_compat_context hc; - - hc.vtable = dig; - dig->init(&hc.vtable); - dig->update(&hc.vtable, src, len); - dig->out(&hc.vtable, dst); -} - -/* see inner.h */ -size_t -br_rsa_oaep_pad(const br_prng_class **rnd, const br_hash_class *dig, - const void *label, size_t label_len, - const br_rsa_public_key *pk, - void *dst, size_t dst_max_len, - const void *src, size_t src_len) -{ - size_t k, hlen; - unsigned char *buf; - - hlen = br_digest_size(dig); - - /* - * Compute actual modulus length (in bytes). - */ - k = pk->nlen; - while (k > 0 && pk->n[k - 1] == 0) { - k --; - } - - /* - * An error is reported if: - * - the modulus is too short; - * - the source message length is too long; - * - the destination buffer is too short. - */ - if (k < ((hlen << 1) + 2) - || src_len > (k - (hlen << 1) - 2) - || dst_max_len < k) - { - return 0; - } - - /* - * Apply padding. At this point, things cannot fail. - */ - buf = dst; - - /* - * Assemble: DB = lHash || PS || 0x01 || M - * We first place the source message M with memmove(), so that - * overlaps between source and destination buffers are supported. - */ - memmove(buf + k - src_len, src, src_len); - hash_data(dig, buf + 1 + hlen, label, label_len); - memset(buf + 1 + (hlen << 1), 0, k - src_len - (hlen << 1) - 2); - buf[k - src_len - 1] = 0x01; - - /* - * Make the random seed. - */ - (*rnd)->generate(rnd, buf + 1, hlen); - - /* - * Mask DB with the mask generated from the seed. - */ - br_mgf1_xor(buf + 1 + hlen, k - hlen - 1, dig, buf + 1, hlen); - - /* - * Mask the seed with the mask generated from the masked DB. - */ - br_mgf1_xor(buf + 1, hlen, dig, buf + 1 + hlen, k - hlen - 1); - - /* - * Padding result: EM = 0x00 || maskedSeed || maskedDB. - */ - buf[0] = 0x00; - return k; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_oaep_unpad.c b/src/tls/bearssl/rsa_oaep_unpad.c deleted file mode 100644 index adec410d4..000000000 --- a/src/tls/bearssl/rsa_oaep_unpad.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * Hash some data and XOR the result into the provided buffer. This is put - * as a separate function so that stack allocation of the hash function - * context is done only for the duration of the hash. - */ -static void -xor_hash_data(const br_hash_class *dig, void *dst, const void *src, size_t len) -{ - br_hash_compat_context hc; - unsigned char tmp[64]; - unsigned char *buf; - size_t u, hlen; - - hc.vtable = dig; - dig->init(&hc.vtable); - dig->update(&hc.vtable, src, len); - dig->out(&hc.vtable, tmp); - buf = dst; - hlen = br_digest_size(dig); - for (u = 0; u < hlen; u ++) { - buf[u] ^= tmp[u]; - } -} - -/* see inner.h */ -uint32_t -br_rsa_oaep_unpad(const br_hash_class *dig, - const void *label, size_t label_len, - void *data, size_t *len) -{ - size_t u, k, hlen; - unsigned char *buf; - uint32_t r, s, zlen; - - hlen = br_digest_size(dig); - k = *len; - buf = data; - - /* - * There must be room for the padding. - */ - if (k < ((hlen << 1) + 2)) { - return 0; - } - - /* - * Unmask the seed, then the DB value. - */ - br_mgf1_xor(buf + 1, hlen, dig, buf + 1 + hlen, k - hlen - 1); - br_mgf1_xor(buf + 1 + hlen, k - hlen - 1, dig, buf + 1, hlen); - - /* - * Hash the label and XOR it with the value in the array; if - * they are equal then these should yield only zeros. - */ - xor_hash_data(dig, buf + 1 + hlen, label, label_len); - - /* - * At that point, if the padding was correct, when we should - * have: 0x00 || seed || 0x00 ... 0x00 0x01 || M - * Padding is valid as long as: - * - There is at least hlen+1 leading bytes of value 0x00. - * - There is at least one non-zero byte. - * - The first (leftmost) non-zero byte has value 0x01. - * - * Ultimately, we may leak the resulting message length, i.e. - * the position of the byte of value 0x01, but we must take care - * to do so only if the number of zero bytes has been verified - * to be at least hlen+1. - * - * The loop below counts the number of bytes of value 0x00, and - * checks that the next byte has value 0x01, in constant-time. - * - * - If the initial byte (before the seed) is not 0x00, then - * r and s are set to 0, and stay there. - * - Value r is 1 until the first non-zero byte is reached - * (after the seed); it switches to 0 at that point. - * - Value s is set to 1 if and only if the data encountered - * at the time of the transition of r from 1 to 0 has value - * exactly 0x01. - * - Value zlen counts the number of leading bytes of value zero - * (after the seed). - */ - r = 1 - ((buf[0] + 0xFF) >> 8); - s = 0; - zlen = 0; - for (u = hlen + 1; u < k; u ++) { - uint32_t w, nz; - - w = buf[u]; - - /* - * nz == 1 only for the first non-zero byte. - */ - nz = r & ((w + 0xFF) >> 8); - s |= nz & EQ(w, 0x01); - r &= NOT(nz); - zlen += r; - } - - /* - * Padding is correct only if s == 1, _and_ zlen >= hlen. - */ - s &= GE(zlen, (uint32_t)hlen); - - /* - * At that point, padding was verified, and we are now allowed - * to make conditional jumps. - */ - if (s) { - size_t plen; - - plen = 2 + hlen + zlen; - k -= plen; - memmove(buf, buf + plen, k); - *len = k; - } - return s; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_pkcs1_sig_pad.c b/src/tls/bearssl/rsa_pkcs1_sig_pad.c deleted file mode 100644 index 7fc4a5e2a..000000000 --- a/src/tls/bearssl/rsa_pkcs1_sig_pad.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -uint32_t -br_rsa_pkcs1_sig_pad(const unsigned char *hash_oid, - const unsigned char *hash, size_t hash_len, - uint32_t n_bitlen, unsigned char *x) -{ - size_t u, x3, xlen; - - /* - * Padded hash value has format: - * 00 01 FF .. FF 00 30 x1 30 x2 06 x3 OID 05 00 04 x4 HASH - * - * with the following rules: - * - * -- Total length is equal to the modulus length (unsigned - * encoding). - * - * -- There must be at least eight bytes of value 0xFF. - * - * -- x4 is equal to the hash length (hash_len). - * - * -- x3 is equal to the encoded OID value length (hash_oid[0]). - * - * -- x2 = x3 + 4. - * - * -- x1 = x2 + x4 + 4 = x3 + x4 + 8. - * - * Note: the "05 00" is optional (signatures with and without - * that sequence exist in practice), but notes in PKCS#1 seem to - * indicate that the presence of that sequence (specifically, - * an ASN.1 NULL value for the hash parameters) may be slightly - * more "standard" than the opposite. - */ - xlen = (n_bitlen + 7) >> 3; - - if (hash_oid == NULL) { - if (xlen < hash_len + 11) { - return 0; - } - x[0] = 0x00; - x[1] = 0x01; - u = xlen - hash_len; - memset(x + 2, 0xFF, u - 3); - x[u - 1] = 0x00; - } else { - x3 = hash_oid[0]; - - /* - * Check that there is enough room for all the elements, - * including at least eight bytes of value 0xFF. - */ - if (xlen < (x3 + hash_len + 21)) { - return 0; - } - x[0] = 0x00; - x[1] = 0x01; - u = xlen - x3 - hash_len - 11; - memset(x + 2, 0xFF, u - 2); - x[u] = 0x00; - x[u + 1] = 0x30; - x[u + 2] = x3 + hash_len + 8; - x[u + 3] = 0x30; - x[u + 4] = x3 + 4; - x[u + 5] = 0x06; - memcpy(x + u + 6, hash_oid, x3 + 1); - u += x3 + 7; - x[u ++] = 0x05; - x[u ++] = 0x00; - x[u ++] = 0x04; - x[u ++] = hash_len; - } - memcpy(x + u, hash, hash_len); - return 1; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_pkcs1_sig_unpad.c b/src/tls/bearssl/rsa_pkcs1_sig_unpad.c deleted file mode 100644 index 2ab198203..000000000 --- a/src/tls/bearssl/rsa_pkcs1_sig_unpad.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_pkcs1_sig_unpad(const unsigned char *sig, size_t sig_len, - const unsigned char *hash_oid, size_t hash_len, - unsigned char *hash_out) -{ - static const unsigned char pad1[] = { - 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF - }; - - unsigned char pad2[43]; - size_t u, x2, x3, pad_len, zlen; - - if (sig_len < 11) { - return 0; - } - - /* - * Expected format: - * 00 01 FF ... FF 00 30 x1 30 x2 06 x3 OID [ 05 00 ] 04 x4 HASH - * - * with the following rules: - * - * -- Total length is that of the modulus and the signature - * (this was already verified by br_rsa_i31_public()). - * - * -- There are at least eight bytes of value 0xFF. - * - * -- x4 is equal to the hash length (hash_len). - * - * -- x3 is equal to the encoded OID value length (so x3 is the - * first byte of hash_oid[]). - * - * -- If the "05 00" is present, then x2 == x3 + 4; otherwise, - * x2 == x3 + 2. - * - * -- x1 == x2 + x4 + 4. - * - * So the total length after the last "FF" is either x3 + x4 + 11 - * (with the "05 00") or x3 + x4 + 9 (without the "05 00"). - */ - - /* - * Check the "00 01 FF .. FF 00" with at least eight 0xFF bytes. - * The comparison is valid because we made sure that the signature - * is at least 11 bytes long. - */ - if (memcmp(sig, pad1, sizeof pad1) != 0) { - return 0; - } - for (u = sizeof pad1; u < sig_len; u ++) { - if (sig[u] != 0xFF) { - break; - } - } - - /* - * Remaining length is sig_len - u bytes (including the 00 just - * after the last FF). This must be equal to one of the two - * possible values (depending on whether the "05 00" sequence is - * present or not). - */ - if (hash_oid == NULL) { - if (sig_len - u != hash_len + 1 || sig[u] != 0x00) { - return 0; - } - } else { - x3 = hash_oid[0]; - pad_len = x3 + 9; - memset(pad2, 0, pad_len); - zlen = sig_len - u - hash_len; - if (zlen == pad_len) { - x2 = x3 + 2; - } else if (zlen == pad_len + 2) { - x2 = x3 + 4; - pad_len = zlen; - pad2[pad_len - 4] = 0x05; - } else { - return 0; - } - pad2[1] = 0x30; - pad2[2] = x2 + hash_len + 4; - pad2[3] = 0x30; - pad2[4] = x2; - pad2[5] = 0x06; - memcpy(pad2 + 6, hash_oid, x3 + 1); - pad2[pad_len - 2] = 0x04; - pad2[pad_len - 1] = hash_len; - if (memcmp(pad2, sig + u, pad_len) != 0) { - return 0; - } - } - memcpy(hash_out, sig + sig_len - hash_len, hash_len); - return 1; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/rsa_ssl_decrypt.c b/src/tls/bearssl/rsa_ssl_decrypt.c deleted file mode 100644 index 6464c328d..000000000 --- a/src/tls/bearssl/rsa_ssl_decrypt.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_ssl_decrypt(br_rsa_private core, const br_rsa_private_key *sk, - unsigned char *data, size_t len) -{ - uint32_t x; - size_t u; - - /* - * A first check on length. Since this test works only on the - * buffer length, it needs not (and cannot) be constant-time. - */ - if (len < 59 || len != (sk->n_bitlen + 7) >> 3) { - return 0; - } - x = core(data, sk); - - x &= EQ(data[0], 0x00); - x &= EQ(data[1], 0x02); - for (u = 2; u < (len - 49); u ++) { - x &= NEQ(data[u], 0); - } - x &= EQ(data[len - 49], 0x00); - memmove(data, data + len - 48, 48); - return x; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/settings.c b/src/tls/bearssl/settings.c deleted file mode 100644 index 509003f92..000000000 --- a/src/tls/bearssl/settings.c +++ /dev/null @@ -1,311 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -static const br_config_option config[] = { - { "BR_64", -#if BR_64 - 1 -#else - 0 -#endif - }, - { "BR_AES_X86NI", -#if BR_AES_X86NI - 1 -#else - 0 -#endif - }, - { "BR_amd64", -#if BR_amd64 - 1 -#else - 0 -#endif - }, - { "BR_ARMEL_CORTEXM_GCC", -#if BR_ARMEL_CORTEXM_GCC - 1 -#else - 0 -#endif - }, - { "BR_BE_UNALIGNED", -#if BR_BE_UNALIGNED - 1 -#else - 0 -#endif - }, - { "BR_CLANG", -#if BR_CLANG - 1 -#else - 0 -#endif - }, - { "BR_CLANG_3_7", -#if BR_CLANG_3_7 - 1 -#else - 0 -#endif - }, - { "BR_CLANG_3_8", -#if BR_CLANG_3_8 - 1 -#else - 0 -#endif - }, - { "BR_CT_MUL15", -#if BR_CT_MUL15 - 1 -#else - 0 -#endif - }, - { "BR_CT_MUL31", -#if BR_CT_MUL31 - 1 -#else - 0 -#endif - }, - { "BR_GCC", -#if BR_GCC - 1 -#else - 0 -#endif - }, - { "BR_GCC_4_4", -#if BR_GCC_4_4 - 1 -#else - 0 -#endif - }, - { "BR_GCC_4_5", -#if BR_GCC_4_5 - 1 -#else - 0 -#endif - }, - { "BR_GCC_4_6", -#if BR_GCC_4_6 - 1 -#else - 0 -#endif - }, - { "BR_GCC_4_7", -#if BR_GCC_4_7 - 1 -#else - 0 -#endif - }, - { "BR_GCC_4_8", -#if BR_GCC_4_8 - 1 -#else - 0 -#endif - }, - { "BR_GCC_4_9", -#if BR_GCC_4_9 - 1 -#else - 0 -#endif - }, - { "BR_GCC_5_0", -#if BR_GCC_5_0 - 1 -#else - 0 -#endif - }, - { "BR_i386", -#if BR_i386 - 1 -#else - 0 -#endif - }, - { "BR_INT128", -#if BR_INT128 - 1 -#else - 0 -#endif - }, - { "BR_LE_UNALIGNED", -#if BR_LE_UNALIGNED - 1 -#else - 0 -#endif - }, - { "BR_LOMUL", -#if BR_LOMUL - 1 -#else - 0 -#endif - }, - { "BR_MAX_EC_SIZE", BR_MAX_EC_SIZE }, - { "BR_MAX_RSA_SIZE", BR_MAX_RSA_SIZE }, - { "BR_MAX_RSA_FACTOR", BR_MAX_RSA_FACTOR }, - { "BR_MSC", -#if BR_MSC - 1 -#else - 0 -#endif - }, - { "BR_MSC_2005", -#if BR_MSC_2005 - 1 -#else - 0 -#endif - }, - { "BR_MSC_2008", -#if BR_MSC_2008 - 1 -#else - 0 -#endif - }, - { "BR_MSC_2010", -#if BR_MSC_2010 - 1 -#else - 0 -#endif - }, - { "BR_MSC_2012", -#if BR_MSC_2012 - 1 -#else - 0 -#endif - }, - { "BR_MSC_2013", -#if BR_MSC_2013 - 1 -#else - 0 -#endif - }, - { "BR_MSC_2015", -#if BR_MSC_2015 - 1 -#else - 0 -#endif - }, - { "BR_POWER8", -#if BR_POWER8 - 1 -#else - 0 -#endif - }, - { "BR_RDRAND", -#if BR_RDRAND - 1 -#else - 0 -#endif - }, - { "BR_SLOW_MUL", -#if BR_SLOW_MUL - 1 -#else - 0 -#endif - }, - { "BR_SLOW_MUL15", -#if BR_SLOW_MUL15 - 1 -#else - 0 -#endif - }, - { "BR_SSE2", -#if BR_SSE2 - 1 -#else - 0 -#endif - }, - { "BR_UMUL128", -#if BR_UMUL128 - 1 -#else - 0 -#endif - }, - { "BR_USE_UNIX_TIME", -#if BR_USE_UNIX_TIME - 1 -#else - 0 -#endif - }, - { "BR_USE_WIN32_RAND", -#if BR_USE_WIN32_RAND - 1 -#else - 0 -#endif - }, - { "BR_USE_WIN32_TIME", -#if BR_USE_WIN32_TIME - 1 -#else - 0 -#endif - }, - - { NULL, 0 } -}; - -/* see bearssl.h */ -const br_config_option * -br_get_config(void) -{ - return config; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/sha1.c b/src/tls/bearssl/sha1.c deleted file mode 100644 index 935e63b82..000000000 --- a/src/tls/bearssl/sha1.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -#define F(B, C, D) ((((C) ^ (D)) & (B)) ^ (D)) -#define G(B, C, D) ((B) ^ (C) ^ (D)) -#define H(B, C, D) (((D) & (C)) | (((D) | (C)) & (B))) -#define I(B, C, D) G(B, C, D) - -#define ROTL(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) - -#define K1 ((uint32_t)0x5A827999) -#define K2 ((uint32_t)0x6ED9EBA1) -#define K3 ((uint32_t)0x8F1BBCDC) -#define K4 ((uint32_t)0xCA62C1D6) - -/* see inner.h */ -const uint32_t br_sha1_IV[5] = { - 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 -}; - -/* see inner.h */ -void -br_sha1_round(const unsigned char *buf, uint32_t *val) -{ - uint32_t m[80]; - uint32_t a, b, c, d, e; - int i; - - a = val[0]; - b = val[1]; - c = val[2]; - d = val[3]; - e = val[4]; - br_range_dec32be(m, 16, buf); - for (i = 16; i < 80; i ++) { - uint32_t x = m[i - 3] ^ m[i - 8] ^ m[i - 14] ^ m[i - 16]; - m[i] = ROTL(x, 1); - } - - for (i = 0; i < 20; i += 5) { - e += ROTL(a, 5) + F(b, c, d) + K1 + m[i + 0]; b = ROTL(b, 30); - d += ROTL(e, 5) + F(a, b, c) + K1 + m[i + 1]; a = ROTL(a, 30); - c += ROTL(d, 5) + F(e, a, b) + K1 + m[i + 2]; e = ROTL(e, 30); - b += ROTL(c, 5) + F(d, e, a) + K1 + m[i + 3]; d = ROTL(d, 30); - a += ROTL(b, 5) + F(c, d, e) + K1 + m[i + 4]; c = ROTL(c, 30); - } - for (i = 20; i < 40; i += 5) { - e += ROTL(a, 5) + G(b, c, d) + K2 + m[i + 0]; b = ROTL(b, 30); - d += ROTL(e, 5) + G(a, b, c) + K2 + m[i + 1]; a = ROTL(a, 30); - c += ROTL(d, 5) + G(e, a, b) + K2 + m[i + 2]; e = ROTL(e, 30); - b += ROTL(c, 5) + G(d, e, a) + K2 + m[i + 3]; d = ROTL(d, 30); - a += ROTL(b, 5) + G(c, d, e) + K2 + m[i + 4]; c = ROTL(c, 30); - } - for (i = 40; i < 60; i += 5) { - e += ROTL(a, 5) + H(b, c, d) + K3 + m[i + 0]; b = ROTL(b, 30); - d += ROTL(e, 5) + H(a, b, c) + K3 + m[i + 1]; a = ROTL(a, 30); - c += ROTL(d, 5) + H(e, a, b) + K3 + m[i + 2]; e = ROTL(e, 30); - b += ROTL(c, 5) + H(d, e, a) + K3 + m[i + 3]; d = ROTL(d, 30); - a += ROTL(b, 5) + H(c, d, e) + K3 + m[i + 4]; c = ROTL(c, 30); - } - for (i = 60; i < 80; i += 5) { - e += ROTL(a, 5) + I(b, c, d) + K4 + m[i + 0]; b = ROTL(b, 30); - d += ROTL(e, 5) + I(a, b, c) + K4 + m[i + 1]; a = ROTL(a, 30); - c += ROTL(d, 5) + I(e, a, b) + K4 + m[i + 2]; e = ROTL(e, 30); - b += ROTL(c, 5) + I(d, e, a) + K4 + m[i + 3]; d = ROTL(d, 30); - a += ROTL(b, 5) + I(c, d, e) + K4 + m[i + 4]; c = ROTL(c, 30); - } - - val[0] += a; - val[1] += b; - val[2] += c; - val[3] += d; - val[4] += e; -} - -/* see bearssl.h */ -void -br_sha1_init(br_sha1_context *cc) -{ - cc->vtable = &br_sha1_vtable; - memcpy(cc->val, br_sha1_IV, sizeof cc->val); - cc->count = 0; -} - -/* see bearssl.h */ -void -br_sha1_update(br_sha1_context *cc, const void *data, size_t len) -{ - const unsigned char *buf; - size_t ptr; - - buf = data; - ptr = (size_t)cc->count & 63; - while (len > 0) { - size_t clen; - - clen = 64 - ptr; - if (clen > len) { - clen = len; - } - memcpy(cc->buf + ptr, buf, clen); - ptr += clen; - buf += clen; - len -= clen; - cc->count += (uint64_t)clen; - if (ptr == 64) { - br_sha1_round(cc->buf, cc->val); - ptr = 0; - } - } -} - -/* see bearssl.h */ -void -br_sha1_out(const br_sha1_context *cc, void *dst) -{ - unsigned char buf[64]; - uint32_t val[5]; - size_t ptr; - - ptr = (size_t)cc->count & 63; - memcpy(buf, cc->buf, ptr); - memcpy(val, cc->val, sizeof val); - buf[ptr ++] = 0x80; - if (ptr > 56) { - memset(buf + ptr, 0, 64 - ptr); - br_sha1_round(buf, val); - memset(buf, 0, 56); - } else { - memset(buf + ptr, 0, 56 - ptr); - } - br_enc64be(buf + 56, cc->count << 3); - br_sha1_round(buf, val); - br_range_enc32be(dst, val, 5); -} - -/* see bearssl.h */ -uint64_t -br_sha1_state(const br_sha1_context *cc, void *dst) -{ - br_range_enc32be(dst, cc->val, 5); - return cc->count; -} - -/* see bearssl.h */ -void -br_sha1_set_state(br_sha1_context *cc, const void *stb, uint64_t count) -{ - br_range_dec32be(cc->val, 5, stb); - cc->count = count; -} - -/* see bearssl.h */ -const br_hash_class br_sha1_vtable = { - sizeof(br_sha1_context), - BR_HASHDESC_ID(br_sha1_ID) - | BR_HASHDESC_OUT(20) - | BR_HASHDESC_STATE(20) - | BR_HASHDESC_LBLEN(6) - | BR_HASHDESC_MD_PADDING - | BR_HASHDESC_MD_PADDING_BE, - (void (*)(const br_hash_class **))&br_sha1_init, - (void (*)(const br_hash_class **, const void *, size_t))&br_sha1_update, - (void (*)(const br_hash_class *const *, void *))&br_sha1_out, - (uint64_t (*)(const br_hash_class *const *, void *))&br_sha1_state, - (void (*)(const br_hash_class **, const void *, uint64_t)) - &br_sha1_set_state -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/sha2big.c b/src/tls/bearssl/sha2big.c deleted file mode 100644 index 6ce516081..000000000 --- a/src/tls/bearssl/sha2big.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -#define CH(X, Y, Z) ((((Y) ^ (Z)) & (X)) ^ (Z)) -#define MAJ(X, Y, Z) (((Y) & (Z)) | (((Y) | (Z)) & (X))) - -#define ROTR(x, n) (((uint64_t)(x) << (64 - (n))) | ((uint64_t)(x) >> (n))) - -#define BSG5_0(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39)) -#define BSG5_1(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41)) -#define SSG5_0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ (uint64_t)((x) >> 7)) -#define SSG5_1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ (uint64_t)((x) >> 6)) - -static const uint64_t IV384[8] = { - 0xCBBB9D5DC1059ED8, 0x629A292A367CD507, - 0x9159015A3070DD17, 0x152FECD8F70E5939, - 0x67332667FFC00B31, 0x8EB44A8768581511, - 0xDB0C2E0D64F98FA7, 0x47B5481DBEFA4FA4 -}; - -static const uint64_t IV512[8] = { - 0x6A09E667F3BCC908, 0xBB67AE8584CAA73B, - 0x3C6EF372FE94F82B, 0xA54FF53A5F1D36F1, - 0x510E527FADE682D1, 0x9B05688C2B3E6C1F, - 0x1F83D9ABFB41BD6B, 0x5BE0CD19137E2179 -}; - -static const uint64_t K[80] = { - 0x428A2F98D728AE22, 0x7137449123EF65CD, - 0xB5C0FBCFEC4D3B2F, 0xE9B5DBA58189DBBC, - 0x3956C25BF348B538, 0x59F111F1B605D019, - 0x923F82A4AF194F9B, 0xAB1C5ED5DA6D8118, - 0xD807AA98A3030242, 0x12835B0145706FBE, - 0x243185BE4EE4B28C, 0x550C7DC3D5FFB4E2, - 0x72BE5D74F27B896F, 0x80DEB1FE3B1696B1, - 0x9BDC06A725C71235, 0xC19BF174CF692694, - 0xE49B69C19EF14AD2, 0xEFBE4786384F25E3, - 0x0FC19DC68B8CD5B5, 0x240CA1CC77AC9C65, - 0x2DE92C6F592B0275, 0x4A7484AA6EA6E483, - 0x5CB0A9DCBD41FBD4, 0x76F988DA831153B5, - 0x983E5152EE66DFAB, 0xA831C66D2DB43210, - 0xB00327C898FB213F, 0xBF597FC7BEEF0EE4, - 0xC6E00BF33DA88FC2, 0xD5A79147930AA725, - 0x06CA6351E003826F, 0x142929670A0E6E70, - 0x27B70A8546D22FFC, 0x2E1B21385C26C926, - 0x4D2C6DFC5AC42AED, 0x53380D139D95B3DF, - 0x650A73548BAF63DE, 0x766A0ABB3C77B2A8, - 0x81C2C92E47EDAEE6, 0x92722C851482353B, - 0xA2BFE8A14CF10364, 0xA81A664BBC423001, - 0xC24B8B70D0F89791, 0xC76C51A30654BE30, - 0xD192E819D6EF5218, 0xD69906245565A910, - 0xF40E35855771202A, 0x106AA07032BBD1B8, - 0x19A4C116B8D2D0C8, 0x1E376C085141AB53, - 0x2748774CDF8EEB99, 0x34B0BCB5E19B48A8, - 0x391C0CB3C5C95A63, 0x4ED8AA4AE3418ACB, - 0x5B9CCA4F7763E373, 0x682E6FF3D6B2B8A3, - 0x748F82EE5DEFB2FC, 0x78A5636F43172F60, - 0x84C87814A1F0AB72, 0x8CC702081A6439EC, - 0x90BEFFFA23631E28, 0xA4506CEBDE82BDE9, - 0xBEF9A3F7B2C67915, 0xC67178F2E372532B, - 0xCA273ECEEA26619C, 0xD186B8C721C0C207, - 0xEADA7DD6CDE0EB1E, 0xF57D4F7FEE6ED178, - 0x06F067AA72176FBA, 0x0A637DC5A2C898A6, - 0x113F9804BEF90DAE, 0x1B710B35131C471B, - 0x28DB77F523047D84, 0x32CAAB7B40C72493, - 0x3C9EBE0A15C9BEBC, 0x431D67C49C100D4C, - 0x4CC5D4BECB3E42B6, 0x597F299CFC657E2A, - 0x5FCB6FAB3AD6FAEC, 0x6C44198C4A475817 -}; - -static void -sha2big_round(const unsigned char *buf, uint64_t *val) -{ - -#define SHA2BIG_STEP(A, B, C, D, E, F, G, H, j) do { \ - uint64_t T1, T2; \ - T1 = H + BSG5_1(E) + CH(E, F, G) + K[j] + w[j]; \ - T2 = BSG5_0(A) + MAJ(A, B, C); \ - D += T1; \ - H = T1 + T2; \ - } while (0) - - int i; - uint64_t a, b, c, d, e, f, g, h; - uint64_t w[80]; - - br_range_dec64be(w, 16, buf); - for (i = 16; i < 80; i ++) { - w[i] = SSG5_1(w[i - 2]) + w[i - 7] - + SSG5_0(w[i - 15]) + w[i - 16]; - } - a = val[0]; - b = val[1]; - c = val[2]; - d = val[3]; - e = val[4]; - f = val[5]; - g = val[6]; - h = val[7]; - for (i = 0; i < 80; i += 8) { - SHA2BIG_STEP(a, b, c, d, e, f, g, h, i + 0); - SHA2BIG_STEP(h, a, b, c, d, e, f, g, i + 1); - SHA2BIG_STEP(g, h, a, b, c, d, e, f, i + 2); - SHA2BIG_STEP(f, g, h, a, b, c, d, e, i + 3); - SHA2BIG_STEP(e, f, g, h, a, b, c, d, i + 4); - SHA2BIG_STEP(d, e, f, g, h, a, b, c, i + 5); - SHA2BIG_STEP(c, d, e, f, g, h, a, b, i + 6); - SHA2BIG_STEP(b, c, d, e, f, g, h, a, i + 7); - } - val[0] += a; - val[1] += b; - val[2] += c; - val[3] += d; - val[4] += e; - val[5] += f; - val[6] += g; - val[7] += h; -} - -static void -sha2big_update(br_sha384_context *cc, const void *data, size_t len) -{ - const unsigned char *buf; - size_t ptr; - - buf = data; - ptr = (size_t)cc->count & 127; - cc->count += (uint64_t)len; - while (len > 0) { - size_t clen; - - clen = 128 - ptr; - if (clen > len) { - clen = len; - } - memcpy(cc->buf + ptr, buf, clen); - ptr += clen; - buf += clen; - len -= clen; - if (ptr == 128) { - sha2big_round(cc->buf, cc->val); - ptr = 0; - } - } -} - -static void -sha2big_out(const br_sha384_context *cc, void *dst, int num) -{ - unsigned char buf[128]; - uint64_t val[8]; - size_t ptr; - - ptr = (size_t)cc->count & 127; - memcpy(buf, cc->buf, ptr); - memcpy(val, cc->val, sizeof val); - buf[ptr ++] = 0x80; - if (ptr > 112) { - memset(buf + ptr, 0, 128 - ptr); - sha2big_round(buf, val); - memset(buf, 0, 112); - } else { - memset(buf + ptr, 0, 112 - ptr); - } - br_enc64be(buf + 112, cc->count >> 61); - br_enc64be(buf + 120, cc->count << 3); - sha2big_round(buf, val); - br_range_enc64be(dst, val, num); -} - -/* see bearssl.h */ -void -br_sha384_init(br_sha384_context *cc) -{ - cc->vtable = &br_sha384_vtable; - memcpy(cc->val, IV384, sizeof IV384); - cc->count = 0; -} - -/* see bearssl.h */ -void -br_sha384_update(br_sha384_context *cc, const void *data, size_t len) -{ - sha2big_update(cc, data, len); -} - -/* see bearssl.h */ -void -br_sha384_out(const br_sha384_context *cc, void *dst) -{ - sha2big_out(cc, dst, 6); -} - -/* see bearssl.h */ -uint64_t -br_sha384_state(const br_sha384_context *cc, void *dst) -{ - br_range_enc64be(dst, cc->val, 8); - return cc->count; -} - -/* see bearssl.h */ -void -br_sha384_set_state(br_sha384_context *cc, const void *stb, uint64_t count) -{ - br_range_dec64be(cc->val, 8, stb); - cc->count = count; -} - -/* see bearssl.h */ -void -br_sha512_init(br_sha512_context *cc) -{ - cc->vtable = &br_sha512_vtable; - memcpy(cc->val, IV512, sizeof IV512); - cc->count = 0; -} - -/* see bearssl.h */ -void -br_sha512_out(const br_sha512_context *cc, void *dst) -{ - sha2big_out(cc, dst, 8); -} - -/* see bearssl.h */ -const br_hash_class br_sha384_vtable = { - sizeof(br_sha384_context), - BR_HASHDESC_ID(br_sha384_ID) - | BR_HASHDESC_OUT(48) - | BR_HASHDESC_STATE(64) - | BR_HASHDESC_LBLEN(7) - | BR_HASHDESC_MD_PADDING - | BR_HASHDESC_MD_PADDING_BE - | BR_HASHDESC_MD_PADDING_128, - (void (*)(const br_hash_class **))&br_sha384_init, - (void (*)(const br_hash_class **, const void *, size_t)) - &br_sha384_update, - (void (*)(const br_hash_class *const *, void *))&br_sha384_out, - (uint64_t (*)(const br_hash_class *const *, void *))&br_sha384_state, - (void (*)(const br_hash_class **, const void *, uint64_t)) - &br_sha384_set_state -}; - -/* see bearssl.h */ -const br_hash_class br_sha512_vtable = { - sizeof(br_sha512_context), - BR_HASHDESC_ID(br_sha512_ID) - | BR_HASHDESC_OUT(64) - | BR_HASHDESC_STATE(64) - | BR_HASHDESC_LBLEN(7) - | BR_HASHDESC_MD_PADDING - | BR_HASHDESC_MD_PADDING_BE - | BR_HASHDESC_MD_PADDING_128, - (void (*)(const br_hash_class **))&br_sha512_init, - (void (*)(const br_hash_class **, const void *, size_t)) - &br_sha512_update, - (void (*)(const br_hash_class *const *, void *))&br_sha512_out, - (uint64_t (*)(const br_hash_class *const *, void *))&br_sha512_state, - (void (*)(const br_hash_class **, const void *, uint64_t)) - &br_sha512_set_state -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/sha2small.c b/src/tls/bearssl/sha2small.c deleted file mode 100644 index 04cc71f81..000000000 --- a/src/tls/bearssl/sha2small.c +++ /dev/null @@ -1,348 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#if defined(BOARD_HAS_ECCX08) || defined(BOARD_HAS_OFFLOADED_ECCX08) || \ - defined(BOARD_HAS_SE050) || defined(ARDUINO_ARCH_ESP32) || \ - defined(ARDUINO_UNOR4_WIFI) - -#include "inner.h" - -#define CH(X, Y, Z) ((((Y) ^ (Z)) & (X)) ^ (Z)) -#define MAJ(X, Y, Z) (((Y) & (Z)) | (((Y) | (Z)) & (X))) - -#define ROTR(x, n) (((uint32_t)(x) << (32 - (n))) | ((uint32_t)(x) >> (n))) - -#define BSG2_0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) -#define BSG2_1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) -#define SSG2_0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ (uint32_t)((x) >> 3)) -#define SSG2_1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ (uint32_t)((x) >> 10)) - -/* see inner.h */ -const uint32_t br_sha224_IV[8] = { - 0xC1059ED8, 0x367CD507, 0x3070DD17, 0xF70E5939, - 0xFFC00B31, 0x68581511, 0x64F98FA7, 0xBEFA4FA4 -}; - -/* see inner.h */ -const uint32_t br_sha256_IV[8] = { - 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, - 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 -}; - -static const uint32_t K[64] = { - 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, - 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, - 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, - 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, - 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, - 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, - 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, - 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967, - 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, - 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, - 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, - 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, - 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, - 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, - 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, - 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2 -}; - -/* see inner.h */ -void -br_sha2small_round(const unsigned char *buf, uint32_t *val) -{ - -#define SHA2_STEP(A, B, C, D, E, F, G, H, j) do { \ - uint32_t T1, T2; \ - T1 = H + BSG2_1(E) + CH(E, F, G) + K[j] + w[j]; \ - T2 = BSG2_0(A) + MAJ(A, B, C); \ - D += T1; \ - H = T1 + T2; \ - } while (0) - - int i; - uint32_t a, b, c, d, e, f, g, h; - uint32_t w[64]; - - br_range_dec32be(w, 16, buf); - for (i = 16; i < 64; i ++) { - w[i] = SSG2_1(w[i - 2]) + w[i - 7] - + SSG2_0(w[i - 15]) + w[i - 16]; - } - a = val[0]; - b = val[1]; - c = val[2]; - d = val[3]; - e = val[4]; - f = val[5]; - g = val[6]; - h = val[7]; - for (i = 0; i < 64; i += 8) { - SHA2_STEP(a, b, c, d, e, f, g, h, i + 0); - SHA2_STEP(h, a, b, c, d, e, f, g, i + 1); - SHA2_STEP(g, h, a, b, c, d, e, f, i + 2); - SHA2_STEP(f, g, h, a, b, c, d, e, i + 3); - SHA2_STEP(e, f, g, h, a, b, c, d, i + 4); - SHA2_STEP(d, e, f, g, h, a, b, c, i + 5); - SHA2_STEP(c, d, e, f, g, h, a, b, i + 6); - SHA2_STEP(b, c, d, e, f, g, h, a, i + 7); - } - val[0] += a; - val[1] += b; - val[2] += c; - val[3] += d; - val[4] += e; - val[5] += f; - val[6] += g; - val[7] += h; - -#if 0 -/* obsolete */ -#define SHA2_MEXP1(pc) do { \ - W[pc] = br_dec32be(buf + ((pc) << 2)); \ - } while (0) - -#define SHA2_MEXP2(pc) do { \ - W[(pc) & 0x0F] = SSG2_1(W[((pc) - 2) & 0x0F]) \ - + W[((pc) - 7) & 0x0F] \ - + SSG2_0(W[((pc) - 15) & 0x0F]) + W[(pc) & 0x0F]; \ - } while (0) - -#define SHA2_STEPn(n, a, b, c, d, e, f, g, h, pc) do { \ - uint32_t t1, t2; \ - SHA2_MEXP ## n(pc); \ - t1 = h + BSG2_1(e) + CH(e, f, g) \ - + K[pcount + (pc)] + W[(pc) & 0x0F]; \ - t2 = BSG2_0(a) + MAJ(a, b, c); \ - d += t1; \ - h = t1 + t2; \ - } while (0) - -#define SHA2_STEP1(a, b, c, d, e, f, g, h, pc) \ - SHA2_STEPn(1, a, b, c, d, e, f, g, h, pc) -#define SHA2_STEP2(a, b, c, d, e, f, g, h, pc) \ - SHA2_STEPn(2, a, b, c, d, e, f, g, h, pc) - - uint32_t A, B, C, D, E, F, G, H; - uint32_t W[16]; - unsigned pcount; - - A = val[0]; - B = val[1]; - C = val[2]; - D = val[3]; - E = val[4]; - F = val[5]; - G = val[6]; - H = val[7]; - pcount = 0; - SHA2_STEP1(A, B, C, D, E, F, G, H, 0); - SHA2_STEP1(H, A, B, C, D, E, F, G, 1); - SHA2_STEP1(G, H, A, B, C, D, E, F, 2); - SHA2_STEP1(F, G, H, A, B, C, D, E, 3); - SHA2_STEP1(E, F, G, H, A, B, C, D, 4); - SHA2_STEP1(D, E, F, G, H, A, B, C, 5); - SHA2_STEP1(C, D, E, F, G, H, A, B, 6); - SHA2_STEP1(B, C, D, E, F, G, H, A, 7); - SHA2_STEP1(A, B, C, D, E, F, G, H, 8); - SHA2_STEP1(H, A, B, C, D, E, F, G, 9); - SHA2_STEP1(G, H, A, B, C, D, E, F, 10); - SHA2_STEP1(F, G, H, A, B, C, D, E, 11); - SHA2_STEP1(E, F, G, H, A, B, C, D, 12); - SHA2_STEP1(D, E, F, G, H, A, B, C, 13); - SHA2_STEP1(C, D, E, F, G, H, A, B, 14); - SHA2_STEP1(B, C, D, E, F, G, H, A, 15); - for (pcount = 16; pcount < 64; pcount += 16) { - SHA2_STEP2(A, B, C, D, E, F, G, H, 0); - SHA2_STEP2(H, A, B, C, D, E, F, G, 1); - SHA2_STEP2(G, H, A, B, C, D, E, F, 2); - SHA2_STEP2(F, G, H, A, B, C, D, E, 3); - SHA2_STEP2(E, F, G, H, A, B, C, D, 4); - SHA2_STEP2(D, E, F, G, H, A, B, C, 5); - SHA2_STEP2(C, D, E, F, G, H, A, B, 6); - SHA2_STEP2(B, C, D, E, F, G, H, A, 7); - SHA2_STEP2(A, B, C, D, E, F, G, H, 8); - SHA2_STEP2(H, A, B, C, D, E, F, G, 9); - SHA2_STEP2(G, H, A, B, C, D, E, F, 10); - SHA2_STEP2(F, G, H, A, B, C, D, E, 11); - SHA2_STEP2(E, F, G, H, A, B, C, D, 12); - SHA2_STEP2(D, E, F, G, H, A, B, C, 13); - SHA2_STEP2(C, D, E, F, G, H, A, B, 14); - SHA2_STEP2(B, C, D, E, F, G, H, A, 15); - } - val[0] += A; - val[1] += B; - val[2] += C; - val[3] += D; - val[4] += E; - val[5] += F; - val[6] += G; - val[7] += H; -#endif -} - -static void -sha2small_update(br_sha224_context *cc, const void *data, size_t len) -{ - const unsigned char *buf; - size_t ptr; - - buf = data; - ptr = (size_t)cc->count & 63; - cc->count += (uint64_t)len; - while (len > 0) { - size_t clen; - - clen = 64 - ptr; - if (clen > len) { - clen = len; - } - memcpy(cc->buf + ptr, buf, clen); - ptr += clen; - buf += clen; - len -= clen; - if (ptr == 64) { - br_sha2small_round(cc->buf, cc->val); - ptr = 0; - } - } -} - -static void -sha2small_out(const br_sha224_context *cc, void *dst, int num) -{ - unsigned char buf[64]; - uint32_t val[8]; - size_t ptr; - - ptr = (size_t)cc->count & 63; - memcpy(buf, cc->buf, ptr); - memcpy(val, cc->val, sizeof val); - buf[ptr ++] = 0x80; - if (ptr > 56) { - memset(buf + ptr, 0, 64 - ptr); - br_sha2small_round(buf, val); - memset(buf, 0, 56); - } else { - memset(buf + ptr, 0, 56 - ptr); - } - br_enc64be(buf + 56, cc->count << 3); - br_sha2small_round(buf, val); - br_range_enc32be(dst, val, num); -} - -/* see bearssl.h */ -void -br_sha224_init(br_sha224_context *cc) -{ - cc->vtable = &br_sha224_vtable; - memcpy(cc->val, br_sha224_IV, sizeof cc->val); - cc->count = 0; -} - -/* see bearssl.h */ -void -br_sha224_update(br_sha224_context *cc, const void *data, size_t len) -{ - sha2small_update(cc, data, len); -} - -/* see bearssl.h */ -void -br_sha224_out(const br_sha224_context *cc, void *dst) -{ - sha2small_out(cc, dst, 7); -} - -/* see bearssl.h */ -uint64_t -br_sha224_state(const br_sha224_context *cc, void *dst) -{ - br_range_enc32be(dst, cc->val, 8); - return cc->count; -} - -/* see bearssl.h */ -void -br_sha224_set_state(br_sha224_context *cc, const void *stb, uint64_t count) -{ - br_range_dec32be(cc->val, 8, stb); - cc->count = count; -} - -/* see bearssl.h */ -void -br_sha256_init(br_sha256_context *cc) -{ - cc->vtable = &br_sha256_vtable; - memcpy(cc->val, br_sha256_IV, sizeof cc->val); - cc->count = 0; -} - -/* see bearssl.h */ -void -br_sha256_out(const br_sha256_context *cc, void *dst) -{ - sha2small_out(cc, dst, 8); -} - -/* see bearssl.h */ -const br_hash_class br_sha224_vtable = { - sizeof(br_sha224_context), - BR_HASHDESC_ID(br_sha224_ID) - | BR_HASHDESC_OUT(28) - | BR_HASHDESC_STATE(32) - | BR_HASHDESC_LBLEN(6) - | BR_HASHDESC_MD_PADDING - | BR_HASHDESC_MD_PADDING_BE, - (void (*)(const br_hash_class **))&br_sha224_init, - (void (*)(const br_hash_class **, - const void *, size_t))&br_sha224_update, - (void (*)(const br_hash_class *const *, void *))&br_sha224_out, - (uint64_t (*)(const br_hash_class *const *, void *))&br_sha224_state, - (void (*)(const br_hash_class **, const void *, uint64_t)) - &br_sha224_set_state -}; - -/* see bearssl.h */ -const br_hash_class br_sha256_vtable = { - sizeof(br_sha256_context), - BR_HASHDESC_ID(br_sha256_ID) - | BR_HASHDESC_OUT(32) - | BR_HASHDESC_STATE(32) - | BR_HASHDESC_LBLEN(6) - | BR_HASHDESC_MD_PADDING - | BR_HASHDESC_MD_PADDING_BE, - (void (*)(const br_hash_class **))&br_sha256_init, - (void (*)(const br_hash_class **, - const void *, size_t))&br_sha256_update, - (void (*)(const br_hash_class *const *, void *))&br_sha256_out, - (uint64_t (*)(const br_hash_class *const *, void *))&br_sha256_state, - (void (*)(const br_hash_class **, const void *, uint64_t)) - &br_sha256_set_state -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/skey_decoder.c b/src/tls/bearssl/skey_decoder.c deleted file mode 100644 index 2b7d03a58..000000000 --- a/src/tls/bearssl/skey_decoder.c +++ /dev/null @@ -1,655 +0,0 @@ -/* Automatically generated code; do not modify directly. */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include -#include - -typedef struct { - uint32_t *dp; - uint32_t *rp; - const unsigned char *ip; -} t0_context; - -static uint32_t -t0_parse7E_unsigned(const unsigned char **p) -{ - uint32_t x; - - x = 0; - for (;;) { - unsigned y; - - y = *(*p) ++; - x = (x << 7) | (uint32_t)(y & 0x7F); - if (y < 0x80) { - return x; - } - } -} - -static int32_t -t0_parse7E_signed(const unsigned char **p) -{ - int neg; - uint32_t x; - - neg = ((**p) >> 6) & 1; - x = (uint32_t)-neg; - for (;;) { - unsigned y; - - y = *(*p) ++; - x = (x << 7) | (uint32_t)(y & 0x7F); - if (y < 0x80) { - if (neg) { - return -(int32_t)~x - 1; - } else { - return (int32_t)x; - } - } - } -} - -#define T0_VBYTE(x, n) (unsigned char)((((uint32_t)(x) >> (n)) & 0x7F) | 0x80) -#define T0_FBYTE(x, n) (unsigned char)(((uint32_t)(x) >> (n)) & 0x7F) -#define T0_SBYTE(x) (unsigned char)((((uint32_t)(x) >> 28) + 0xF8) ^ 0xF8) -#define T0_INT1(x) T0_FBYTE(x, 0) -#define T0_INT2(x) T0_VBYTE(x, 7), T0_FBYTE(x, 0) -#define T0_INT3(x) T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) -#define T0_INT4(x) T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) -#define T0_INT5(x) T0_SBYTE(x), T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) - -/* static const unsigned char t0_datablock[]; */ - - -void br_skey_decoder_init_main(void *t0ctx); - -void br_skey_decoder_run(void *t0ctx); - - - -#include "inner.h" - - - - - -#include "inner.h" - -#define CTX ((br_skey_decoder_context *)(void *)((unsigned char *)t0ctx - offsetof(br_skey_decoder_context, cpu))) -#define CONTEXT_NAME br_skey_decoder_context - -/* see bearssl_x509.h */ -void -br_skey_decoder_init(br_skey_decoder_context *ctx) -{ - memset(ctx, 0, sizeof *ctx); - ctx->cpu.dp = &ctx->dp_stack[0]; - ctx->cpu.rp = &ctx->rp_stack[0]; - br_skey_decoder_init_main(&ctx->cpu); - br_skey_decoder_run(&ctx->cpu); -} - -/* see bearssl_x509.h */ -void -br_skey_decoder_push(br_skey_decoder_context *ctx, - const void *data, size_t len) -{ - ctx->hbuf = data; - ctx->hlen = len; - br_skey_decoder_run(&ctx->cpu); -} - - - -static const unsigned char t0_datablock[] = { - 0x00, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x07, - 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x08, 0x2A, 0x86, 0x48, 0xCE, - 0x3D, 0x03, 0x01, 0x07, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22, 0x05, 0x2B, - 0x81, 0x04, 0x00, 0x23 -}; - -static const unsigned char t0_codeblock[] = { - 0x00, 0x01, 0x01, 0x07, 0x00, 0x00, 0x01, 0x01, 0x08, 0x00, 0x00, 0x13, - 0x13, 0x00, 0x00, 0x01, T0_INT1(BR_ERR_X509_BAD_TAG_CLASS), 0x00, 0x00, - 0x01, T0_INT1(BR_ERR_X509_BAD_TAG_VALUE), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_EXTRA_ELEMENT), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_INDEFINITE_LENGTH), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_INNER_TRUNC), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_INVALID_VALUE), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_LIMIT_EXCEEDED), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_NOT_CONSTRUCTED), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_NOT_PRIMITIVE), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_OVERFLOW), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_UNEXPECTED), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_UNSUPPORTED), 0x00, 0x00, 0x01, - T0_INT1(BR_KEYTYPE_EC), 0x00, 0x00, 0x01, T0_INT1(BR_KEYTYPE_RSA), - 0x00, 0x00, 0x01, T0_INT2(offsetof(CONTEXT_NAME, key_data)), 0x00, - 0x00, 0x01, T0_INT2(offsetof(CONTEXT_NAME, key_type)), 0x00, 0x00, - 0x33, 0x48, 0x00, 0x00, 0x01, T0_INT2(offsetof(CONTEXT_NAME, pad)), - 0x00, 0x00, 0x01, 0x13, 0x00, 0x00, 0x01, 0x1C, 0x00, 0x00, 0x01, 0x22, - 0x00, 0x00, 0x05, 0x02, 0x2C, 0x16, 0x00, 0x00, 0x06, 0x02, 0x2D, 0x16, - 0x00, 0x00, 0x01, 0x10, 0x3D, 0x00, 0x00, 0x0D, 0x05, 0x02, 0x2F, 0x16, - 0x3A, 0x00, 0x00, 0x0D, 0x05, 0x02, 0x2F, 0x16, 0x3B, 0x00, 0x00, 0x06, - 0x02, 0x27, 0x16, 0x00, 0x01, 0x03, 0x00, 0x54, 0x57, 0x01, 0x02, 0x3E, - 0x55, 0x23, 0x06, 0x02, 0x30, 0x16, 0x57, 0x01, 0x04, 0x3E, 0x02, 0x00, - 0x41, 0x3F, 0x00, 0x02, 0x03, 0x00, 0x53, 0x14, 0x14, 0x03, 0x01, 0x48, - 0x0E, 0x06, 0x02, 0x30, 0x16, 0x33, 0x4C, 0x58, 0x01, 0x7F, 0x19, 0x0D, - 0x06, 0x04, 0x13, 0x13, 0x04, 0x29, 0x01, 0x20, 0x19, 0x0D, 0x06, 0x16, - 0x13, 0x3A, 0x53, 0x4D, 0x02, 0x00, 0x06, 0x09, 0x02, 0x00, 0x0C, 0x06, - 0x02, 0x2A, 0x16, 0x04, 0x02, 0x03, 0x00, 0x3F, 0x04, 0x0D, 0x01, 0x21, - 0x19, 0x0D, 0x06, 0x04, 0x13, 0x3A, 0x04, 0x03, 0x30, 0x16, 0x13, 0x5D, - 0x02, 0x00, 0x05, 0x02, 0x30, 0x16, 0x02, 0x00, 0x02, 0x01, 0x1D, 0x00, - 0x02, 0x53, 0x4B, 0x05, 0x02, 0x30, 0x16, 0x5B, 0x15, 0x06, 0x07, 0x5D, - 0x01, 0x7F, 0x03, 0x01, 0x04, 0x16, 0x46, 0x15, 0x06, 0x10, 0x01, 0x00, - 0x03, 0x01, 0x14, 0x06, 0x03, 0x4D, 0x04, 0x02, 0x01, 0x00, 0x03, 0x00, - 0x04, 0x02, 0x30, 0x16, 0x3F, 0x57, 0x01, 0x04, 0x3E, 0x53, 0x02, 0x01, - 0x06, 0x03, 0x43, 0x04, 0x03, 0x02, 0x00, 0x40, 0x3F, 0x5D, 0x02, 0x01, - 0x06, 0x03, 0x32, 0x04, 0x01, 0x31, 0x00, 0x00, 0x54, 0x57, 0x01, 0x02, - 0x3E, 0x55, 0x06, 0x02, 0x30, 0x16, 0x57, 0x01, 0x02, 0x3E, 0x44, 0x3F, - 0x00, 0x07, 0x35, 0x50, 0x14, 0x05, 0x02, 0x2F, 0x16, 0x23, 0x01, 0x03, - 0x0B, 0x33, 0x17, 0x47, 0x07, 0x03, 0x00, 0x4F, 0x4F, 0x35, 0x4E, 0x14, - 0x14, 0x03, 0x01, 0x03, 0x02, 0x51, 0x14, 0x03, 0x03, 0x02, 0x02, 0x07, - 0x14, 0x03, 0x02, 0x51, 0x14, 0x03, 0x04, 0x02, 0x02, 0x07, 0x14, 0x03, - 0x02, 0x51, 0x14, 0x03, 0x05, 0x02, 0x02, 0x07, 0x14, 0x03, 0x02, 0x51, - 0x03, 0x06, 0x02, 0x00, 0x02, 0x01, 0x02, 0x03, 0x02, 0x04, 0x02, 0x05, - 0x02, 0x06, 0x1E, 0x00, 0x00, 0x19, 0x19, 0x00, 0x00, 0x01, 0x0B, 0x00, - 0x00, 0x01, 0x00, 0x20, 0x14, 0x06, 0x08, 0x01, 0x01, 0x21, 0x20, 0x22, - 0x20, 0x04, 0x75, 0x13, 0x00, 0x00, 0x01, - T0_INT2(3 * BR_X509_BUFSIZE_KEY), 0x00, 0x01, 0x01, 0x87, 0xFF, 0xFF, - 0x7F, 0x54, 0x57, 0x01, 0x02, 0x3E, 0x55, 0x01, 0x01, 0x0E, 0x06, 0x02, - 0x30, 0x16, 0x57, 0x01, 0x02, 0x19, 0x0D, 0x06, 0x06, 0x13, 0x3B, 0x44, - 0x32, 0x04, 0x1C, 0x01, 0x04, 0x19, 0x0D, 0x06, 0x08, 0x13, 0x3B, 0x01, - 0x00, 0x41, 0x31, 0x04, 0x0E, 0x01, 0x10, 0x19, 0x0D, 0x06, 0x05, 0x13, - 0x3A, 0x42, 0x04, 0x03, 0x30, 0x16, 0x13, 0x03, 0x00, 0x3F, 0x02, 0x00, - 0x34, 0x1F, 0x5A, 0x27, 0x16, 0x00, 0x01, 0x45, 0x0A, 0x06, 0x02, 0x29, - 0x16, 0x14, 0x03, 0x00, 0x08, 0x02, 0x00, 0x00, 0x00, 0x57, 0x01, 0x06, - 0x3E, 0x56, 0x00, 0x00, 0x20, 0x14, 0x06, 0x07, 0x1A, 0x14, 0x06, 0x01, - 0x12, 0x04, 0x76, 0x24, 0x00, 0x00, 0x4B, 0x05, 0x02, 0x30, 0x16, 0x37, - 0x15, 0x06, 0x04, 0x01, 0x17, 0x04, 0x12, 0x38, 0x15, 0x06, 0x04, 0x01, - 0x18, 0x04, 0x0A, 0x39, 0x15, 0x06, 0x04, 0x01, 0x19, 0x04, 0x02, 0x30, - 0x16, 0x00, 0x00, 0x1C, 0x57, 0x01, 0x02, 0x3E, 0x09, 0x50, 0x00, 0x00, - 0x35, 0x4E, 0x13, 0x00, 0x03, 0x14, 0x03, 0x00, 0x03, 0x01, 0x03, 0x02, - 0x53, 0x59, 0x14, 0x01, 0x81, 0x00, 0x0F, 0x06, 0x02, 0x2E, 0x16, 0x14, - 0x01, 0x00, 0x0D, 0x06, 0x0B, 0x13, 0x14, 0x05, 0x04, 0x13, 0x01, 0x00, - 0x00, 0x59, 0x04, 0x6F, 0x02, 0x01, 0x14, 0x05, 0x02, 0x2B, 0x16, 0x23, - 0x03, 0x01, 0x02, 0x02, 0x1F, 0x02, 0x02, 0x22, 0x03, 0x02, 0x14, 0x06, - 0x03, 0x59, 0x04, 0x68, 0x13, 0x02, 0x00, 0x02, 0x01, 0x08, 0x00, 0x00, - 0x14, 0x35, 0x1C, 0x08, 0x20, 0x1C, 0x07, 0x20, 0x4E, 0x00, 0x01, 0x59, - 0x14, 0x01, 0x81, 0x00, 0x0A, 0x06, 0x01, 0x00, 0x01, 0x81, 0x00, 0x08, - 0x14, 0x05, 0x02, 0x28, 0x16, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, - 0x00, 0x0E, 0x06, 0x19, 0x02, 0x00, 0x23, 0x03, 0x00, 0x14, 0x01, 0x83, - 0xFF, 0xFF, 0x7F, 0x0E, 0x06, 0x02, 0x29, 0x16, 0x01, 0x08, 0x0B, 0x20, - 0x59, 0x1C, 0x07, 0x04, 0x60, 0x00, 0x00, 0x52, 0x4A, 0x00, 0x00, 0x57, - 0x3C, 0x53, 0x00, 0x01, 0x53, 0x14, 0x05, 0x02, 0x2E, 0x16, 0x59, 0x14, - 0x01, 0x81, 0x00, 0x0F, 0x06, 0x02, 0x2E, 0x16, 0x03, 0x00, 0x14, 0x06, - 0x16, 0x59, 0x02, 0x00, 0x14, 0x01, 0x87, 0xFF, 0xFF, 0x7F, 0x0F, 0x06, - 0x02, 0x2E, 0x16, 0x01, 0x08, 0x0B, 0x07, 0x03, 0x00, 0x04, 0x67, 0x13, - 0x02, 0x00, 0x00, 0x00, 0x53, 0x14, 0x01, 0x81, 0x7F, 0x0E, 0x06, 0x08, - 0x5C, 0x01, 0x00, 0x36, 0x1F, 0x01, 0x00, 0x00, 0x14, 0x36, 0x1F, 0x36, - 0x22, 0x4C, 0x01, 0x7F, 0x00, 0x01, 0x59, 0x03, 0x00, 0x02, 0x00, 0x01, - 0x05, 0x10, 0x01, 0x01, 0x11, 0x18, 0x02, 0x00, 0x01, 0x06, 0x10, 0x14, - 0x01, 0x01, 0x11, 0x06, 0x02, 0x25, 0x16, 0x01, 0x04, 0x0B, 0x02, 0x00, - 0x01, 0x1F, 0x11, 0x14, 0x01, 0x1F, 0x0D, 0x06, 0x02, 0x26, 0x16, 0x07, - 0x00, 0x00, 0x14, 0x05, 0x05, 0x01, 0x00, 0x01, 0x7F, 0x00, 0x57, 0x00, - 0x00, 0x14, 0x05, 0x02, 0x29, 0x16, 0x23, 0x5A, 0x00, 0x00, 0x1B, 0x14, - 0x01, 0x00, 0x0F, 0x06, 0x01, 0x00, 0x13, 0x12, 0x04, 0x74, 0x00, 0x01, - 0x01, 0x00, 0x00, 0x5D, 0x13, 0x00, 0x00, 0x14, 0x06, 0x07, 0x5E, 0x14, - 0x06, 0x01, 0x12, 0x04, 0x76, 0x00, 0x00, 0x01, 0x00, 0x19, 0x1A, 0x09, - 0x24, 0x00 -}; - -static const uint16_t t0_caddr[] = { - 0, - 5, - 10, - 14, - 18, - 22, - 26, - 30, - 34, - 38, - 42, - 46, - 50, - 54, - 58, - 62, - 66, - 70, - 75, - 80, - 84, - 89, - 93, - 97, - 101, - 107, - 113, - 118, - 126, - 134, - 140, - 163, - 244, - 311, - 329, - 404, - 408, - 412, - 429, - 434, - 505, - 519, - 526, - 540, - 573, - 582, - 587, - 654, - 665, - 721, - 725, - 730, - 778, - 804, - 848, - 859, - 868, - 881, - 885, - 889, - 901 -}; - -#define T0_INTERPRETED 34 - -#define T0_ENTER(ip, rp, slot) do { \ - const unsigned char *t0_newip; \ - uint32_t t0_lnum; \ - t0_newip = &t0_codeblock[t0_caddr[(slot) - T0_INTERPRETED]]; \ - t0_lnum = t0_parse7E_unsigned(&t0_newip); \ - (rp) += t0_lnum; \ - *((rp) ++) = (uint32_t)((ip) - &t0_codeblock[0]) + (t0_lnum << 16); \ - (ip) = t0_newip; \ - } while (0) - -#define T0_DEFENTRY(name, slot) \ -void \ -name(void *ctx) \ -{ \ - t0_context *t0ctx = ctx; \ - t0ctx->ip = &t0_codeblock[0]; \ - T0_ENTER(t0ctx->ip, t0ctx->rp, slot); \ -} - -T0_DEFENTRY(br_skey_decoder_init_main, 73) - -#define T0_NEXT(t0ipp) (*(*(t0ipp)) ++) - -void -br_skey_decoder_run(void *t0ctx) -{ - uint32_t *dp, *rp; - const unsigned char *ip; - -#define T0_LOCAL(x) (*(rp - 2 - (x))) -#define T0_POP() (*-- dp) -#define T0_POPi() (*(int32_t *)(-- dp)) -#define T0_PEEK(x) (*(dp - 1 - (x))) -#define T0_PEEKi(x) (*(int32_t *)(dp - 1 - (x))) -#define T0_PUSH(v) do { *dp = (v); dp ++; } while (0) -#define T0_PUSHi(v) do { *(int32_t *)dp = (v); dp ++; } while (0) -#define T0_RPOP() (*-- rp) -#define T0_RPOPi() (*(int32_t *)(-- rp)) -#define T0_RPUSH(v) do { *rp = (v); rp ++; } while (0) -#define T0_RPUSHi(v) do { *(int32_t *)rp = (v); rp ++; } while (0) -#define T0_ROLL(x) do { \ - size_t t0len = (size_t)(x); \ - uint32_t t0tmp = *(dp - 1 - t0len); \ - memmove(dp - t0len - 1, dp - t0len, t0len * sizeof *dp); \ - *(dp - 1) = t0tmp; \ -} while (0) -#define T0_SWAP() do { \ - uint32_t t0tmp = *(dp - 2); \ - *(dp - 2) = *(dp - 1); \ - *(dp - 1) = t0tmp; \ -} while (0) -#define T0_ROT() do { \ - uint32_t t0tmp = *(dp - 3); \ - *(dp - 3) = *(dp - 2); \ - *(dp - 2) = *(dp - 1); \ - *(dp - 1) = t0tmp; \ -} while (0) -#define T0_NROT() do { \ - uint32_t t0tmp = *(dp - 1); \ - *(dp - 1) = *(dp - 2); \ - *(dp - 2) = *(dp - 3); \ - *(dp - 3) = t0tmp; \ -} while (0) -#define T0_PICK(x) do { \ - uint32_t t0depth = (x); \ - T0_PUSH(T0_PEEK(t0depth)); \ -} while (0) -#define T0_CO() do { \ - goto t0_exit; \ -} while (0) -#define T0_RET() goto t0_next - - dp = ((t0_context *)t0ctx)->dp; - rp = ((t0_context *)t0ctx)->rp; - ip = ((t0_context *)t0ctx)->ip; - goto t0_next; - for (;;) { - uint32_t t0x; - - t0_next: - t0x = T0_NEXT(&ip); - if (t0x < T0_INTERPRETED) { - switch (t0x) { - int32_t t0off; - - case 0: /* ret */ - t0x = T0_RPOP(); - rp -= (t0x >> 16); - t0x &= 0xFFFF; - if (t0x == 0) { - ip = NULL; - goto t0_exit; - } - ip = &t0_codeblock[t0x]; - break; - case 1: /* literal constant */ - T0_PUSHi(t0_parse7E_signed(&ip)); - break; - case 2: /* read local */ - T0_PUSH(T0_LOCAL(t0_parse7E_unsigned(&ip))); - break; - case 3: /* write local */ - T0_LOCAL(t0_parse7E_unsigned(&ip)) = T0_POP(); - break; - case 4: /* jump */ - t0off = t0_parse7E_signed(&ip); - ip += t0off; - break; - case 5: /* jump if */ - t0off = t0_parse7E_signed(&ip); - if (T0_POP()) { - ip += t0off; - } - break; - case 6: /* jump if not */ - t0off = t0_parse7E_signed(&ip); - if (!T0_POP()) { - ip += t0off; - } - break; - case 7: { - /* + */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(a + b); - - } - break; - case 8: { - /* - */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(a - b); - - } - break; - case 9: { - /* -rot */ - T0_NROT(); - } - break; - case 10: { - /* < */ - - int32_t b = T0_POPi(); - int32_t a = T0_POPi(); - T0_PUSH(-(uint32_t)(a < b)); - - } - break; - case 11: { - /* << */ - - int c = (int)T0_POPi(); - uint32_t x = T0_POP(); - T0_PUSH(x << c); - - } - break; - case 12: { - /* <> */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(-(uint32_t)(a != b)); - - } - break; - case 13: { - /* = */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(-(uint32_t)(a == b)); - - } - break; - case 14: { - /* > */ - - int32_t b = T0_POPi(); - int32_t a = T0_POPi(); - T0_PUSH(-(uint32_t)(a > b)); - - } - break; - case 15: { - /* >= */ - - int32_t b = T0_POPi(); - int32_t a = T0_POPi(); - T0_PUSH(-(uint32_t)(a >= b)); - - } - break; - case 16: { - /* >> */ - - int c = (int)T0_POPi(); - int32_t x = T0_POPi(); - T0_PUSHi(x >> c); - - } - break; - case 17: { - /* and */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(a & b); - - } - break; - case 18: { - /* co */ - T0_CO(); - } - break; - case 19: { - /* drop */ - (void)T0_POP(); - } - break; - case 20: { - /* dup */ - T0_PUSH(T0_PEEK(0)); - } - break; - case 21: { - /* eqOID */ - - const unsigned char *a2 = &t0_datablock[T0_POP()]; - const unsigned char *a1 = &CTX->pad[0]; - size_t len = a1[0]; - int x; - if (len == a2[0]) { - x = -(memcmp(a1 + 1, a2 + 1, len) == 0); - } else { - x = 0; - } - T0_PUSH((uint32_t)x); - - } - break; - case 22: { - /* fail */ - - CTX->err = T0_POPi(); - T0_CO(); - - } - break; - case 23: { - /* get8 */ - - uint32_t addr = T0_POP(); - T0_PUSH(*((unsigned char *)CTX + addr)); - - } - break; - case 24: { - /* neg */ - - uint32_t a = T0_POP(); - T0_PUSH(-a); - - } - break; - case 25: { - /* over */ - T0_PUSH(T0_PEEK(1)); - } - break; - case 26: { - /* read-blob-inner */ - - uint32_t len = T0_POP(); - uint32_t addr = T0_POP(); - size_t clen = CTX->hlen; - if (clen > len) { - clen = (size_t)len; - } - if (addr != 0) { - memcpy((unsigned char *)CTX + addr, CTX->hbuf, clen); - } - CTX->hbuf += clen; - CTX->hlen -= clen; - T0_PUSH(addr + clen); - T0_PUSH(len - clen); - - } - break; - case 27: { - /* read8-low */ - - if (CTX->hlen == 0) { - T0_PUSHi(-1); - } else { - CTX->hlen --; - T0_PUSH(*CTX->hbuf ++); - } - - } - break; - case 28: { - /* rot */ - T0_ROT(); - } - break; - case 29: { - /* set-ec-key */ - - size_t xlen = T0_POP(); - uint32_t curve = T0_POP(); - CTX->key.ec.curve = curve; - CTX->key.ec.x = CTX->key_data; - CTX->key.ec.xlen = xlen; - - } - break; - case 30: { - /* set-rsa-key */ - - size_t iqlen = T0_POP(); - size_t dqlen = T0_POP(); - size_t dplen = T0_POP(); - size_t qlen = T0_POP(); - size_t plen = T0_POP(); - uint32_t n_bitlen = T0_POP(); - size_t off; - - CTX->key.rsa.n_bitlen = n_bitlen; - CTX->key.rsa.p = CTX->key_data; - CTX->key.rsa.plen = plen; - off = plen; - CTX->key.rsa.q = CTX->key_data + off; - CTX->key.rsa.qlen = qlen; - off += qlen; - CTX->key.rsa.dp = CTX->key_data + off; - CTX->key.rsa.dplen = dplen; - off += dplen; - CTX->key.rsa.dq = CTX->key_data + off; - CTX->key.rsa.dqlen = dqlen; - off += dqlen; - CTX->key.rsa.iq = CTX->key_data + off; - CTX->key.rsa.iqlen = iqlen; - - } - break; - case 31: { - /* set8 */ - - uint32_t addr = T0_POP(); - *((unsigned char *)CTX + addr) = (unsigned char)T0_POP(); - - } - break; - case 32: { - /* swap */ - T0_SWAP(); - } - break; - case 33: { - /* u>> */ - - int c = (int)T0_POPi(); - uint32_t x = T0_POP(); - T0_PUSH(x >> c); - - } - break; - } - - } else { - T0_ENTER(ip, rp, t0x); - } - } -t0_exit: - ((t0_context *)t0ctx)->dp = dp; - ((t0_context *)t0ctx)->rp = rp; - ((t0_context *)t0ctx)->ip = ip; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ssl_ccert_single_ec.c b/src/tls/bearssl/ssl_ccert_single_ec.c deleted file mode 100644 index d18d165e6..000000000 --- a/src/tls/bearssl/ssl_ccert_single_ec.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -static void -cc_none0(const br_ssl_client_certificate_class **pctx) -{ - (void)pctx; -} - -static void -cc_none1(const br_ssl_client_certificate_class **pctx, size_t len) -{ - (void)pctx; - (void)len; -} - -static void -cc_none2(const br_ssl_client_certificate_class **pctx, - const unsigned char *data, size_t len) -{ - (void)pctx; - (void)data; - (void)len; -} - -static void -cc_choose(const br_ssl_client_certificate_class **pctx, - const br_ssl_client_context *cc, uint32_t auth_types, - br_ssl_client_certificate *choices) -{ - br_ssl_client_certificate_ec_context *zc; - int x; - int scurve; - - zc = (br_ssl_client_certificate_ec_context *)pctx; - scurve = br_ssl_client_get_server_curve(cc); - - if ((zc->allowed_usages & BR_KEYTYPE_KEYX) != 0 - && scurve == zc->sk->curve) - { - int x; - - x = (zc->issuer_key_type == BR_KEYTYPE_RSA) ? 16 : 17; - if (((auth_types >> x) & 1) != 0) { - choices->auth_type = BR_AUTH_ECDH; - choices->hash_id = -1; - choices->chain = zc->chain; - choices->chain_len = zc->chain_len; - } - } - - /* - * For ECDSA authentication, we must choose an appropriate - * hash function. - */ - x = br_ssl_choose_hash((unsigned)(auth_types >> 8)); - if (x == 0 || (zc->allowed_usages & BR_KEYTYPE_SIGN) == 0) { - memset(choices, 0, sizeof *choices); - return; - } - choices->auth_type = BR_AUTH_ECDSA; - choices->hash_id = x; - choices->chain = zc->chain; - choices->chain_len = zc->chain_len; -} - -static uint32_t -cc_do_keyx(const br_ssl_client_certificate_class **pctx, - unsigned char *data, size_t *len) -{ - br_ssl_client_certificate_ec_context *zc; - uint32_t r; - size_t xoff, xlen; - - zc = (br_ssl_client_certificate_ec_context *)pctx; - r = zc->iec->mul(data, *len, zc->sk->x, zc->sk->xlen, zc->sk->curve); - xoff = zc->iec->xoff(zc->sk->curve, &xlen); - memmove(data, data + xoff, xlen); - *len = xlen; - return r; -} - -static size_t -cc_do_sign(const br_ssl_client_certificate_class **pctx, - int hash_id, size_t hv_len, unsigned char *data, size_t len) -{ - br_ssl_client_certificate_ec_context *zc; - unsigned char hv[64]; - const br_hash_class *hc; - - zc = (br_ssl_client_certificate_ec_context *)pctx; - memcpy(hv, data, hv_len); - hc = br_multihash_getimpl(zc->mhash, hash_id); - if (hc == NULL) { - return 0; - } - if (len < 139) { - return 0; - } - return zc->iecdsa(zc->iec, hc, hv, zc->sk, data); -} - -static const br_ssl_client_certificate_class ccert_vtable = { - sizeof(br_ssl_client_certificate_ec_context), - cc_none0, /* start_name_list */ - cc_none1, /* start_name */ - cc_none2, /* append_name */ - cc_none0, /* end_name */ - cc_none0, /* end_name_list */ - cc_choose, - cc_do_keyx, - cc_do_sign -}; - -/* see bearssl_ssl.h */ -void -br_ssl_client_set_single_ec(br_ssl_client_context *cc, - const br_x509_certificate *chain, size_t chain_len, - const br_ec_private_key *sk, unsigned allowed_usages, - unsigned cert_issuer_key_type, - const br_ec_impl *iec, br_ecdsa_sign iecdsa) -{ - cc->client_auth.single_ec.vtable = &ccert_vtable; - cc->client_auth.single_ec.chain = chain; - cc->client_auth.single_ec.chain_len = chain_len; - cc->client_auth.single_ec.sk = sk; - cc->client_auth.single_ec.allowed_usages = allowed_usages; - cc->client_auth.single_ec.issuer_key_type = cert_issuer_key_type; - cc->client_auth.single_ec.mhash = &cc->eng.mhash; - cc->client_auth.single_ec.iec = iec; - cc->client_auth.single_ec.iecdsa = iecdsa; - cc->client_auth_vtable = &cc->client_auth.single_ec.vtable; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ssl_ccert_single_rsa.c b/src/tls/bearssl/ssl_ccert_single_rsa.c deleted file mode 100644 index 713095f2a..000000000 --- a/src/tls/bearssl/ssl_ccert_single_rsa.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -static void -cc_none0(const br_ssl_client_certificate_class **pctx) -{ - (void)pctx; -} - -static void -cc_none1(const br_ssl_client_certificate_class **pctx, size_t len) -{ - (void)pctx; - (void)len; -} - -static void -cc_none2(const br_ssl_client_certificate_class **pctx, - const unsigned char *data, size_t len) -{ - (void)pctx; - (void)data; - (void)len; -} - -static void -cc_choose(const br_ssl_client_certificate_class **pctx, - const br_ssl_client_context *cc, uint32_t auth_types, - br_ssl_client_certificate *choices) -{ - br_ssl_client_certificate_rsa_context *zc; - int x; - - (void)cc; - zc = (br_ssl_client_certificate_rsa_context *)pctx; - x = br_ssl_choose_hash((unsigned)auth_types); - if (x == 0 && (auth_types & 1) == 0) { - memset(choices, 0, sizeof *choices); - } - choices->auth_type = BR_AUTH_RSA; - choices->hash_id = x; - choices->chain = zc->chain; - choices->chain_len = zc->chain_len; -} - -/* - * OID for hash functions in RSA signatures. - */ -static const unsigned char HASH_OID_SHA1[] = { - 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A -}; - -static const unsigned char HASH_OID_SHA224[] = { - 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04 -}; - -static const unsigned char HASH_OID_SHA256[] = { - 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01 -}; - -static const unsigned char HASH_OID_SHA384[] = { - 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02 -}; - -static const unsigned char HASH_OID_SHA512[] = { - 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03 -}; - -static const unsigned char *HASH_OID[] = { - HASH_OID_SHA1, - HASH_OID_SHA224, - HASH_OID_SHA256, - HASH_OID_SHA384, - HASH_OID_SHA512 -}; - -static size_t -cc_do_sign(const br_ssl_client_certificate_class **pctx, - int hash_id, size_t hv_len, unsigned char *data, size_t len) -{ - br_ssl_client_certificate_rsa_context *zc; - unsigned char hv[64]; - const unsigned char *hash_oid; - size_t sig_len; - - zc = (br_ssl_client_certificate_rsa_context *)pctx; - memcpy(hv, data, hv_len); - if (hash_id == 0) { - hash_oid = NULL; - } else if (hash_id >= 2 && hash_id <= 6) { - hash_oid = HASH_OID[hash_id - 2]; - } else { - return 0; - } - sig_len = (zc->sk->n_bitlen + 7) >> 3; - if (len < sig_len) { - return 0; - } - return zc->irsasign(hash_oid, hv, hv_len, zc->sk, data) ? sig_len : 0; -} - -static const br_ssl_client_certificate_class ccert_vtable = { - sizeof(br_ssl_client_certificate_rsa_context), - cc_none0, /* start_name_list */ - cc_none1, /* start_name */ - cc_none2, /* append_name */ - cc_none0, /* end_name */ - cc_none0, /* end_name_list */ - cc_choose, - 0, - cc_do_sign -}; - -/* see bearssl_ssl.h */ -void -br_ssl_client_set_single_rsa(br_ssl_client_context *cc, - const br_x509_certificate *chain, size_t chain_len, - const br_rsa_private_key *sk, br_rsa_pkcs1_sign irsasign) -{ - cc->client_auth.single_rsa.vtable = &ccert_vtable; - cc->client_auth.single_rsa.chain = chain; - cc->client_auth.single_rsa.chain_len = chain_len; - cc->client_auth.single_rsa.sk = sk; - cc->client_auth.single_rsa.irsasign = irsasign; - cc->client_auth_vtable = &cc->client_auth.single_rsa.vtable; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ssl_client.c b/src/tls/bearssl/ssl_client.c deleted file mode 100644 index ccb9f6e08..000000000 --- a/src/tls/bearssl/ssl_client.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_ssl.h */ -void -br_ssl_client_zero(br_ssl_client_context *cc) -{ - /* - * For really standard C, we should explicitly set to NULL all - * pointers, and 0 all other fields. However, on all our target - * architectures, a direct memset() will work, be faster, and - * use a lot less code. - */ - memset(cc, 0, sizeof *cc); -} - -/* see bearssl_ssl.h */ -int -br_ssl_client_reset(br_ssl_client_context *cc, - const char *server_name, int resume_session) -{ - size_t n; - - br_ssl_engine_set_buffer(&cc->eng, NULL, 0, 0); - cc->eng.version_out = cc->eng.version_min; - if (!resume_session) { - br_ssl_client_forget_session(cc); - } - if (!br_ssl_engine_init_rand(&cc->eng)) { - return 0; - } - - /* - * We always set back the "reneg" flag to 0 because we use it - * to distinguish between first handshake and renegotiation. - * Note that "renegotiation" and "session resumption" are two - * different things. - */ - cc->eng.reneg = 0; - - if (server_name == NULL) { - cc->eng.server_name[0] = 0; - } else { - n = strlen(server_name) + 1; - if (n > sizeof cc->eng.server_name) { - br_ssl_engine_fail(&cc->eng, BR_ERR_BAD_PARAM); - return 0; - } - memcpy(cc->eng.server_name, server_name, n); - } - - br_ssl_engine_hs_reset(&cc->eng, - br_ssl_hs_client_init_main, br_ssl_hs_client_run); - return br_ssl_engine_last_error(&cc->eng) == BR_ERR_OK; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ssl_client_default_rsapub.c b/src/tls/bearssl/ssl_client_default_rsapub.c deleted file mode 100644 index f87a61595..000000000 --- a/src/tls/bearssl/ssl_client_default_rsapub.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_ssl.h */ -void -br_ssl_client_set_default_rsapub(br_ssl_client_context *cc) -{ - br_ssl_client_set_rsapub(cc, br_rsa_public_get_default()); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ssl_client_full.c b/src/tls/bearssl/ssl_client_full.c deleted file mode 100644 index e64ad08b6..000000000 --- a/src/tls/bearssl/ssl_client_full.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_ssl.h */ -void -br_ssl_client_init_full(br_ssl_client_context *cc, - br_x509_minimal_context *xc, - const br_x509_trust_anchor *trust_anchors, size_t trust_anchors_num) -{ - /* - * The "full" profile supports all implemented cipher suites. - * - * Rationale for suite order, from most important to least - * important rule: - * - * -- Don't use 3DES if AES or ChaCha20 is available. - * -- Try to have Forward Secrecy (ECDHE suite) if possible. - * -- When not using Forward Secrecy, ECDH key exchange is - * better than RSA key exchange (slightly more expensive on the - * client, but much cheaper on the server, and it implies smaller - * messages). - * -- ChaCha20+Poly1305 is better than AES/GCM (faster, smaller code). - * -- GCM is better than CCM and CBC. CCM is better than CBC. - * -- CCM is preferable over CCM_8 (with CCM_8, forgeries may succeed - * with probability 2^(-64)). - * -- AES-128 is preferred over AES-256 (AES-128 is already - * strong enough, and AES-256 is 40% more expensive). - */ - static const uint16_t suites[] = { - BR_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, - BR_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, - BR_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, - BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - BR_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, - BR_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, - BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, - BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, - BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, - BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, - BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, - BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, - BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, - BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, - BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, - BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, - BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, - BR_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, - BR_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, - BR_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, - BR_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, - BR_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, - BR_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, - BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, - BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, - BR_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, - BR_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, - BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, - BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, - BR_TLS_RSA_WITH_AES_128_GCM_SHA256, - BR_TLS_RSA_WITH_AES_256_GCM_SHA384, - BR_TLS_RSA_WITH_AES_128_CCM, - BR_TLS_RSA_WITH_AES_256_CCM, - BR_TLS_RSA_WITH_AES_128_CCM_8, - BR_TLS_RSA_WITH_AES_256_CCM_8, - BR_TLS_RSA_WITH_AES_128_CBC_SHA256, - BR_TLS_RSA_WITH_AES_256_CBC_SHA256, - BR_TLS_RSA_WITH_AES_128_CBC_SHA, - BR_TLS_RSA_WITH_AES_256_CBC_SHA, - BR_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, - BR_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, - BR_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, - BR_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, - BR_TLS_RSA_WITH_3DES_EDE_CBC_SHA - }; - - /* - * All hash functions are activated. - * Note: the X.509 validation engine will nonetheless refuse to - * validate signatures that use MD5 as hash function. - */ - static const br_hash_class *hashes[] = { - &br_md5_vtable, - &br_sha1_vtable, - &br_sha224_vtable, - &br_sha256_vtable, - &br_sha384_vtable, - &br_sha512_vtable - }; - - int id; - - /* - * Reset client context and set supported versions from TLS-1.0 - * to TLS-1.2 (inclusive). - */ - br_ssl_client_zero(cc); - br_ssl_engine_set_versions(&cc->eng, BR_TLS10, BR_TLS12); - - /* - * X.509 engine uses SHA-256 to hash certificate DN (for - * comparisons). - */ - br_x509_minimal_init(xc, &br_sha256_vtable, - trust_anchors, trust_anchors_num); - - /* - * Set suites and asymmetric crypto implementations. We use the - * "i31" code for RSA (it is somewhat faster than the "i32" - * implementation). - * TODO: change that when better implementations are made available. - */ - br_ssl_engine_set_suites(&cc->eng, suites, - (sizeof suites) / (sizeof suites[0])); - br_ssl_client_set_default_rsapub(cc); - br_ssl_engine_set_default_rsavrfy(&cc->eng); - br_ssl_engine_set_default_ecdsa(&cc->eng); - br_x509_minimal_set_rsa(xc, br_ssl_engine_get_rsavrfy(&cc->eng)); - br_x509_minimal_set_ecdsa(xc, - br_ssl_engine_get_ec(&cc->eng), - br_ssl_engine_get_ecdsa(&cc->eng)); - - /* - * Set supported hash functions, for the SSL engine and for the - * X.509 engine. - */ - for (id = br_md5_ID; id <= br_sha512_ID; id ++) { - const br_hash_class *hc; - - hc = hashes[id - 1]; - br_ssl_engine_set_hash(&cc->eng, id, hc); - br_x509_minimal_set_hash(xc, id, hc); - } - - /* - * Link the X.509 engine in the SSL engine. - */ - br_ssl_engine_set_x509(&cc->eng, &xc->vtable); - - /* - * Set the PRF implementations. - */ - br_ssl_engine_set_prf10(&cc->eng, &br_tls10_prf); - br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf); - br_ssl_engine_set_prf_sha384(&cc->eng, &br_tls12_sha384_prf); - - /* - * Symmetric encryption. We use the "default" implementations - * (fastest among constant-time implementations). - */ - br_ssl_engine_set_default_aes_cbc(&cc->eng); - br_ssl_engine_set_default_aes_ccm(&cc->eng); - br_ssl_engine_set_default_aes_gcm(&cc->eng); - br_ssl_engine_set_default_des_cbc(&cc->eng); - br_ssl_engine_set_default_chapol(&cc->eng); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ssl_engine.c b/src/tls/bearssl/ssl_engine.c deleted file mode 100644 index d36ba9ddf..000000000 --- a/src/tls/bearssl/ssl_engine.c +++ /dev/null @@ -1,1574 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -#if 0 -/* obsolete */ - -/* - * If BR_USE_URANDOM is not defined, then try to autodetect its presence - * through compiler macros. - */ -#ifndef BR_USE_URANDOM - -/* - * Macro values documented on: - * https://sourceforge.net/p/predef/wiki/OperatingSystems/ - * - * Only the most common systems have been included here for now. This - * should be enriched later on. - */ -#if defined _AIX \ - || defined __ANDROID__ \ - || defined __FreeBSD__ \ - || defined __NetBSD__ \ - || defined __OpenBSD__ \ - || defined __DragonFly__ \ - || defined __linux__ \ - || (defined __sun && (defined __SVR4 || defined __svr4__)) \ - || (defined __APPLE__ && defined __MACH__) -#define BR_USE_URANDOM 1 -#endif - -#endif - -/* - * If BR_USE_WIN32_RAND is not defined, perform autodetection here. - */ -#ifndef BR_USE_WIN32_RAND - -#if defined _WIN32 || defined _WIN64 -#define BR_USE_WIN32_RAND 1 -#endif - -#endif - -#if BR_USE_URANDOM -#include -#include -#include -#include -#endif - -#if BR_USE_WIN32_RAND -#include -#include -#pragma comment(lib, "advapi32") -#endif - -#endif - -/* ==================================================================== */ -/* - * This part of the file does the low-level record management. - */ - -/* - * IMPLEMENTATION NOTES - * ==================== - * - * In this file, we designate by "input" (and the "i" letter) the "recv" - * operations: incoming records from the peer, from which payload data - * is obtained, and must be extracted by the application (or the SSL - * handshake engine). Similarly, "output" (and the "o" letter) is for - * "send": payload data injected by the application (and SSL handshake - * engine), to be wrapped into records, that are then conveyed to the - * peer over the transport medium. - * - * The input and output buffers may be distinct or shared. When - * shared, input and output cannot occur concurrently; the caller - * must make sure that it never needs to output data while input - * data has been received. In practice, a shared buffer prevents - * pipelining of HTTP requests, or similar protocols; however, a - * shared buffer saves RAM. - * - * The input buffer is pointed to by 'ibuf' and has size 'ibuf_len'; - * the output buffer is pointed to by 'obuf' and has size 'obuf_len'. - * From the size of these buffers is derived the maximum fragment - * length, which will be honoured upon sending records; regardless of - * that length, incoming records will be processed as long as they - * fit in the input buffer, and their length still complies with the - * protocol specification (maximum plaintext payload length is 16384 - * bytes). - * - * Three registers are used to manage buffering in ibuf, called ixa, - * ixb and ixc. Similarly, three registers are used to manage buffering - * in obuf, called oxa, oxb and oxc. - * - * - * At any time, the engine is in one of the following modes: - * -- Failed mode: an error occurs, no I/O can happen. - * -- Input mode: the engine can either receive record bytes from the - * transport layer, or it has some buffered payload bytes to yield. - * -- Output mode: the engine can either receive payload bytes, or it - * has some record bytes to send to the transport layer. - * -- Input/Output mode: both input and output modes are active. When - * the buffer is shared, this can happen only when the buffer is empty - * (no buffered payload bytes or record bytes in either direction). - * - * - * Failed mode: - * ------------ - * - * I/O failed for some reason (invalid received data, not enough room - * for the next record...). No I/O may ever occur again for this context, - * until an explicit reset is performed. This mode, and the error code, - * are also used for protocol errors, especially handshake errors. - * - * - * Input mode: - * ----------- - * - * ixa index within ibuf[] for the currently read data - * ixb maximum index within ibuf[] for the currently read data - * ixc number of bytes not yet received for the current record - * - * -- When ixa == ixb, there is no available data for readers. When - * ixa != ixb, there is available data and it starts at offset ixa. - * - * -- When waiting for the next record header, ixa and ixb are equal - * and contain a value ranging from 0 to 4; ixc is equal to 5-ixa. - * - * -- When the header has been received, record data is obtained. The - * ixc field records how many bytes are still needed to reach the - * end of the current record. - * - * ** If encryption is active, then ixa and ixb are kept equal, and - * point to the end of the currently received record bytes. When - * ixc reaches 0, decryption/MAC is applied, and ixa and ixb are - * adjusted. - * - * ** If encryption is not active, then ixa and ixb are distinct - * and data can be read right away. Additional record data is - * obtained only when ixa == ixb. - * - * Note: in input mode and no encryption, records larger than the buffer - * size are allowed. When encryption is active, the complete record must - * fit within the buffer, since it cannot be decrypted/MACed until it - * has been completely received. - * - * -- When receiving the next record header, 'version_in' contains the - * expected input version (0 if not expecting a specific version); on - * mismatch, the mode switches to 'failed'. - * - * -- When the header has been received, 'version_in' contains the received - * version. It is up to the caller to check and adjust the 'version_in' field - * to implement the required semantics. - * - * -- The 'record_type_in' field is updated with the incoming record type - * when the next record header has been received. - * - * - * Output mode: - * ------------ - * - * oxa index within obuf[] for the currently accumulated data - * oxb maximum index within obuf[] for record data - * oxc pointer for start of record data, and for record sending - * - * -- When oxa != oxb, more data can be accumulated into the current - * record; when oxa == oxb, a closed record is being sent. - * - * -- When accumulating data, oxc points to the start of the data. - * - * -- During record sending, oxa (and oxb) point to the next record byte - * to send, and oxc indicates the end of the current record. - * - * Note: sent records must fit within the buffer, since the header is - * adjusted only when the complete record has been assembled. - * - * -- The 'version_out' and 'record_type_out' fields are used to build the - * record header when the mode is switched to 'sending'. - * - * - * Modes: - * ------ - * - * The state register iomode contains one of the following values: - * - * BR_IO_FAILED I/O failed - * BR_IO_IN input mode - * BR_IO_OUT output mode - * BR_IO_INOUT input/output mode - * - * Whether encryption is active on incoming records is indicated by the - * incrypt flag. For outgoing records, there is no such flag; "encryption" - * is always considered active, but initially uses functions that do not - * encrypt anything. The 'incrypt' flag is needed because when there is - * no active encryption, records larger than the I/O buffer are accepted. - * - * Note: we do not support no-encryption modes (MAC only). - * - * TODO: implement GCM support - * - * - * Misc: - * ----- - * - * 'max_frag_len' is the maximum plaintext size for an outgoing record. - * By default, it is set to the maximum value that fits in the provided - * buffers, in the following list: 512, 1024, 2048, 4096, 16384. The - * caller may change it if needed, but the new value MUST still fit in - * the buffers, and it MUST be one of the list above for compatibility - * with the Maximum Fragment Length extension. - * - * For incoming records, only the total buffer length and current - * encryption mode impact the maximum length for incoming records. The - * 'max_frag_len' value is still adjusted so that records up to that - * length can be both received and sent. - * - * - * Offsets and lengths: - * -------------------- - * - * When sending fragments with TLS-1.1+, the maximum overhead is: - * 5 bytes for the record header - * 16 bytes for the explicit IV - * 48 bytes for the MAC (HMAC/SHA-384) - * 16 bytes for the padding (AES) - * so a total of 85 extra bytes. Note that we support block cipher sizes - * up to 16 bytes (AES) and HMAC output sizes up to 48 bytes (SHA-384). - * - * With TLS-1.0 and CBC mode, we apply a 1/n-1 split, for a maximum - * overhead of: - * 5 bytes for the first record header - * 32 bytes for the first record payload (AES-CBC + HMAC/SHA-1) - * 5 bytes for the second record header - * 20 bytes for the MAC (HMAC/SHA-1) - * 16 bytes for the padding (AES) - * -1 byte to account for the payload byte in the first record - * so a total of 77 extra bytes at most, less than the 85 bytes above. - * Note that with TLS-1.0, the MAC is HMAC with either MD5 or SHA-1, but - * no other hash function. - * - * The implementation does not try to send larger records when the current - * encryption mode has less overhead. - * - * Maximum input record overhead is: - * 5 bytes for the record header - * 16 bytes for the explicit IV (TLS-1.1+) - * 48 bytes for the MAC (HMAC/SHA-384) - * 256 bytes for the padding - * so a total of 325 extra bytes. - * - * When receiving the next record header, it is written into the buffer - * bytes 0 to 4 (inclusive). Record data is always written into buf[] - * starting at offset 5. When encryption is active, the plaintext data - * may start at a larger offset (e.g. because of an explicit IV). - */ - -#define MAX_OUT_OVERHEAD 85 -#define MAX_IN_OVERHEAD 325 - -/* see inner.h */ -void -br_ssl_engine_fail(br_ssl_engine_context *rc, int err) -{ - if (rc->iomode != BR_IO_FAILED) { - rc->iomode = BR_IO_FAILED; - rc->err = err; - } -} - -/* - * Adjust registers for a new incoming record. - */ -static void -make_ready_in(br_ssl_engine_context *rc) -{ - rc->ixa = rc->ixb = 0; - rc->ixc = 5; - if (rc->iomode == BR_IO_IN) { - rc->iomode = BR_IO_INOUT; - } -} - -/* - * Adjust registers for a new outgoing record. - */ -static void -make_ready_out(br_ssl_engine_context *rc) -{ - size_t a, b; - - a = 5; - b = rc->obuf_len - a; - rc->out.vtable->max_plaintext(&rc->out.vtable, &a, &b); - if ((b - a) > rc->max_frag_len) { - b = a + rc->max_frag_len; - } - rc->oxa = a; - rc->oxb = b; - rc->oxc = a; - if (rc->iomode == BR_IO_OUT) { - rc->iomode = BR_IO_INOUT; - } -} - -/* see inner.h */ -void -br_ssl_engine_new_max_frag_len(br_ssl_engine_context *rc, unsigned max_frag_len) -{ - size_t nxb; - - rc->max_frag_len = max_frag_len; - nxb = rc->oxc + max_frag_len; - if (rc->oxa < rc->oxb && rc->oxb > nxb && rc->oxa < nxb) { - rc->oxb = nxb; - } -} - -/* see bearssl_ssl.h */ -void -br_ssl_engine_set_buffer(br_ssl_engine_context *rc, - void *buf, size_t buf_len, int bidi) -{ - if (buf == NULL) { - br_ssl_engine_set_buffers_bidi(rc, NULL, 0, NULL, 0); - } else { - /* - * In bidirectional mode, we want to maximise input - * buffer size, since we support arbitrary fragmentation - * when sending, but the peer will not necessarily - * comply to any low fragment length (in particular if - * we are the server, because the maximum fragment - * length extension is under client control). - * - * We keep a minimum size of 512 bytes for the plaintext - * of our outgoing records. - * - * br_ssl_engine_set_buffers_bidi() will compute the maximum - * fragment length for outgoing records by using the minimum - * of allocated spaces for both input and output records, - * rounded down to a standard length. - */ - if (bidi) { - size_t w; - - if (buf_len < (512 + MAX_IN_OVERHEAD - + 512 + MAX_OUT_OVERHEAD)) - { - rc->iomode = BR_IO_FAILED; - rc->err = BR_ERR_BAD_PARAM; - return; - } else if (buf_len < (16384 + MAX_IN_OVERHEAD - + 512 + MAX_OUT_OVERHEAD)) - { - w = 512 + MAX_OUT_OVERHEAD; - } else { - w = buf_len - (16384 + MAX_IN_OVERHEAD); - } - br_ssl_engine_set_buffers_bidi(rc, - buf, buf_len - w, - (unsigned char *)buf + w, w); - } else { - br_ssl_engine_set_buffers_bidi(rc, - buf, buf_len, NULL, 0); - } - } -} - -/* see bearssl_ssl.h */ -void -br_ssl_engine_set_buffers_bidi(br_ssl_engine_context *rc, - void *ibuf, size_t ibuf_len, void *obuf, size_t obuf_len) -{ - rc->iomode = BR_IO_INOUT; - rc->incrypt = 0; - rc->err = BR_ERR_OK; - rc->version_in = 0; - rc->record_type_in = 0; - rc->version_out = 0; - rc->record_type_out = 0; - if (ibuf == NULL) { - if (rc->ibuf == NULL) { - br_ssl_engine_fail(rc, BR_ERR_BAD_PARAM); - } - } else { - unsigned u; - - rc->ibuf = ibuf; - rc->ibuf_len = ibuf_len; - if (obuf == NULL) { - obuf = ibuf; - obuf_len = ibuf_len; - } - rc->obuf = obuf; - rc->obuf_len = obuf_len; - - /* - * Compute the maximum fragment length, that fits for - * both incoming and outgoing records. This length will - * be used in fragment length negotiation, so we must - * honour it both ways. Regardless, larger incoming - * records will be accepted, as long as they fit in the - * actual buffer size. - */ - for (u = 14; u >= 9; u --) { - size_t flen; - - flen = (size_t)1 << u; - if (obuf_len >= flen + MAX_OUT_OVERHEAD - && ibuf_len >= flen + MAX_IN_OVERHEAD) - { - break; - } - } - if (u == 8) { - br_ssl_engine_fail(rc, BR_ERR_BAD_PARAM); - return; - } else if (u == 13) { - u = 12; - } - rc->max_frag_len = (size_t)1 << u; - rc->log_max_frag_len = u; - rc->peer_log_max_frag_len = 0; - } - rc->out.vtable = &br_sslrec_out_clear_vtable; - make_ready_in(rc); - make_ready_out(rc); -} - -/* - * Clear buffers in both directions. - */ -static void -engine_clearbuf(br_ssl_engine_context *rc) -{ - make_ready_in(rc); - make_ready_out(rc); -} - -/* - * Make sure the internal PRNG is initialised (but not necessarily - * seeded properly yet). - */ -static int -rng_init(br_ssl_engine_context *cc) -{ - const br_hash_class *h; - - if (cc->rng_init_done != 0) { - return 1; - } - - /* - * If using TLS-1.2, then SHA-256 or SHA-384 must be present (or - * both); we prefer SHA-256 which is faster for 32-bit systems. - * - * If using TLS-1.0 or 1.1 then SHA-1 must be present. - * - * Though HMAC_DRBG/SHA-1 is, as far as we know, as safe as - * these things can be, we still prefer the SHA-2 functions over - * SHA-1, if only for public relations (known theoretical - * weaknesses of SHA-1 with regards to collisions are mostly - * irrelevant here, but they still make people nervous). - */ - h = br_multihash_getimpl(&cc->mhash, br_sha256_ID); - if (!h) { - h = br_multihash_getimpl(&cc->mhash, br_sha384_ID); - if (!h) { - h = br_multihash_getimpl(&cc->mhash, - br_sha1_ID); - if (!h) { - br_ssl_engine_fail(cc, BR_ERR_BAD_STATE); - return 0; - } - } - } - br_hmac_drbg_init(&cc->rng, h, NULL, 0); - cc->rng_init_done = 1; - return 1; -} - -/* see inner.h */ -int -br_ssl_engine_init_rand(br_ssl_engine_context *cc) -{ - if (!rng_init(cc)) { - return 0; - } - - /* - * We always try OS/hardware seeding once. If it works, then - * we assume proper seeding. If not, then external entropy must - * have been injected; otherwise, we report an error. - */ - if (!cc->rng_os_rand_done) { - br_prng_seeder sd; - - sd = br_prng_seeder_system(NULL); - if (sd != 0 && sd(&cc->rng.vtable)) { - cc->rng_init_done = 2; - } - cc->rng_os_rand_done = 1; - } - if (cc->rng_init_done < 2) { - br_ssl_engine_fail(cc, BR_ERR_NO_RANDOM); - return 0; - } - return 1; -} - -/* see bearssl_ssl.h */ -void -br_ssl_engine_inject_entropy(br_ssl_engine_context *cc, - const void *data, size_t len) -{ - /* - * Externally provided entropy is assumed to be "good enough" - * (we cannot really test its quality) so if the RNG structure - * could be initialised at all, then we marked the RNG as - * "properly seeded". - */ - if (!rng_init(cc)) { - return; - } - br_hmac_drbg_update(&cc->rng, data, len); - cc->rng_init_done = 2; -} - -/* - * We define a few internal functions that implement the low-level engine - * API for I/O; the external API (br_ssl_engine_sendapp_buf() and similar - * functions) is built upon these function, with special processing for - * records which are not of type "application data". - * - * recvrec_buf, recvrec_ack receives bytes from transport medium - * sendrec_buf, sendrec_ack send bytes to transport medium - * recvpld_buf, recvpld_ack receives payload data from engine - * sendpld_buf, sendpld_ack send payload data to engine - */ - -static unsigned char * -recvrec_buf(const br_ssl_engine_context *rc, size_t *len) -{ - if (rc->shutdown_recv) { - *len = 0; - return NULL; - } - - /* - * Bytes from the transport can be injected only if the mode is - * compatible (in or in/out), and ixa == ixb; ixc then contains - * the number of bytes that are still expected (but it may - * exceed our buffer size). - * - * We cannot get "stuck" here (buffer is full, but still more - * data is expected) because oversized records are detected when - * their header is processed. - */ - switch (rc->iomode) { - case BR_IO_IN: - case BR_IO_INOUT: - if (rc->ixa == rc->ixb) { - size_t z; - - z = rc->ixc; - if (z > rc->ibuf_len - rc->ixa) { - z = rc->ibuf_len - rc->ixa; - } - *len = z; - return rc->ibuf + rc->ixa; - } - break; - } - *len = 0; - return NULL; -} - -static void -recvrec_ack(br_ssl_engine_context *rc, size_t len) -{ - unsigned char *pbuf; - size_t pbuf_len; - - /* - * Adjust state if necessary (for a shared input/output buffer): - * we got some incoming bytes, so we cannot (temporarily) handle - * outgoing data. - */ - if (rc->iomode == BR_IO_INOUT && rc->ibuf == rc->obuf) { - rc->iomode = BR_IO_IN; - } - - /* - * Adjust data pointers. - */ - rc->ixb = (rc->ixa += len); - rc->ixc -= len; - - /* - * If we are receiving a header and did not fully obtained it - * yet, then just wait for the next bytes. - */ - if (rc->ixa < 5) { - return; - } - - /* - * If we just obtained a full header, process it. - */ - if (rc->ixa == 5) { - unsigned version; - unsigned rlen; - - /* - * Get record type and version. We support only versions - * 3.x (if the version major number does not match, then - * we suppose that the record format is too alien for us - * to process it). - * - * Note: right now, we reject clients that try to send - * a ClientHello in a format compatible with SSL-2.0. It - * is unclear whether this will ever be supported; and - * if we want to support it, then this might be done in - * in the server-specific code, not here. - */ - rc->record_type_in = rc->ibuf[0]; - version = br_dec16be(rc->ibuf + 1); - if ((version >> 8) != 3) { - br_ssl_engine_fail(rc, BR_ERR_UNSUPPORTED_VERSION); - return; - } - - /* - * We ensure that successive records have the same - * version. The handshake code must check and adjust the - * variables when necessary to accommodate the protocol - * negotiation details. - */ - if (rc->version_in != 0 && rc->version_in != version) { - br_ssl_engine_fail(rc, BR_ERR_BAD_VERSION); - return; - } - rc->version_in = version; - - /* - * Decode record length. We must check that the length - * is valid (relatively to the current encryption mode) - * and also (if encryption is active) that the record - * will fit in our buffer. - * - * When no encryption is active, we can process records - * by chunks, and thus accept any record up to the - * maximum allowed plaintext length (16384 bytes). - */ - rlen = br_dec16be(rc->ibuf + 3); - if (rc->incrypt) { - if (!rc->in.vtable->check_length( - &rc->in.vtable, rlen)) - { - br_ssl_engine_fail(rc, BR_ERR_BAD_LENGTH); - return; - } - if (rlen > (rc->ibuf_len - 5)) { - br_ssl_engine_fail(rc, BR_ERR_TOO_LARGE); - return; - } - } else { - if (rlen > 16384) { - br_ssl_engine_fail(rc, BR_ERR_BAD_LENGTH); - return; - } - } - - /* - * If the record is completely empty then we must switch - * to a new record. Note that, in that case, we - * completely ignore the record type, which is fitting - * since we received no actual data of that type. - * - * A completely empty record is technically allowed as - * long as encryption/MAC is not active, i.e. before - * completion of the first handshake. It it still weird; - * it might conceptually be useful as a heartbeat or - * keep-alive mechanism while some lengthy operation is - * going on, e.g. interaction with a human user. - */ - if (rlen == 0) { - make_ready_in(rc); - } else { - rc->ixa = rc->ixb = 5; - rc->ixc = rlen; - } - return; - } - - /* - * If there is no active encryption, then the data can be read - * right away. Note that we do not receive bytes from the - * transport medium when we still have payload bytes to be - * acknowledged. - */ - if (!rc->incrypt) { - rc->ixa = 5; - return; - } - - /* - * Since encryption is active, we must wait for a full record - * before processing it. - */ - if (rc->ixc != 0) { - return; - } - - /* - * We got the full record. Decrypt it. - */ - pbuf_len = rc->ixa - 5; - pbuf = rc->in.vtable->decrypt(&rc->in.vtable, - rc->record_type_in, rc->version_in, rc->ibuf + 5, &pbuf_len); - if (pbuf == 0) { - br_ssl_engine_fail(rc, BR_ERR_BAD_MAC); - return; - } - rc->ixa = (size_t)(pbuf - rc->ibuf); - rc->ixb = rc->ixa + pbuf_len; - - /* - * Decryption may have yielded an empty record, in which case - * we get back to "ready" state immediately. - */ - if (rc->ixa == rc->ixb) { - make_ready_in(rc); - } -} - -/* see inner.h */ -int -br_ssl_engine_recvrec_finished(const br_ssl_engine_context *rc) -{ - switch (rc->iomode) { - case BR_IO_IN: - case BR_IO_INOUT: - return rc->ixc == 0 || rc->ixa < 5; - default: - return 1; - } -} - -static unsigned char * -recvpld_buf(const br_ssl_engine_context *rc, size_t *len) -{ - /* - * There is payload data to be read only if the mode is - * compatible, and ixa != ixb. - */ - switch (rc->iomode) { - case BR_IO_IN: - case BR_IO_INOUT: - *len = rc->ixb - rc->ixa; - return (*len == 0) ? NULL : (rc->ibuf + rc->ixa); - default: - *len = 0; - return NULL; - } -} - -static void -recvpld_ack(br_ssl_engine_context *rc, size_t len) -{ - rc->ixa += len; - - /* - * If we read all the available data, then we either expect - * the remainder of the current record (if the current record - * was not finished; this may happen when encryption is not - * active), or go to "ready" state. - */ - if (rc->ixa == rc->ixb) { - if (rc->ixc == 0) { - make_ready_in(rc); - } else { - rc->ixa = rc->ixb = 5; - } - } -} - -static unsigned char * -sendpld_buf(const br_ssl_engine_context *rc, size_t *len) -{ - /* - * Payload data can be injected only if the current mode is - * compatible, and oxa != oxb. - */ - switch (rc->iomode) { - case BR_IO_OUT: - case BR_IO_INOUT: - *len = rc->oxb - rc->oxa; - return (*len == 0) ? NULL : (rc->obuf + rc->oxa); - default: - *len = 0; - return NULL; - } -} - -/* - * If some payload bytes have been accumulated, then wrap them into - * an outgoing record. Otherwise, this function does nothing, unless - * 'force' is non-zero, in which case an empty record is assembled. - * - * The caller must take care not to invoke this function if the engine - * is not currently ready to receive payload bytes to send. - */ -static void -sendpld_flush(br_ssl_engine_context *rc, int force) -{ - size_t xlen; - unsigned char *buf; - - if (rc->oxa == rc->oxb) { - return; - } - xlen = rc->oxa - rc->oxc; - if (xlen == 0 && !force) { - return; - } - buf = rc->out.vtable->encrypt(&rc->out.vtable, - rc->record_type_out, rc->version_out, - rc->obuf + rc->oxc, &xlen); - rc->oxb = rc->oxa = (size_t)(buf - rc->obuf); - rc->oxc = rc->oxa + xlen; -} - -static void -sendpld_ack(br_ssl_engine_context *rc, size_t len) -{ - /* - * If using a shared buffer, then we may have to modify the - * current mode. - */ - if (rc->iomode == BR_IO_INOUT && rc->ibuf == rc->obuf) { - rc->iomode = BR_IO_OUT; - } - rc->oxa += len; - if (rc->oxa >= rc->oxb) { - /* - * Set oxb to one more than oxa so that sendpld_flush() - * does not mistakingly believe that a record is - * already prepared and being sent. - */ - rc->oxb = rc->oxa + 1; - sendpld_flush(rc, 0); - } -} - -static unsigned char * -sendrec_buf(const br_ssl_engine_context *rc, size_t *len) -{ - /* - * When still gathering payload bytes, oxc points to the start - * of the record data, so oxc <= oxa. However, when a full - * record has been completed, oxc points to the end of the record, - * so oxc > oxa. - */ - switch (rc->iomode) { - case BR_IO_OUT: - case BR_IO_INOUT: - if (rc->oxc > rc->oxa) { - *len = rc->oxc - rc->oxa; - return rc->obuf + rc->oxa; - } - break; - } - *len = 0; - return NULL; -} - -static void -sendrec_ack(br_ssl_engine_context *rc, size_t len) -{ - rc->oxb = (rc->oxa += len); - if (rc->oxa == rc->oxc) { - make_ready_out(rc); - } -} - -/* - * Test whether there is some buffered outgoing record that still must - * sent. - */ -static inline int -has_rec_tosend(const br_ssl_engine_context *rc) -{ - return rc->oxa == rc->oxb && rc->oxa != rc->oxc; -} - -/* - * The "no encryption" mode has no overhead. It limits the payload size - * to the maximum size allowed by the standard (16384 bytes); the caller - * is responsible for possibly enforcing a smaller fragment length. - */ -static void -clear_max_plaintext(const br_sslrec_out_clear_context *cc, - size_t *start, size_t *end) -{ - size_t len; - - (void)cc; - len = *end - *start; - if (len > 16384) { - *end = *start + 16384; - } -} - -/* - * In "no encryption" mode, encryption is trivial (a no-operation) so - * we just have to encode the header. - */ -static unsigned char * -clear_encrypt(br_sslrec_out_clear_context *cc, - int record_type, unsigned version, void *data, size_t *data_len) -{ - unsigned char *buf; - - (void)cc; - buf = (unsigned char *)data - 5; - buf[0] = record_type; - br_enc16be(buf + 1, version); - br_enc16be(buf + 3, *data_len); - *data_len += 5; - return buf; -} - -/* see bearssl_ssl.h */ -const br_sslrec_out_class br_sslrec_out_clear_vtable = { - sizeof(br_sslrec_out_clear_context), - (void (*)(const br_sslrec_out_class *const *, size_t *, size_t *)) - &clear_max_plaintext, - (unsigned char *(*)(const br_sslrec_out_class **, - int, unsigned, void *, size_t *)) - &clear_encrypt -}; - -/* ==================================================================== */ -/* - * In this part of the file, we handle the various record types, and - * communications with the handshake processor. - */ - -/* - * IMPLEMENTATION NOTES - * ==================== - * - * The handshake processor is written in T0 and runs as a coroutine. - * It receives the contents of all records except application data, and - * is responsible for producing the contents of all records except - * application data. - * - * A state flag is maintained, which specifies whether application data - * is acceptable or not. When it is set: - * - * -- Application data can be injected as payload data (provided that - * the output buffer is ready for that). - * - * -- Incoming application data records are accepted, and yield data - * that the caller may retrieve. - * - * When the flag is cleared, application data is not accepted from the - * application, and incoming application data records trigger an error. - * - * - * Records of type handshake, alert or change-cipher-spec are handled - * by the handshake processor. The handshake processor is written in T0 - * and runs as a coroutine; it gets invoked whenever one of the following - * situations is reached: - * - * -- An incoming record has type handshake, alert or change-cipher-spec, - * and yields data that can be read (zero-length records are thus - * ignored). - * - * -- An outgoing record has just finished being sent, and the "application - * data" flag is cleared. - * - * -- The caller wishes to perform a close (call to br_ssl_engine_close()). - * - * -- The caller wishes to perform a renegotiation (call to - * br_ssl_engine_renegotiate()). - * - * Whenever the handshake processor is entered, access to the payload - * buffers is provided, along with some information about explicit - * closures or renegotiations. - */ - -/* see bearssl_ssl.h */ -void -br_ssl_engine_set_suites(br_ssl_engine_context *cc, - const uint16_t *suites, size_t suites_num) -{ - if ((suites_num * sizeof *suites) > sizeof cc->suites_buf) { - br_ssl_engine_fail(cc, BR_ERR_BAD_PARAM); - return; - } - memcpy(cc->suites_buf, suites, suites_num * sizeof *suites); - cc->suites_num = suites_num; -} - -/* - * Give control to handshake processor. 'action' is 1 for a close, - * 2 for a renegotiation, or 0 for a jump due to I/O completion. - */ -static void -jump_handshake(br_ssl_engine_context *cc, int action) -{ - /* - * We use a loop because the handshake processor actions may - * allow for more actions; namely, if the processor reads all - * input data, then it may allow for output data to be produced, - * in case of a shared in/out buffer. - */ - for (;;) { - size_t hlen_in, hlen_out; - - /* - * Get input buffer. We do not want to provide - * application data to the handshake processor (we could - * get called with an explicit close or renegotiation - * while there is application data ready to be read). - */ - cc->hbuf_in = recvpld_buf(cc, &hlen_in); - if (cc->hbuf_in != NULL - && cc->record_type_in == BR_SSL_APPLICATION_DATA) - { - hlen_in = 0; - } - - /* - * Get output buffer. The handshake processor never - * leaves an unfinished outgoing record, so if there is - * buffered output, then it MUST be some application - * data, so the processor cannot write to it. - */ - cc->saved_hbuf_out = cc->hbuf_out = sendpld_buf(cc, &hlen_out); - if (cc->hbuf_out != NULL && br_ssl_engine_has_pld_to_send(cc)) { - hlen_out = 0; - } - - /* - * Note: hlen_in and hlen_out can be both non-zero only if - * the input and output buffers are disjoint. Thus, we can - * offer both buffers to the handshake code. - */ - - cc->hlen_in = hlen_in; - cc->hlen_out = hlen_out; - cc->action = action; - cc->hsrun(&cc->cpu); - if (br_ssl_engine_closed(cc)) { - return; - } - if (cc->hbuf_out != cc->saved_hbuf_out) { - sendpld_ack(cc, cc->hbuf_out - cc->saved_hbuf_out); - } - if (hlen_in != cc->hlen_in) { - recvpld_ack(cc, hlen_in - cc->hlen_in); - if (cc->hlen_in == 0) { - /* - * We read all data bytes, which may have - * released the output buffer in case it - * is shared with the input buffer, and - * the handshake code might be waiting for - * that. - */ - action = 0; - continue; - } - } - break; - } -} - -/* see inner.h */ -void -br_ssl_engine_flush_record(br_ssl_engine_context *cc) -{ - if (cc->hbuf_out != cc->saved_hbuf_out) { - sendpld_ack(cc, cc->hbuf_out - cc->saved_hbuf_out); - } - if (br_ssl_engine_has_pld_to_send(cc)) { - sendpld_flush(cc, 0); - } - cc->saved_hbuf_out = cc->hbuf_out = sendpld_buf(cc, &cc->hlen_out); -} - -/* see bearssl_ssl.h */ -unsigned char * -br_ssl_engine_sendapp_buf(const br_ssl_engine_context *cc, size_t *len) -{ - if (!(cc->application_data & 1)) { - *len = 0; - return NULL; - } - return sendpld_buf(cc, len); -} - -/* see bearssl_ssl.h */ -void -br_ssl_engine_sendapp_ack(br_ssl_engine_context *cc, size_t len) -{ - sendpld_ack(cc, len); -} - -/* see bearssl_ssl.h */ -unsigned char * -br_ssl_engine_recvapp_buf(const br_ssl_engine_context *cc, size_t *len) -{ - if (!(cc->application_data & 1) - || cc->record_type_in != BR_SSL_APPLICATION_DATA) - { - *len = 0; - return NULL; - } - return recvpld_buf(cc, len); -} - -/* see bearssl_ssl.h */ -void -br_ssl_engine_recvapp_ack(br_ssl_engine_context *cc, size_t len) -{ - recvpld_ack(cc, len); -} - -/* see bearssl_ssl.h */ -unsigned char * -br_ssl_engine_sendrec_buf(const br_ssl_engine_context *cc, size_t *len) -{ - return sendrec_buf(cc, len); -} - -/* see bearssl_ssl.h */ -void -br_ssl_engine_sendrec_ack(br_ssl_engine_context *cc, size_t len) -{ - sendrec_ack(cc, len); - if (len != 0 && !has_rec_tosend(cc) - && (cc->record_type_out != BR_SSL_APPLICATION_DATA - || (cc->application_data & 1) == 0)) - { - jump_handshake(cc, 0); - } -} - -/* see bearssl_ssl.h */ -unsigned char * -br_ssl_engine_recvrec_buf(const br_ssl_engine_context *cc, size_t *len) -{ - return recvrec_buf(cc, len); -} - -/* see bearssl_ssl.h */ -void -br_ssl_engine_recvrec_ack(br_ssl_engine_context *cc, size_t len) -{ - unsigned char *buf; - - recvrec_ack(cc, len); - if (br_ssl_engine_closed(cc)) { - return; - } - - /* - * We just received some bytes from the peer. This may have - * yielded some payload bytes, in which case we must process - * them according to the record type. - */ - buf = recvpld_buf(cc, &len); - if (buf != NULL) { - switch (cc->record_type_in) { - case BR_SSL_CHANGE_CIPHER_SPEC: - case BR_SSL_ALERT: - case BR_SSL_HANDSHAKE: - jump_handshake(cc, 0); - break; - case BR_SSL_APPLICATION_DATA: - if (cc->application_data == 1) { - break; - } - - /* - * If we are currently closing, and waiting for - * a close_notify from the peer, then incoming - * application data should be discarded. - */ - if (cc->application_data == 2) { - recvpld_ack(cc, len); - break; - } - - /* Fall through */ - default: - br_ssl_engine_fail(cc, BR_ERR_UNEXPECTED); - break; - } - } -} - -/* see bearssl_ssl.h */ -void -br_ssl_engine_close(br_ssl_engine_context *cc) -{ - if (!br_ssl_engine_closed(cc)) { - jump_handshake(cc, 1); - } -} - -/* see bearssl_ssl.h */ -int -br_ssl_engine_renegotiate(br_ssl_engine_context *cc) -{ - size_t len; - - if (br_ssl_engine_closed(cc) || cc->reneg == 1 - || (cc->flags & BR_OPT_NO_RENEGOTIATION) != 0 - || br_ssl_engine_recvapp_buf(cc, &len) != NULL) - { - return 0; - } - jump_handshake(cc, 2); - return 1; -} - -/* see bearssl.h */ -unsigned -br_ssl_engine_current_state(const br_ssl_engine_context *cc) -{ - unsigned s; - size_t len; - - if (br_ssl_engine_closed(cc)) { - return BR_SSL_CLOSED; - } - - s = 0; - if (br_ssl_engine_sendrec_buf(cc, &len) != NULL) { - s |= BR_SSL_SENDREC; - } - if (br_ssl_engine_recvrec_buf(cc, &len) != NULL) { - s |= BR_SSL_RECVREC; - } - if (br_ssl_engine_sendapp_buf(cc, &len) != NULL) { - s |= BR_SSL_SENDAPP; - } - if (br_ssl_engine_recvapp_buf(cc, &len) != NULL) { - s |= BR_SSL_RECVAPP; - } - return s; -} - -/* see bearssl_ssl.h */ -void -br_ssl_engine_flush(br_ssl_engine_context *cc, int force) -{ - if (!br_ssl_engine_closed(cc) && (cc->application_data & 1) != 0) { - sendpld_flush(cc, force); - } -} - -/* see inner.h */ -void -br_ssl_engine_hs_reset(br_ssl_engine_context *cc, - void (*hsinit)(void *), void (*hsrun)(void *)) -{ - engine_clearbuf(cc); - cc->cpu.dp = cc->dp_stack; - cc->cpu.rp = cc->rp_stack; - hsinit(&cc->cpu); - cc->hsrun = hsrun; - cc->shutdown_recv = 0; - cc->application_data = 0; - cc->alert = 0; - jump_handshake(cc, 0); -} - -/* see inner.h */ -br_tls_prf_impl -br_ssl_engine_get_PRF(br_ssl_engine_context *cc, int prf_id) -{ - if (cc->session.version >= BR_TLS12) { - if (prf_id == br_sha384_ID) { - return cc->prf_sha384; - } else { - return cc->prf_sha256; - } - } else { - return cc->prf10; - } -} - -/* see inner.h */ -void -br_ssl_engine_compute_master(br_ssl_engine_context *cc, - int prf_id, const void *pms, size_t pms_len) -{ - br_tls_prf_impl iprf; - br_tls_prf_seed_chunk seed[2] = { - { cc->client_random, sizeof cc->client_random }, - { cc->server_random, sizeof cc->server_random } - }; - - iprf = br_ssl_engine_get_PRF(cc, prf_id); - iprf(cc->session.master_secret, sizeof cc->session.master_secret, - pms, pms_len, "master secret", 2, seed); -} - -/* - * Compute key block. - */ -static void -compute_key_block(br_ssl_engine_context *cc, int prf_id, - size_t half_len, unsigned char *kb) -{ - br_tls_prf_impl iprf; - br_tls_prf_seed_chunk seed[2] = { - { cc->server_random, sizeof cc->server_random }, - { cc->client_random, sizeof cc->client_random } - }; - - iprf = br_ssl_engine_get_PRF(cc, prf_id); - iprf(kb, half_len << 1, - cc->session.master_secret, sizeof cc->session.master_secret, - "key expansion", 2, seed); -} - -/* see inner.h */ -void -br_ssl_engine_switch_cbc_in(br_ssl_engine_context *cc, - int is_client, int prf_id, int mac_id, - const br_block_cbcdec_class *bc_impl, size_t cipher_key_len) -{ - unsigned char kb[192]; - unsigned char *cipher_key, *mac_key, *iv; - const br_hash_class *imh; - size_t mac_key_len, mac_out_len, iv_len; - - imh = br_ssl_engine_get_hash(cc, mac_id); - mac_out_len = (imh->desc >> BR_HASHDESC_OUT_OFF) & BR_HASHDESC_OUT_MASK; - mac_key_len = mac_out_len; - - /* - * TLS 1.1+ uses per-record explicit IV, so no IV to generate here. - */ - if (cc->session.version >= BR_TLS11) { - iv_len = 0; - } else { - iv_len = bc_impl->block_size; - } - compute_key_block(cc, prf_id, - mac_key_len + cipher_key_len + iv_len, kb); - if (is_client) { - mac_key = &kb[mac_key_len]; - cipher_key = &kb[(mac_key_len << 1) + cipher_key_len]; - iv = &kb[((mac_key_len + cipher_key_len) << 1) + iv_len]; - } else { - mac_key = &kb[0]; - cipher_key = &kb[mac_key_len << 1]; - iv = &kb[(mac_key_len + cipher_key_len) << 1]; - } - if (iv_len == 0) { - iv = NULL; - } - cc->icbc_in->init(&cc->in.cbc.vtable, - bc_impl, cipher_key, cipher_key_len, - imh, mac_key, mac_key_len, mac_out_len, iv); - cc->incrypt = 1; -} - -/* see inner.h */ -void -br_ssl_engine_switch_cbc_out(br_ssl_engine_context *cc, - int is_client, int prf_id, int mac_id, - const br_block_cbcenc_class *bc_impl, size_t cipher_key_len) -{ - unsigned char kb[192]; - unsigned char *cipher_key, *mac_key, *iv; - const br_hash_class *imh; - size_t mac_key_len, mac_out_len, iv_len; - - imh = br_ssl_engine_get_hash(cc, mac_id); - mac_out_len = (imh->desc >> BR_HASHDESC_OUT_OFF) & BR_HASHDESC_OUT_MASK; - mac_key_len = mac_out_len; - - /* - * TLS 1.1+ uses per-record explicit IV, so no IV to generate here. - */ - if (cc->session.version >= BR_TLS11) { - iv_len = 0; - } else { - iv_len = bc_impl->block_size; - } - compute_key_block(cc, prf_id, - mac_key_len + cipher_key_len + iv_len, kb); - if (is_client) { - mac_key = &kb[0]; - cipher_key = &kb[mac_key_len << 1]; - iv = &kb[(mac_key_len + cipher_key_len) << 1]; - } else { - mac_key = &kb[mac_key_len]; - cipher_key = &kb[(mac_key_len << 1) + cipher_key_len]; - iv = &kb[((mac_key_len + cipher_key_len) << 1) + iv_len]; - } - if (iv_len == 0) { - iv = NULL; - } - cc->icbc_out->init(&cc->out.cbc.vtable, - bc_impl, cipher_key, cipher_key_len, - imh, mac_key, mac_key_len, mac_out_len, iv); -} - -/* see inner.h */ -void -br_ssl_engine_switch_gcm_in(br_ssl_engine_context *cc, - int is_client, int prf_id, - const br_block_ctr_class *bc_impl, size_t cipher_key_len) -{ - unsigned char kb[72]; - unsigned char *cipher_key, *iv; - - compute_key_block(cc, prf_id, cipher_key_len + 4, kb); - if (is_client) { - cipher_key = &kb[cipher_key_len]; - iv = &kb[(cipher_key_len << 1) + 4]; - } else { - cipher_key = &kb[0]; - iv = &kb[cipher_key_len << 1]; - } - cc->igcm_in->init(&cc->in.gcm.vtable.in, - bc_impl, cipher_key, cipher_key_len, cc->ighash, iv); - cc->incrypt = 1; -} - -/* see inner.h */ -void -br_ssl_engine_switch_gcm_out(br_ssl_engine_context *cc, - int is_client, int prf_id, - const br_block_ctr_class *bc_impl, size_t cipher_key_len) -{ - unsigned char kb[72]; - unsigned char *cipher_key, *iv; - - compute_key_block(cc, prf_id, cipher_key_len + 4, kb); - if (is_client) { - cipher_key = &kb[0]; - iv = &kb[cipher_key_len << 1]; - } else { - cipher_key = &kb[cipher_key_len]; - iv = &kb[(cipher_key_len << 1) + 4]; - } - cc->igcm_out->init(&cc->out.gcm.vtable.out, - bc_impl, cipher_key, cipher_key_len, cc->ighash, iv); -} - -/* see inner.h */ -void -br_ssl_engine_switch_chapol_in(br_ssl_engine_context *cc, - int is_client, int prf_id) -{ - unsigned char kb[88]; - unsigned char *cipher_key, *iv; - - compute_key_block(cc, prf_id, 44, kb); - if (is_client) { - cipher_key = &kb[32]; - iv = &kb[76]; - } else { - cipher_key = &kb[0]; - iv = &kb[64]; - } - cc->ichapol_in->init(&cc->in.chapol.vtable.in, - cc->ichacha, cc->ipoly, cipher_key, iv); - cc->incrypt = 1; -} - -/* see inner.h */ -void -br_ssl_engine_switch_chapol_out(br_ssl_engine_context *cc, - int is_client, int prf_id) -{ - unsigned char kb[88]; - unsigned char *cipher_key, *iv; - - compute_key_block(cc, prf_id, 44, kb); - if (is_client) { - cipher_key = &kb[0]; - iv = &kb[64]; - } else { - cipher_key = &kb[32]; - iv = &kb[76]; - } - cc->ichapol_out->init(&cc->out.chapol.vtable.out, - cc->ichacha, cc->ipoly, cipher_key, iv); -} - -/* see inner.h */ -void -br_ssl_engine_switch_ccm_in(br_ssl_engine_context *cc, - int is_client, int prf_id, - const br_block_ctrcbc_class *bc_impl, - size_t cipher_key_len, size_t tag_len) -{ - unsigned char kb[72]; - unsigned char *cipher_key, *iv; - - compute_key_block(cc, prf_id, cipher_key_len + 4, kb); - if (is_client) { - cipher_key = &kb[cipher_key_len]; - iv = &kb[(cipher_key_len << 1) + 4]; - } else { - cipher_key = &kb[0]; - iv = &kb[cipher_key_len << 1]; - } - cc->iccm_in->init(&cc->in.ccm.vtable.in, - bc_impl, cipher_key, cipher_key_len, iv, tag_len); - cc->incrypt = 1; -} - -/* see inner.h */ -void -br_ssl_engine_switch_ccm_out(br_ssl_engine_context *cc, - int is_client, int prf_id, - const br_block_ctrcbc_class *bc_impl, - size_t cipher_key_len, size_t tag_len) -{ - unsigned char kb[72]; - unsigned char *cipher_key, *iv; - - compute_key_block(cc, prf_id, cipher_key_len + 4, kb); - if (is_client) { - cipher_key = &kb[0]; - iv = &kb[cipher_key_len << 1]; - } else { - cipher_key = &kb[cipher_key_len]; - iv = &kb[(cipher_key_len << 1) + 4]; - } - cc->iccm_out->init(&cc->out.ccm.vtable.out, - bc_impl, cipher_key, cipher_key_len, iv, tag_len); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ssl_engine_default_aescbc.c b/src/tls/bearssl/ssl_engine_default_aescbc.c deleted file mode 100644 index 91bd3d812..000000000 --- a/src/tls/bearssl/ssl_engine_default_aescbc.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_ssl.h */ -void -br_ssl_engine_set_default_aes_cbc(br_ssl_engine_context *cc) -{ -#if BR_AES_X86NI || BR_POWER8 - const br_block_cbcenc_class *ienc; - const br_block_cbcdec_class *idec; -#endif - - br_ssl_engine_set_cbc(cc, - &br_sslrec_in_cbc_vtable, - &br_sslrec_out_cbc_vtable); -#if BR_AES_X86NI - ienc = br_aes_x86ni_cbcenc_get_vtable(); - idec = br_aes_x86ni_cbcdec_get_vtable(); - if (ienc != NULL && idec != NULL) { - br_ssl_engine_set_aes_cbc(cc, ienc, idec); - return; - } -#endif -#if BR_POWER8 - ienc = br_aes_pwr8_cbcenc_get_vtable(); - idec = br_aes_pwr8_cbcdec_get_vtable(); - if (ienc != NULL && idec != NULL) { - br_ssl_engine_set_aes_cbc(cc, ienc, idec); - return; - } -#endif -#if BR_64 - br_ssl_engine_set_aes_cbc(cc, - &br_aes_ct64_cbcenc_vtable, - &br_aes_ct64_cbcdec_vtable); -#else - br_ssl_engine_set_aes_cbc(cc, - &br_aes_ct_cbcenc_vtable, - &br_aes_ct_cbcdec_vtable); -#endif -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ssl_engine_default_aesccm.c b/src/tls/bearssl/ssl_engine_default_aesccm.c deleted file mode 100644 index dcc12d668..000000000 --- a/src/tls/bearssl/ssl_engine_default_aesccm.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_ssl.h */ -void -br_ssl_engine_set_default_aes_ccm(br_ssl_engine_context *cc) -{ -#if BR_AES_X86NI || BR_POWER8 - const br_block_ctrcbc_class *ictrcbc; -#endif - - br_ssl_engine_set_ccm(cc, - &br_sslrec_in_ccm_vtable, - &br_sslrec_out_ccm_vtable); -#if BR_AES_X86NI - ictrcbc = br_aes_x86ni_ctrcbc_get_vtable(); - if (ictrcbc != NULL) { - br_ssl_engine_set_aes_ctrcbc(cc, ictrcbc); - } else { -#if BR_64 - br_ssl_engine_set_aes_ctrcbc(cc, &br_aes_ct64_ctrcbc_vtable); -#else - br_ssl_engine_set_aes_ctrcbc(cc, &br_aes_ct_ctrcbc_vtable); -#endif - } -#elif BR_POWER8 - ictrcbc = br_aes_pwr8_ctrcbc_get_vtable(); - if (ictrcbc != NULL) { - br_ssl_engine_set_aes_ctrcbc(cc, ictrcbc); - } else { -#if BR_64 - br_ssl_engine_set_aes_ctrcbc(cc, &br_aes_ct64_ctrcbc_vtable); -#else - br_ssl_engine_set_aes_ctrcbc(cc, &br_aes_ct_ctrcbc_vtable); -#endif - } -#else -#if BR_64 - br_ssl_engine_set_aes_ctrcbc(cc, &br_aes_ct64_ctrcbc_vtable); -#else - br_ssl_engine_set_aes_ctrcbc(cc, &br_aes_ct_ctrcbc_vtable); -#endif -#endif -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ssl_engine_default_aesgcm.c b/src/tls/bearssl/ssl_engine_default_aesgcm.c deleted file mode 100644 index 145a01c18..000000000 --- a/src/tls/bearssl/ssl_engine_default_aesgcm.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_ssl.h */ -void -br_ssl_engine_set_default_aes_gcm(br_ssl_engine_context *cc) -{ -#if BR_AES_X86NI || BR_POWER8 - const br_block_ctr_class *ictr; - br_ghash ighash; -#endif - - br_ssl_engine_set_gcm(cc, - &br_sslrec_in_gcm_vtable, - &br_sslrec_out_gcm_vtable); -#if BR_AES_X86NI - ictr = br_aes_x86ni_ctr_get_vtable(); - if (ictr != NULL) { - br_ssl_engine_set_aes_ctr(cc, ictr); - } else { -#if BR_64 - br_ssl_engine_set_aes_ctr(cc, &br_aes_ct64_ctr_vtable); -#else - br_ssl_engine_set_aes_ctr(cc, &br_aes_ct_ctr_vtable); -#endif - } -#elif BR_POWER8 - ictr = br_aes_pwr8_ctr_get_vtable(); - if (ictr != NULL) { - br_ssl_engine_set_aes_ctr(cc, ictr); - } else { -#if BR_64 - br_ssl_engine_set_aes_ctr(cc, &br_aes_ct64_ctr_vtable); -#else - br_ssl_engine_set_aes_ctr(cc, &br_aes_ct_ctr_vtable); -#endif - } -#else -#if BR_64 - br_ssl_engine_set_aes_ctr(cc, &br_aes_ct64_ctr_vtable); -#else - br_ssl_engine_set_aes_ctr(cc, &br_aes_ct_ctr_vtable); -#endif -#endif -#if BR_AES_X86NI - ighash = br_ghash_pclmul_get(); - if (ighash != 0) { - br_ssl_engine_set_ghash(cc, ighash); - return; - } -#endif -#if BR_POWER8 - ighash = br_ghash_pwr8_get(); - if (ighash != 0) { - br_ssl_engine_set_ghash(cc, ighash); - return; - } -#endif -#if BR_LOMUL - br_ssl_engine_set_ghash(cc, &br_ghash_ctmul32); -#elif BR_64 - br_ssl_engine_set_ghash(cc, &br_ghash_ctmul64); -#else - br_ssl_engine_set_ghash(cc, &br_ghash_ctmul); -#endif -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ssl_engine_default_chapol.c b/src/tls/bearssl/ssl_engine_default_chapol.c deleted file mode 100644 index ae1007228..000000000 --- a/src/tls/bearssl/ssl_engine_default_chapol.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_ssl.h */ -void -br_ssl_engine_set_default_chapol(br_ssl_engine_context *cc) -{ -#if BR_INT128 || BR_UMUL128 - br_poly1305_run bp; -#endif -#if BR_SSE2 - br_chacha20_run bc; -#endif - - br_ssl_engine_set_chapol(cc, - &br_sslrec_in_chapol_vtable, - &br_sslrec_out_chapol_vtable); -#if BR_SSE2 - bc = br_chacha20_sse2_get(); - if (bc) { - br_ssl_engine_set_chacha20(cc, bc); - } else { -#endif - br_ssl_engine_set_chacha20(cc, &br_chacha20_ct_run); -#if BR_SSE2 - } -#endif -#if BR_INT128 || BR_UMUL128 - bp = br_poly1305_ctmulq_get(); - if (bp) { - br_ssl_engine_set_poly1305(cc, bp); - } else { -#endif -#if BR_LOMUL - br_ssl_engine_set_poly1305(cc, &br_poly1305_ctmul32_run); -#else - br_ssl_engine_set_poly1305(cc, &br_poly1305_ctmul_run); -#endif -#if BR_INT128 || BR_UMUL128 - } -#endif -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ssl_engine_default_descbc.c b/src/tls/bearssl/ssl_engine_default_descbc.c deleted file mode 100644 index 81d486715..000000000 --- a/src/tls/bearssl/ssl_engine_default_descbc.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_ssl.h */ -void -br_ssl_engine_set_default_des_cbc(br_ssl_engine_context *cc) -{ - br_ssl_engine_set_cbc(cc, - &br_sslrec_in_cbc_vtable, - &br_sslrec_out_cbc_vtable); - br_ssl_engine_set_des_cbc(cc, - &br_des_ct_cbcenc_vtable, - &br_des_ct_cbcdec_vtable); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ssl_engine_default_ec.c b/src/tls/bearssl/ssl_engine_default_ec.c deleted file mode 100644 index 687b61481..000000000 --- a/src/tls/bearssl/ssl_engine_default_ec.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_ssl.h */ -void -br_ssl_engine_set_default_ec(br_ssl_engine_context *cc) -{ -#if BR_LOMUL - br_ssl_engine_set_ec(cc, &br_ec_all_m15); -#else - br_ssl_engine_set_ec(cc, &br_ec_all_m31); -#endif -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ssl_engine_default_ecdsa.c b/src/tls/bearssl/ssl_engine_default_ecdsa.c deleted file mode 100644 index 194bce0fe..000000000 --- a/src/tls/bearssl/ssl_engine_default_ecdsa.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_ssl.h */ -void -br_ssl_engine_set_default_ecdsa(br_ssl_engine_context *cc) -{ -#if BR_LOMUL - br_ssl_engine_set_ec(cc, &br_ec_all_m15); - br_ssl_engine_set_ecdsa(cc, &br_ecdsa_i15_vrfy_asn1); -#else - br_ssl_engine_set_ec(cc, &br_ec_all_m31); - br_ssl_engine_set_ecdsa(cc, &br_ecdsa_i31_vrfy_asn1); -#endif -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ssl_engine_default_rsavrfy.c b/src/tls/bearssl/ssl_engine_default_rsavrfy.c deleted file mode 100644 index b94a3fc6c..000000000 --- a/src/tls/bearssl/ssl_engine_default_rsavrfy.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_ssl.h */ -void -br_ssl_engine_set_default_rsavrfy(br_ssl_engine_context *cc) -{ - br_ssl_engine_set_rsavrfy(cc, br_rsa_pkcs1_vrfy_get_default()); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ssl_hashes.c b/src/tls/bearssl/ssl_hashes.c deleted file mode 100644 index 06d00a4fa..000000000 --- a/src/tls/bearssl/ssl_hashes.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see inner.h */ -int -br_ssl_choose_hash(unsigned bf) -{ - static const unsigned char pref[] = { - br_sha256_ID, br_sha384_ID, br_sha512_ID, - br_sha224_ID, br_sha1_ID - }; - size_t u; - - for (u = 0; u < sizeof pref; u ++) { - int x; - - x = pref[u]; - if ((bf >> x) & 1) { - return x; - } - } - return 0; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ssl_hs_client.c b/src/tls/bearssl/ssl_hs_client.c deleted file mode 100644 index 716582067..000000000 --- a/src/tls/bearssl/ssl_hs_client.c +++ /dev/null @@ -1,1920 +0,0 @@ -/* Automatically generated code; do not modify directly. */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include -#include - -typedef struct { - uint32_t *dp; - uint32_t *rp; - const unsigned char *ip; -} t0_context; - -static uint32_t -t0_parse7E_unsigned(const unsigned char **p) -{ - uint32_t x; - - x = 0; - for (;;) { - unsigned y; - - y = *(*p) ++; - x = (x << 7) | (uint32_t)(y & 0x7F); - if (y < 0x80) { - return x; - } - } -} - -static int32_t -t0_parse7E_signed(const unsigned char **p) -{ - int neg; - uint32_t x; - - neg = ((**p) >> 6) & 1; - x = (uint32_t)-neg; - for (;;) { - unsigned y; - - y = *(*p) ++; - x = (x << 7) | (uint32_t)(y & 0x7F); - if (y < 0x80) { - if (neg) { - return -(int32_t)~x - 1; - } else { - return (int32_t)x; - } - } - } -} - -#define T0_VBYTE(x, n) (unsigned char)((((uint32_t)(x) >> (n)) & 0x7F) | 0x80) -#define T0_FBYTE(x, n) (unsigned char)(((uint32_t)(x) >> (n)) & 0x7F) -#define T0_SBYTE(x) (unsigned char)((((uint32_t)(x) >> 28) + 0xF8) ^ 0xF8) -#define T0_INT1(x) T0_FBYTE(x, 0) -#define T0_INT2(x) T0_VBYTE(x, 7), T0_FBYTE(x, 0) -#define T0_INT3(x) T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) -#define T0_INT4(x) T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) -#define T0_INT5(x) T0_SBYTE(x), T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) - -/* static const unsigned char t0_datablock[]; */ - - -void br_ssl_hs_client_init_main(void *t0ctx); - -void br_ssl_hs_client_run(void *t0ctx); - - - -#include -#include - -#include "inner.h" - -/* - * This macro evaluates to a pointer to the current engine context. - */ -#define ENG ((br_ssl_engine_context *)(void *)((unsigned char *)t0ctx - offsetof(br_ssl_engine_context, cpu))) - - - - - -/* - * This macro evaluates to a pointer to the client context, under that - * specific name. It must be noted that since the engine context is the - * first field of the br_ssl_client_context structure ('eng'), then - * pointers values of both types are interchangeable, modulo an - * appropriate cast. This also means that "addresses" computed as offsets - * within the structure work for both kinds of context. - */ -#define CTX ((br_ssl_client_context *)ENG) - -/* - * Generate the pre-master secret for RSA key exchange, and encrypt it - * with the server's public key. Returned value is either the encrypted - * data length (in bytes), or -x on error, with 'x' being an error code. - * - * This code assumes that the public key has been already verified (it - * was properly obtained by the X.509 engine, and it has the right type, - * i.e. it is of type RSA and suitable for encryption). - */ -static int -make_pms_rsa(br_ssl_client_context *ctx, int prf_id) -{ - const br_x509_class **xc; - const br_x509_pkey *pk; - const unsigned char *n; - unsigned char *pms; - size_t nlen, u; - - xc = ctx->eng.x509ctx; - pk = (*xc)->get_pkey(xc, NULL); - - /* - * Compute actual RSA key length, in case there are leading zeros. - */ - n = pk->key.rsa.n; - nlen = pk->key.rsa.nlen; - while (nlen > 0 && *n == 0) { - n ++; - nlen --; - } - - /* - * We need at least 59 bytes (48 bytes for pre-master secret, and - * 11 bytes for the PKCS#1 type 2 padding). Note that the X.509 - * minimal engine normally blocks RSA keys shorter than 128 bytes, - * so this is mostly for public keys provided explicitly by the - * caller. - */ - if (nlen < 59) { - return -BR_ERR_X509_WEAK_PUBLIC_KEY; - } - if (nlen > sizeof ctx->eng.pad) { - return -BR_ERR_LIMIT_EXCEEDED; - } - - /* - * Make PMS. - */ - pms = ctx->eng.pad + nlen - 48; - br_enc16be(pms, ctx->eng.version_max); - br_hmac_drbg_generate(&ctx->eng.rng, pms + 2, 46); - br_ssl_engine_compute_master(&ctx->eng, prf_id, pms, 48); - - /* - * Apply PKCS#1 type 2 padding. - */ - ctx->eng.pad[0] = 0x00; - ctx->eng.pad[1] = 0x02; - ctx->eng.pad[nlen - 49] = 0x00; - br_hmac_drbg_generate(&ctx->eng.rng, ctx->eng.pad + 2, nlen - 51); - for (u = 2; u < nlen - 49; u ++) { - while (ctx->eng.pad[u] == 0) { - br_hmac_drbg_generate(&ctx->eng.rng, - &ctx->eng.pad[u], 1); - } - } - - /* - * Compute RSA encryption. - */ - if (!ctx->irsapub(ctx->eng.pad, nlen, &pk->key.rsa)) { - return -BR_ERR_LIMIT_EXCEEDED; - } - return (int)nlen; -} - -/* - * OID for hash functions in RSA signatures. - */ -static const unsigned char *HASH_OID[] = { - BR_HASH_OID_SHA1, - BR_HASH_OID_SHA224, - BR_HASH_OID_SHA256, - BR_HASH_OID_SHA384, - BR_HASH_OID_SHA512 -}; - -/* - * Check the RSA signature on the ServerKeyExchange message. - * - * hash hash function ID (2 to 6), or 0 for MD5+SHA-1 (with RSA only) - * use_rsa non-zero for RSA signature, zero for ECDSA - * sig_len signature length (in bytes); signature value is in the pad - * - * Returned value is 0 on success, or an error code. - */ -static int -verify_SKE_sig(br_ssl_client_context *ctx, - int hash, int use_rsa, size_t sig_len) -{ - const br_x509_class **xc; - const br_x509_pkey *pk; - br_multihash_context mhc; - unsigned char hv[64], head[4]; - size_t hv_len; - - xc = ctx->eng.x509ctx; - pk = (*xc)->get_pkey(xc, NULL); - br_multihash_zero(&mhc); - br_multihash_copyimpl(&mhc, &ctx->eng.mhash); - br_multihash_init(&mhc); - br_multihash_update(&mhc, - ctx->eng.client_random, sizeof ctx->eng.client_random); - br_multihash_update(&mhc, - ctx->eng.server_random, sizeof ctx->eng.server_random); - head[0] = 3; - head[1] = 0; - head[2] = ctx->eng.ecdhe_curve; - head[3] = ctx->eng.ecdhe_point_len; - br_multihash_update(&mhc, head, sizeof head); - br_multihash_update(&mhc, - ctx->eng.ecdhe_point, ctx->eng.ecdhe_point_len); - if (hash) { - hv_len = br_multihash_out(&mhc, hash, hv); - if (hv_len == 0) { - return BR_ERR_INVALID_ALGORITHM; - } - } else { - if (!br_multihash_out(&mhc, br_md5_ID, hv) - || !br_multihash_out(&mhc, br_sha1_ID, hv + 16)) - { - return BR_ERR_INVALID_ALGORITHM; - } - hv_len = 36; - } - if (use_rsa) { - unsigned char tmp[64]; - const unsigned char *hash_oid; - - if (hash) { - hash_oid = HASH_OID[hash - 2]; - } else { - hash_oid = NULL; - } - if (!ctx->eng.irsavrfy(ctx->eng.pad, sig_len, - hash_oid, hv_len, &pk->key.rsa, tmp) - || memcmp(tmp, hv, hv_len) != 0) - { - return BR_ERR_BAD_SIGNATURE; - } - } else { - if (!ctx->eng.iecdsa(ctx->eng.iec, hv, hv_len, &pk->key.ec, - ctx->eng.pad, sig_len)) - { - return BR_ERR_BAD_SIGNATURE; - } - } - return 0; -} - -/* - * Perform client-side ECDH (or ECDHE). The point that should be sent to - * the server is written in the pad; returned value is either the point - * length (in bytes), or -x on error, with 'x' being an error code. - * - * The point _from_ the server is taken from ecdhe_point[] if 'ecdhe' - * is non-zero, or from the X.509 engine context if 'ecdhe' is zero - * (for static ECDH). - */ -static int -make_pms_ecdh(br_ssl_client_context *ctx, unsigned ecdhe, int prf_id) -{ - int curve; - unsigned char key[66], point[133]; - const unsigned char *order, *point_src; - size_t glen, olen, point_len, xoff, xlen; - unsigned char mask; - - if (ecdhe) { - curve = ctx->eng.ecdhe_curve; - point_src = ctx->eng.ecdhe_point; - point_len = ctx->eng.ecdhe_point_len; - } else { - const br_x509_class **xc; - const br_x509_pkey *pk; - - xc = ctx->eng.x509ctx; - pk = (*xc)->get_pkey(xc, NULL); - curve = pk->key.ec.curve; - point_src = pk->key.ec.q; - point_len = pk->key.ec.qlen; - } - if ((ctx->eng.iec->supported_curves & ((uint32_t)1 << curve)) == 0) { - return -BR_ERR_INVALID_ALGORITHM; - } - - /* - * We need to generate our key, as a non-zero random value which - * is lower than the curve order, in a "large enough" range. We - * force top bit to 0 and bottom bit to 1, which guarantees that - * the value is in the proper range. - */ - order = ctx->eng.iec->order(curve, &olen); - mask = 0xFF; - while (mask >= order[0]) { - mask >>= 1; - } - br_hmac_drbg_generate(&ctx->eng.rng, key, olen); - key[0] &= mask; - key[olen - 1] |= 0x01; - - /* - * Compute the common ECDH point, whose X coordinate is the - * pre-master secret. - */ - ctx->eng.iec->generator(curve, &glen); - if (glen != point_len) { - return -BR_ERR_INVALID_ALGORITHM; - } - - memcpy(point, point_src, glen); - if (!ctx->eng.iec->mul(point, glen, key, olen, curve)) { - return -BR_ERR_INVALID_ALGORITHM; - } - - /* - * The pre-master secret is the X coordinate. - */ - xoff = ctx->eng.iec->xoff(curve, &xlen); - br_ssl_engine_compute_master(&ctx->eng, prf_id, point + xoff, xlen); - - ctx->eng.iec->mulgen(point, key, olen, curve); - memcpy(ctx->eng.pad, point, glen); - return (int)glen; -} - -/* - * Perform full static ECDH. This occurs only in the context of client - * authentication with certificates: the server uses an EC public key, - * the cipher suite is of type ECDH (not ECDHE), the server requested a - * client certificate and accepts static ECDH, the client has a - * certificate with an EC public key in the same curve, and accepts - * static ECDH as well. - * - * Returned value is 0 on success, -1 on error. - */ -static int -make_pms_static_ecdh(br_ssl_client_context *ctx, int prf_id) -{ - unsigned char point[133]; - size_t point_len; - const br_x509_class **xc; - const br_x509_pkey *pk; - - xc = ctx->eng.x509ctx; - pk = (*xc)->get_pkey(xc, NULL); - point_len = pk->key.ec.qlen; - if (point_len > sizeof point) { - return -1; - } - memcpy(point, pk->key.ec.q, point_len); - if (!(*ctx->client_auth_vtable)->do_keyx( - ctx->client_auth_vtable, point, &point_len)) - { - return -1; - } - br_ssl_engine_compute_master(&ctx->eng, - prf_id, point, point_len); - return 0; -} - -/* - * Compute the client-side signature. This is invoked only when a - * signature-based client authentication was selected. The computed - * signature is in the pad; its length (in bytes) is returned. On - * error, 0 is returned. - */ -static size_t -make_client_sign(br_ssl_client_context *ctx) -{ - size_t hv_len; - - /* - * Compute hash of handshake messages so far. This "cannot" fail - * because the list of supported hash functions provided to the - * client certificate handler was trimmed to include only the - * hash functions that the multi-hasher supports. - */ - if (ctx->hash_id) { - hv_len = br_multihash_out(&ctx->eng.mhash, - ctx->hash_id, ctx->eng.pad); - } else { - br_multihash_out(&ctx->eng.mhash, - br_md5_ID, ctx->eng.pad); - br_multihash_out(&ctx->eng.mhash, - br_sha1_ID, ctx->eng.pad + 16); - hv_len = 36; - } - return (*ctx->client_auth_vtable)->do_sign( - ctx->client_auth_vtable, ctx->hash_id, hv_len, - ctx->eng.pad, sizeof ctx->eng.pad); -} - - - -static const unsigned char t0_datablock[] = { - 0x00, 0x00, 0x0A, 0x00, 0x24, 0x00, 0x2F, 0x01, 0x24, 0x00, 0x35, 0x02, - 0x24, 0x00, 0x3C, 0x01, 0x44, 0x00, 0x3D, 0x02, 0x44, 0x00, 0x9C, 0x03, - 0x04, 0x00, 0x9D, 0x04, 0x05, 0xC0, 0x03, 0x40, 0x24, 0xC0, 0x04, 0x41, - 0x24, 0xC0, 0x05, 0x42, 0x24, 0xC0, 0x08, 0x20, 0x24, 0xC0, 0x09, 0x21, - 0x24, 0xC0, 0x0A, 0x22, 0x24, 0xC0, 0x0D, 0x30, 0x24, 0xC0, 0x0E, 0x31, - 0x24, 0xC0, 0x0F, 0x32, 0x24, 0xC0, 0x12, 0x10, 0x24, 0xC0, 0x13, 0x11, - 0x24, 0xC0, 0x14, 0x12, 0x24, 0xC0, 0x23, 0x21, 0x44, 0xC0, 0x24, 0x22, - 0x55, 0xC0, 0x25, 0x41, 0x44, 0xC0, 0x26, 0x42, 0x55, 0xC0, 0x27, 0x11, - 0x44, 0xC0, 0x28, 0x12, 0x55, 0xC0, 0x29, 0x31, 0x44, 0xC0, 0x2A, 0x32, - 0x55, 0xC0, 0x2B, 0x23, 0x04, 0xC0, 0x2C, 0x24, 0x05, 0xC0, 0x2D, 0x43, - 0x04, 0xC0, 0x2E, 0x44, 0x05, 0xC0, 0x2F, 0x13, 0x04, 0xC0, 0x30, 0x14, - 0x05, 0xC0, 0x31, 0x33, 0x04, 0xC0, 0x32, 0x34, 0x05, 0xC0, 0x9C, 0x06, - 0x04, 0xC0, 0x9D, 0x07, 0x04, 0xC0, 0xA0, 0x08, 0x04, 0xC0, 0xA1, 0x09, - 0x04, 0xC0, 0xAC, 0x26, 0x04, 0xC0, 0xAD, 0x27, 0x04, 0xC0, 0xAE, 0x28, - 0x04, 0xC0, 0xAF, 0x29, 0x04, 0xCC, 0xA8, 0x15, 0x04, 0xCC, 0xA9, 0x25, - 0x04, 0x00, 0x00 -}; - -static const unsigned char t0_codeblock[] = { - 0x00, 0x01, 0x00, 0x0A, 0x00, 0x00, 0x01, 0x00, 0x0D, 0x00, 0x00, 0x01, - 0x00, 0x0E, 0x00, 0x00, 0x01, 0x00, 0x0F, 0x00, 0x00, 0x01, 0x01, 0x08, - 0x00, 0x00, 0x01, 0x01, 0x09, 0x00, 0x00, 0x01, 0x02, 0x08, 0x00, 0x00, - 0x01, 0x02, 0x09, 0x00, 0x00, 0x25, 0x25, 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_BAD_CCS), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_BAD_CIPHER_SUITE), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_BAD_COMPRESSION), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_BAD_FINISHED), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_BAD_FRAGLEN), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_BAD_HANDSHAKE), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_BAD_HELLO_DONE), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_BAD_PARAM), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_BAD_SECRENEG), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_BAD_SNI), 0x00, 0x00, 0x01, T0_INT1(BR_ERR_BAD_VERSION), - 0x00, 0x00, 0x01, T0_INT1(BR_ERR_EXTRA_EXTENSION), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_INVALID_ALGORITHM), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_LIMIT_EXCEEDED), 0x00, 0x00, 0x01, T0_INT1(BR_ERR_OK), - 0x00, 0x00, 0x01, T0_INT1(BR_ERR_OVERSIZED_ID), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_RESUME_MISMATCH), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_UNEXPECTED), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_UNSUPPORTED_VERSION), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_WRONG_KEY_USAGE), 0x00, 0x00, 0x01, - T0_INT2(offsetof(br_ssl_engine_context, action)), 0x00, 0x00, 0x01, - T0_INT2(offsetof(br_ssl_engine_context, alert)), 0x00, 0x00, 0x01, - T0_INT2(offsetof(br_ssl_engine_context, application_data)), 0x00, 0x00, - 0x01, T0_INT2(offsetof(br_ssl_client_context, auth_type)), 0x00, 0x00, - 0x01, - T0_INT2(offsetof(br_ssl_engine_context, session) + offsetof(br_ssl_session_parameters, cipher_suite)), - 0x00, 0x00, 0x01, - T0_INT2(offsetof(br_ssl_engine_context, client_random)), 0x00, 0x00, - 0x01, T0_INT2(offsetof(br_ssl_engine_context, close_received)), 0x00, - 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, ecdhe_curve)), - 0x00, 0x00, 0x01, - T0_INT2(offsetof(br_ssl_engine_context, ecdhe_point)), 0x00, 0x00, - 0x01, T0_INT2(offsetof(br_ssl_engine_context, ecdhe_point_len)), 0x00, - 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, flags)), 0x00, - 0x00, 0x01, T0_INT2(offsetof(br_ssl_client_context, hash_id)), 0x00, - 0x00, 0x01, T0_INT2(offsetof(br_ssl_client_context, hashes)), 0x00, - 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, log_max_frag_len)), - 0x00, 0x00, 0x01, - T0_INT2(offsetof(br_ssl_client_context, min_clienthello_len)), 0x00, - 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, pad)), 0x00, 0x00, - 0x01, T0_INT2(offsetof(br_ssl_engine_context, protocol_names_num)), - 0x00, 0x00, 0x01, - T0_INT2(offsetof(br_ssl_engine_context, record_type_in)), 0x00, 0x00, - 0x01, T0_INT2(offsetof(br_ssl_engine_context, record_type_out)), 0x00, - 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, reneg)), 0x00, - 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, saved_finished)), - 0x00, 0x00, 0x01, - T0_INT2(offsetof(br_ssl_engine_context, selected_protocol)), 0x00, - 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, server_name)), - 0x00, 0x00, 0x01, - T0_INT2(offsetof(br_ssl_engine_context, server_random)), 0x00, 0x00, - 0x01, - T0_INT2(offsetof(br_ssl_engine_context, session) + offsetof(br_ssl_session_parameters, session_id)), - 0x00, 0x00, 0x01, - T0_INT2(offsetof(br_ssl_engine_context, session) + offsetof(br_ssl_session_parameters, session_id_len)), - 0x00, 0x00, 0x01, - T0_INT2(offsetof(br_ssl_engine_context, shutdown_recv)), 0x00, 0x00, - 0x01, T0_INT2(offsetof(br_ssl_engine_context, suites_buf)), 0x00, 0x00, - 0x01, T0_INT2(offsetof(br_ssl_engine_context, suites_num)), 0x00, 0x00, - 0x01, - T0_INT2(offsetof(br_ssl_engine_context, session) + offsetof(br_ssl_session_parameters, version)), - 0x00, 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, version_in)), - 0x00, 0x00, 0x01, - T0_INT2(offsetof(br_ssl_engine_context, version_max)), 0x00, 0x00, - 0x01, T0_INT2(offsetof(br_ssl_engine_context, version_min)), 0x00, - 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, version_out)), - 0x00, 0x00, 0x09, 0x26, 0x58, 0x06, 0x02, 0x68, 0x28, 0x00, 0x00, 0x06, - 0x08, 0x2C, 0x0E, 0x05, 0x02, 0x71, 0x28, 0x04, 0x01, 0x3C, 0x00, 0x00, - 0x01, 0x01, 0x00, 0x01, 0x03, 0x00, 0x99, 0x26, 0x5E, 0x44, 0x9D, 0x26, - 0x05, 0x04, 0x60, 0x01, 0x00, 0x00, 0x02, 0x00, 0x0E, 0x06, 0x02, 0x9D, - 0x00, 0x5E, 0x04, 0x6B, 0x00, 0x06, 0x02, 0x68, 0x28, 0x00, 0x00, 0x26, - 0x89, 0x44, 0x05, 0x03, 0x01, 0x0C, 0x08, 0x44, 0x79, 0x2C, 0xAB, 0x1C, - 0x84, 0x01, 0x0C, 0x31, 0x00, 0x00, 0x26, 0x1F, 0x01, 0x08, 0x0B, 0x44, - 0x5C, 0x1F, 0x08, 0x00, 0x01, 0x03, 0x00, 0x77, 0x2E, 0x02, 0x00, 0x36, - 0x17, 0x01, 0x01, 0x0B, 0x77, 0x3E, 0x29, 0x1A, 0x36, 0x06, 0x07, 0x02, - 0x00, 0xCF, 0x03, 0x00, 0x04, 0x75, 0x01, 0x00, 0xC5, 0x02, 0x00, 0x26, - 0x1A, 0x17, 0x06, 0x02, 0x6F, 0x28, 0xCF, 0x04, 0x76, 0x01, 0x01, 0x00, - 0x77, 0x3E, 0x01, 0x16, 0x87, 0x3E, 0x01, 0x00, 0x8A, 0x3C, 0x34, 0xD5, - 0x29, 0xB4, 0x06, 0x09, 0x01, 0x7F, 0xAF, 0x01, 0x7F, 0xD2, 0x04, 0x80, - 0x53, 0xB1, 0x79, 0x2C, 0xA1, 0x01, T0_INT1(BR_KEYTYPE_SIGN), 0x17, - 0x06, 0x01, 0xB5, 0xB8, 0x26, 0x01, 0x0D, 0x0E, 0x06, 0x07, 0x25, 0xB7, - 0xB8, 0x01, 0x7F, 0x04, 0x02, 0x01, 0x00, 0x03, 0x00, 0x01, 0x0E, 0x0E, - 0x05, 0x02, 0x72, 0x28, 0x06, 0x02, 0x67, 0x28, 0x33, 0x06, 0x02, 0x72, - 0x28, 0x02, 0x00, 0x06, 0x1C, 0xD3, 0x80, 0x2E, 0x01, 0x81, 0x7F, 0x0E, - 0x06, 0x0D, 0x25, 0x01, 0x10, 0xDE, 0x01, 0x00, 0xDD, 0x79, 0x2C, 0xAB, - 0x24, 0x04, 0x04, 0xD6, 0x06, 0x01, 0xD4, 0x04, 0x01, 0xD6, 0x01, 0x7F, - 0xD2, 0x01, 0x7F, 0xAF, 0x01, 0x01, 0x77, 0x3E, 0x01, 0x17, 0x87, 0x3E, - 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x9A, 0x01, 0x0C, 0x11, 0x01, 0x00, - 0x38, 0x0E, 0x06, 0x05, 0x25, 0x01, - T0_INT1(BR_KEYTYPE_RSA | BR_KEYTYPE_KEYX), 0x04, 0x30, 0x01, 0x01, - 0x38, 0x0E, 0x06, 0x05, 0x25, 0x01, - T0_INT1(BR_KEYTYPE_RSA | BR_KEYTYPE_SIGN), 0x04, 0x25, 0x01, 0x02, - 0x38, 0x0E, 0x06, 0x05, 0x25, 0x01, - T0_INT1(BR_KEYTYPE_EC | BR_KEYTYPE_SIGN), 0x04, 0x1A, 0x01, 0x03, - 0x38, 0x0E, 0x06, 0x05, 0x25, 0x01, - T0_INT1(BR_KEYTYPE_EC | BR_KEYTYPE_KEYX), 0x04, 0x0F, 0x01, 0x04, - 0x38, 0x0E, 0x06, 0x05, 0x25, 0x01, - T0_INT1(BR_KEYTYPE_EC | BR_KEYTYPE_KEYX), 0x04, 0x04, 0x01, 0x00, - 0x44, 0x25, 0x00, 0x00, 0x82, 0x2E, 0x01, 0x0E, 0x0E, 0x06, 0x04, 0x01, - 0x00, 0x04, 0x02, 0x01, 0x05, 0x00, 0x00, 0x40, 0x06, 0x04, 0x01, 0x06, - 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x88, 0x2E, 0x26, 0x06, 0x08, 0x01, - 0x01, 0x09, 0x01, 0x11, 0x07, 0x04, 0x03, 0x25, 0x01, 0x05, 0x00, 0x01, - 0x41, 0x03, 0x00, 0x25, 0x01, 0x00, 0x43, 0x06, 0x03, 0x02, 0x00, 0x08, - 0x42, 0x06, 0x03, 0x02, 0x00, 0x08, 0x26, 0x06, 0x06, 0x01, 0x01, 0x0B, - 0x01, 0x06, 0x08, 0x00, 0x00, 0x8B, 0x3F, 0x26, 0x06, 0x03, 0x01, 0x09, - 0x08, 0x00, 0x01, 0x40, 0x26, 0x06, 0x1E, 0x01, 0x00, 0x03, 0x00, 0x26, - 0x06, 0x0E, 0x26, 0x01, 0x01, 0x17, 0x02, 0x00, 0x08, 0x03, 0x00, 0x01, - 0x01, 0x11, 0x04, 0x6F, 0x25, 0x02, 0x00, 0x01, 0x01, 0x0B, 0x01, 0x06, - 0x08, 0x00, 0x00, 0x7F, 0x2D, 0x44, 0x11, 0x01, 0x01, 0x17, 0x35, 0x00, - 0x00, 0x9F, 0xCE, 0x26, 0x01, 0x07, 0x17, 0x01, 0x00, 0x38, 0x0E, 0x06, - 0x09, 0x25, 0x01, 0x10, 0x17, 0x06, 0x01, 0x9F, 0x04, 0x35, 0x01, 0x01, - 0x38, 0x0E, 0x06, 0x2C, 0x25, 0x25, 0x01, 0x00, 0x77, 0x3E, 0xB3, 0x88, - 0x2E, 0x01, 0x01, 0x0E, 0x01, 0x01, 0xA8, 0x37, 0x06, 0x17, 0x29, 0x1A, - 0x36, 0x06, 0x04, 0xCE, 0x25, 0x04, 0x78, 0x01, 0x80, 0x64, 0xC5, 0x01, - 0x01, 0x77, 0x3E, 0x01, 0x17, 0x87, 0x3E, 0x04, 0x01, 0x9F, 0x04, 0x03, - 0x72, 0x28, 0x25, 0x04, 0xFF, 0x34, 0x01, 0x26, 0x03, 0x00, 0x09, 0x26, - 0x58, 0x06, 0x02, 0x68, 0x28, 0x02, 0x00, 0x00, 0x00, 0x9A, 0x01, 0x0F, - 0x17, 0x00, 0x00, 0x76, 0x2E, 0x01, 0x00, 0x38, 0x0E, 0x06, 0x10, 0x25, - 0x26, 0x01, 0x01, 0x0D, 0x06, 0x03, 0x25, 0x01, 0x02, 0x76, 0x3E, 0x01, - 0x00, 0x04, 0x21, 0x01, 0x01, 0x38, 0x0E, 0x06, 0x14, 0x25, 0x01, 0x00, - 0x76, 0x3E, 0x26, 0x01, 0x80, 0x64, 0x0E, 0x06, 0x05, 0x01, 0x82, 0x00, - 0x08, 0x28, 0x5A, 0x04, 0x07, 0x25, 0x01, 0x82, 0x00, 0x08, 0x28, 0x25, - 0x00, 0x00, 0x01, 0x00, 0x2F, 0x06, 0x05, 0x3A, 0xAC, 0x37, 0x04, 0x78, - 0x26, 0x06, 0x04, 0x01, 0x01, 0x8F, 0x3E, 0x00, 0x01, 0xBF, 0xAA, 0xBF, - 0xAA, 0xC1, 0x84, 0x44, 0x26, 0x03, 0x00, 0xB6, 0x9B, 0x9B, 0x02, 0x00, - 0x4D, 0x26, 0x58, 0x06, 0x0A, 0x01, 0x03, 0xA8, 0x06, 0x02, 0x72, 0x28, - 0x25, 0x04, 0x03, 0x5C, 0x8A, 0x3C, 0x00, 0x00, 0x2F, 0x06, 0x0B, 0x86, - 0x2E, 0x01, 0x14, 0x0D, 0x06, 0x02, 0x72, 0x28, 0x04, 0x11, 0xCE, 0x01, - 0x07, 0x17, 0x26, 0x01, 0x02, 0x0D, 0x06, 0x06, 0x06, 0x02, 0x72, 0x28, - 0x04, 0x70, 0x25, 0xC2, 0x01, 0x01, 0x0D, 0x33, 0x37, 0x06, 0x02, 0x61, - 0x28, 0x26, 0x01, 0x01, 0xC8, 0x36, 0xB2, 0x00, 0x01, 0xB8, 0x01, 0x0B, - 0x0E, 0x05, 0x02, 0x72, 0x28, 0x26, 0x01, 0x03, 0x0E, 0x06, 0x08, 0xC0, - 0x06, 0x02, 0x68, 0x28, 0x44, 0x25, 0x00, 0x44, 0x57, 0xC0, 0xAA, 0x26, - 0x06, 0x23, 0xC0, 0xAA, 0x26, 0x56, 0x26, 0x06, 0x18, 0x26, 0x01, 0x82, - 0x00, 0x0F, 0x06, 0x05, 0x01, 0x82, 0x00, 0x04, 0x01, 0x26, 0x03, 0x00, - 0x84, 0x02, 0x00, 0xB6, 0x02, 0x00, 0x53, 0x04, 0x65, 0x9B, 0x54, 0x04, - 0x5A, 0x9B, 0x9B, 0x55, 0x26, 0x06, 0x02, 0x35, 0x00, 0x25, 0x2B, 0x00, - 0x00, 0x79, 0x2C, 0xA1, 0x01, 0x7F, 0xB0, 0x26, 0x58, 0x06, 0x02, 0x35, - 0x28, 0x26, 0x05, 0x02, 0x72, 0x28, 0x38, 0x17, 0x0D, 0x06, 0x02, 0x74, - 0x28, 0x3B, 0x00, 0x00, 0x9C, 0xB8, 0x01, 0x14, 0x0D, 0x06, 0x02, 0x72, - 0x28, 0x84, 0x01, 0x0C, 0x08, 0x01, 0x0C, 0xB6, 0x9B, 0x84, 0x26, 0x01, - 0x0C, 0x08, 0x01, 0x0C, 0x30, 0x05, 0x02, 0x64, 0x28, 0x00, 0x00, 0xB9, - 0x06, 0x02, 0x72, 0x28, 0x06, 0x02, 0x66, 0x28, 0x00, 0x0A, 0xB8, 0x01, - 0x02, 0x0E, 0x05, 0x02, 0x72, 0x28, 0xBF, 0x03, 0x00, 0x02, 0x00, 0x95, - 0x2C, 0x0A, 0x02, 0x00, 0x94, 0x2C, 0x0F, 0x37, 0x06, 0x02, 0x73, 0x28, - 0x02, 0x00, 0x93, 0x2C, 0x0D, 0x06, 0x02, 0x6B, 0x28, 0x02, 0x00, 0x96, - 0x3C, 0x8C, 0x01, 0x20, 0xB6, 0x01, 0x00, 0x03, 0x01, 0xC1, 0x03, 0x02, - 0x02, 0x02, 0x01, 0x20, 0x0F, 0x06, 0x02, 0x70, 0x28, 0x84, 0x02, 0x02, - 0xB6, 0x02, 0x02, 0x8E, 0x2E, 0x0E, 0x02, 0x02, 0x01, 0x00, 0x0F, 0x17, - 0x06, 0x0B, 0x8D, 0x84, 0x02, 0x02, 0x30, 0x06, 0x04, 0x01, 0x7F, 0x03, - 0x01, 0x8D, 0x84, 0x02, 0x02, 0x31, 0x02, 0x02, 0x8E, 0x3E, 0x02, 0x00, - 0x92, 0x02, 0x01, 0x98, 0xBF, 0x26, 0xC3, 0x58, 0x06, 0x02, 0x62, 0x28, - 0x26, 0xCD, 0x02, 0x00, 0x01, 0x86, 0x03, 0x0A, 0x17, 0x06, 0x02, 0x62, - 0x28, 0x79, 0x02, 0x01, 0x98, 0xC1, 0x06, 0x02, 0x63, 0x28, 0x26, 0x06, - 0x81, 0x47, 0xBF, 0xAA, 0xA6, 0x03, 0x03, 0xA4, 0x03, 0x04, 0xA2, 0x03, - 0x05, 0xA5, 0x03, 0x06, 0xA7, 0x03, 0x07, 0xA3, 0x03, 0x08, 0x27, 0x03, - 0x09, 0x26, 0x06, 0x81, 0x18, 0xBF, 0x01, 0x00, 0x38, 0x0E, 0x06, 0x0F, - 0x25, 0x02, 0x03, 0x05, 0x02, 0x6C, 0x28, 0x01, 0x00, 0x03, 0x03, 0xBE, - 0x04, 0x80, 0x7F, 0x01, 0x01, 0x38, 0x0E, 0x06, 0x0F, 0x25, 0x02, 0x05, - 0x05, 0x02, 0x6C, 0x28, 0x01, 0x00, 0x03, 0x05, 0xBC, 0x04, 0x80, 0x6A, - 0x01, 0x83, 0xFE, 0x01, 0x38, 0x0E, 0x06, 0x0F, 0x25, 0x02, 0x04, 0x05, - 0x02, 0x6C, 0x28, 0x01, 0x00, 0x03, 0x04, 0xBD, 0x04, 0x80, 0x53, 0x01, - 0x0D, 0x38, 0x0E, 0x06, 0x0E, 0x25, 0x02, 0x06, 0x05, 0x02, 0x6C, 0x28, - 0x01, 0x00, 0x03, 0x06, 0xBA, 0x04, 0x3F, 0x01, 0x0A, 0x38, 0x0E, 0x06, - 0x0E, 0x25, 0x02, 0x07, 0x05, 0x02, 0x6C, 0x28, 0x01, 0x00, 0x03, 0x07, - 0xBA, 0x04, 0x2B, 0x01, 0x0B, 0x38, 0x0E, 0x06, 0x0E, 0x25, 0x02, 0x08, - 0x05, 0x02, 0x6C, 0x28, 0x01, 0x00, 0x03, 0x08, 0xBA, 0x04, 0x17, 0x01, - 0x10, 0x38, 0x0E, 0x06, 0x0E, 0x25, 0x02, 0x09, 0x05, 0x02, 0x6C, 0x28, - 0x01, 0x00, 0x03, 0x09, 0xAE, 0x04, 0x03, 0x6C, 0x28, 0x25, 0x04, 0xFE, - 0x64, 0x02, 0x04, 0x06, 0x0D, 0x02, 0x04, 0x01, 0x05, 0x0F, 0x06, 0x02, - 0x69, 0x28, 0x01, 0x01, 0x88, 0x3E, 0x9B, 0x04, 0x0C, 0xA4, 0x01, 0x05, - 0x0F, 0x06, 0x02, 0x69, 0x28, 0x01, 0x01, 0x88, 0x3E, 0x9B, 0x02, 0x01, - 0x00, 0x04, 0xB8, 0x01, 0x0C, 0x0E, 0x05, 0x02, 0x72, 0x28, 0xC1, 0x01, - 0x03, 0x0E, 0x05, 0x02, 0x6D, 0x28, 0xBF, 0x26, 0x7C, 0x3E, 0x26, 0x01, - 0x20, 0x10, 0x06, 0x02, 0x6D, 0x28, 0x40, 0x44, 0x11, 0x01, 0x01, 0x17, - 0x05, 0x02, 0x6D, 0x28, 0xC1, 0x26, 0x01, 0x81, 0x05, 0x0F, 0x06, 0x02, - 0x6D, 0x28, 0x26, 0x7E, 0x3E, 0x7D, 0x44, 0xB6, 0x92, 0x2C, 0x01, 0x86, - 0x03, 0x10, 0x03, 0x00, 0x79, 0x2C, 0xCB, 0x03, 0x01, 0x01, 0x02, 0x03, - 0x02, 0x02, 0x00, 0x06, 0x21, 0xC1, 0x26, 0x26, 0x01, 0x02, 0x0A, 0x44, - 0x01, 0x06, 0x0F, 0x37, 0x06, 0x02, 0x6D, 0x28, 0x03, 0x02, 0xC1, 0x02, - 0x01, 0x01, 0x01, 0x0B, 0x01, 0x03, 0x08, 0x0E, 0x05, 0x02, 0x6D, 0x28, - 0x04, 0x08, 0x02, 0x01, 0x06, 0x04, 0x01, 0x00, 0x03, 0x02, 0xBF, 0x26, - 0x03, 0x03, 0x26, 0x01, 0x84, 0x00, 0x0F, 0x06, 0x02, 0x6E, 0x28, 0x84, - 0x44, 0xB6, 0x02, 0x02, 0x02, 0x01, 0x02, 0x03, 0x50, 0x26, 0x06, 0x01, - 0x28, 0x25, 0x9B, 0x00, 0x02, 0x03, 0x00, 0x03, 0x01, 0x02, 0x00, 0x97, - 0x02, 0x01, 0x02, 0x00, 0x39, 0x26, 0x01, 0x00, 0x0E, 0x06, 0x02, 0x60, - 0x00, 0xD0, 0x04, 0x74, 0x02, 0x01, 0x00, 0x03, 0x00, 0xC1, 0xAA, 0x26, - 0x06, 0x80, 0x43, 0xC1, 0x01, 0x01, 0x38, 0x0E, 0x06, 0x06, 0x25, 0x01, - 0x81, 0x7F, 0x04, 0x2E, 0x01, 0x80, 0x40, 0x38, 0x0E, 0x06, 0x07, 0x25, - 0x01, 0x83, 0xFE, 0x00, 0x04, 0x20, 0x01, 0x80, 0x41, 0x38, 0x0E, 0x06, - 0x07, 0x25, 0x01, 0x84, 0x80, 0x00, 0x04, 0x12, 0x01, 0x80, 0x42, 0x38, - 0x0E, 0x06, 0x07, 0x25, 0x01, 0x88, 0x80, 0x00, 0x04, 0x04, 0x01, 0x00, - 0x44, 0x25, 0x02, 0x00, 0x37, 0x03, 0x00, 0x04, 0xFF, 0x39, 0x9B, 0x79, - 0x2C, 0xC9, 0x05, 0x09, 0x02, 0x00, 0x01, 0x83, 0xFF, 0x7F, 0x17, 0x03, - 0x00, 0x92, 0x2C, 0x01, 0x86, 0x03, 0x10, 0x06, 0x3A, 0xBB, 0x26, 0x81, - 0x3D, 0x41, 0x25, 0x26, 0x01, 0x08, 0x0B, 0x37, 0x01, 0x8C, 0x80, 0x00, - 0x37, 0x17, 0x02, 0x00, 0x17, 0x02, 0x00, 0x01, 0x8C, 0x80, 0x00, 0x17, - 0x06, 0x19, 0x26, 0x01, 0x81, 0x7F, 0x17, 0x06, 0x05, 0x01, 0x84, 0x80, - 0x00, 0x37, 0x26, 0x01, 0x83, 0xFE, 0x00, 0x17, 0x06, 0x05, 0x01, 0x88, - 0x80, 0x00, 0x37, 0x03, 0x00, 0x04, 0x09, 0x02, 0x00, 0x01, 0x8C, 0x88, - 0x01, 0x17, 0x03, 0x00, 0x16, 0xBF, 0xAA, 0x26, 0x06, 0x23, 0xBF, 0xAA, - 0x26, 0x15, 0x26, 0x06, 0x18, 0x26, 0x01, 0x82, 0x00, 0x0F, 0x06, 0x05, - 0x01, 0x82, 0x00, 0x04, 0x01, 0x26, 0x03, 0x01, 0x84, 0x02, 0x01, 0xB6, - 0x02, 0x01, 0x12, 0x04, 0x65, 0x9B, 0x13, 0x04, 0x5A, 0x9B, 0x14, 0x9B, - 0x02, 0x00, 0x2A, 0x00, 0x00, 0xB9, 0x26, 0x5A, 0x06, 0x07, 0x25, 0x06, - 0x02, 0x66, 0x28, 0x04, 0x74, 0x00, 0x00, 0xC2, 0x01, 0x03, 0xC0, 0x44, - 0x25, 0x44, 0x00, 0x00, 0xBF, 0xC6, 0x00, 0x03, 0x01, 0x00, 0x03, 0x00, - 0xBF, 0xAA, 0x26, 0x06, 0x80, 0x50, 0xC1, 0x03, 0x01, 0xC1, 0x03, 0x02, - 0x02, 0x01, 0x01, 0x08, 0x0E, 0x06, 0x16, 0x02, 0x02, 0x01, 0x0F, 0x0C, - 0x06, 0x0D, 0x01, 0x01, 0x02, 0x02, 0x01, 0x10, 0x08, 0x0B, 0x02, 0x00, - 0x37, 0x03, 0x00, 0x04, 0x2A, 0x02, 0x01, 0x01, 0x02, 0x10, 0x02, 0x01, - 0x01, 0x06, 0x0C, 0x17, 0x02, 0x02, 0x01, 0x01, 0x0E, 0x02, 0x02, 0x01, - 0x03, 0x0E, 0x37, 0x17, 0x06, 0x11, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, - 0x5D, 0x01, 0x02, 0x0B, 0x02, 0x01, 0x08, 0x0B, 0x37, 0x03, 0x00, 0x04, - 0xFF, 0x2C, 0x9B, 0x02, 0x00, 0x00, 0x00, 0xBF, 0x01, 0x01, 0x0E, 0x05, - 0x02, 0x65, 0x28, 0xC1, 0x01, 0x08, 0x08, 0x82, 0x2E, 0x0E, 0x05, 0x02, - 0x65, 0x28, 0x00, 0x00, 0xBF, 0x88, 0x2E, 0x05, 0x15, 0x01, 0x01, 0x0E, - 0x05, 0x02, 0x69, 0x28, 0xC1, 0x01, 0x00, 0x0E, 0x05, 0x02, 0x69, 0x28, - 0x01, 0x02, 0x88, 0x3E, 0x04, 0x1C, 0x01, 0x19, 0x0E, 0x05, 0x02, 0x69, - 0x28, 0xC1, 0x01, 0x18, 0x0E, 0x05, 0x02, 0x69, 0x28, 0x84, 0x01, 0x18, - 0xB6, 0x89, 0x84, 0x01, 0x18, 0x30, 0x05, 0x02, 0x69, 0x28, 0x00, 0x00, - 0xBF, 0x06, 0x02, 0x6A, 0x28, 0x00, 0x00, 0x01, 0x02, 0x97, 0xC2, 0x01, - 0x08, 0x0B, 0xC2, 0x08, 0x00, 0x00, 0x01, 0x03, 0x97, 0xC2, 0x01, 0x08, - 0x0B, 0xC2, 0x08, 0x01, 0x08, 0x0B, 0xC2, 0x08, 0x00, 0x00, 0x01, 0x01, - 0x97, 0xC2, 0x00, 0x00, 0x3A, 0x26, 0x58, 0x05, 0x01, 0x00, 0x25, 0xD0, - 0x04, 0x76, 0x02, 0x03, 0x00, 0x91, 0x2E, 0x03, 0x01, 0x01, 0x00, 0x26, - 0x02, 0x01, 0x0A, 0x06, 0x10, 0x26, 0x01, 0x01, 0x0B, 0x90, 0x08, 0x2C, - 0x02, 0x00, 0x0E, 0x06, 0x01, 0x00, 0x5C, 0x04, 0x6A, 0x25, 0x01, 0x7F, - 0x00, 0x00, 0x01, 0x15, 0x87, 0x3E, 0x44, 0x52, 0x25, 0x52, 0x25, 0x29, - 0x00, 0x00, 0x01, 0x01, 0x44, 0xC4, 0x00, 0x00, 0x44, 0x38, 0x97, 0x44, - 0x26, 0x06, 0x05, 0xC2, 0x25, 0x5D, 0x04, 0x78, 0x25, 0x00, 0x00, 0x26, - 0x01, 0x81, 0xAC, 0x00, 0x0E, 0x06, 0x04, 0x25, 0x01, 0x7F, 0x00, 0x9A, - 0x59, 0x00, 0x02, 0x03, 0x00, 0x79, 0x2C, 0x9A, 0x03, 0x01, 0x02, 0x01, - 0x01, 0x0F, 0x17, 0x02, 0x01, 0x01, 0x04, 0x11, 0x01, 0x0F, 0x17, 0x02, - 0x01, 0x01, 0x08, 0x11, 0x01, 0x0F, 0x17, 0x01, 0x00, 0x38, 0x0E, 0x06, - 0x10, 0x25, 0x01, 0x00, 0x01, 0x18, 0x02, 0x00, 0x06, 0x03, 0x49, 0x04, - 0x01, 0x4A, 0x04, 0x81, 0x0D, 0x01, 0x01, 0x38, 0x0E, 0x06, 0x10, 0x25, - 0x01, 0x01, 0x01, 0x10, 0x02, 0x00, 0x06, 0x03, 0x49, 0x04, 0x01, 0x4A, - 0x04, 0x80, 0x77, 0x01, 0x02, 0x38, 0x0E, 0x06, 0x10, 0x25, 0x01, 0x01, - 0x01, 0x20, 0x02, 0x00, 0x06, 0x03, 0x49, 0x04, 0x01, 0x4A, 0x04, 0x80, - 0x61, 0x01, 0x03, 0x38, 0x0E, 0x06, 0x0F, 0x25, 0x25, 0x01, 0x10, 0x02, - 0x00, 0x06, 0x03, 0x47, 0x04, 0x01, 0x48, 0x04, 0x80, 0x4C, 0x01, 0x04, - 0x38, 0x0E, 0x06, 0x0E, 0x25, 0x25, 0x01, 0x20, 0x02, 0x00, 0x06, 0x03, - 0x47, 0x04, 0x01, 0x48, 0x04, 0x38, 0x01, 0x05, 0x38, 0x0E, 0x06, 0x0C, - 0x25, 0x25, 0x02, 0x00, 0x06, 0x03, 0x4B, 0x04, 0x01, 0x4C, 0x04, 0x26, - 0x26, 0x01, 0x09, 0x0F, 0x06, 0x02, 0x68, 0x28, 0x44, 0x25, 0x26, 0x01, - 0x01, 0x17, 0x01, 0x04, 0x0B, 0x01, 0x10, 0x08, 0x44, 0x01, 0x08, 0x17, - 0x01, 0x10, 0x44, 0x09, 0x02, 0x00, 0x06, 0x03, 0x45, 0x04, 0x01, 0x46, - 0x00, 0x25, 0x00, 0x00, 0x9A, 0x01, 0x0C, 0x11, 0x01, 0x02, 0x0F, 0x00, - 0x00, 0x9A, 0x01, 0x0C, 0x11, 0x26, 0x5B, 0x44, 0x01, 0x03, 0x0A, 0x17, - 0x00, 0x00, 0x9A, 0x01, 0x0C, 0x11, 0x01, 0x01, 0x0E, 0x00, 0x00, 0x9A, - 0x01, 0x0C, 0x11, 0x5A, 0x00, 0x00, 0x9A, 0x01, 0x81, 0x70, 0x17, 0x01, - 0x20, 0x0D, 0x00, 0x00, 0x1B, 0x01, 0x00, 0x75, 0x2E, 0x26, 0x06, 0x22, - 0x01, 0x01, 0x38, 0x0E, 0x06, 0x06, 0x25, 0x01, 0x00, 0x9E, 0x04, 0x14, - 0x01, 0x02, 0x38, 0x0E, 0x06, 0x0D, 0x25, 0x77, 0x2E, 0x01, 0x01, 0x0E, - 0x06, 0x03, 0x01, 0x10, 0x37, 0x04, 0x01, 0x25, 0x04, 0x01, 0x25, 0x7B, - 0x2E, 0x05, 0x33, 0x2F, 0x06, 0x30, 0x86, 0x2E, 0x01, 0x14, 0x38, 0x0E, - 0x06, 0x06, 0x25, 0x01, 0x02, 0x37, 0x04, 0x22, 0x01, 0x15, 0x38, 0x0E, - 0x06, 0x09, 0x25, 0xAD, 0x06, 0x03, 0x01, 0x7F, 0x9E, 0x04, 0x13, 0x01, - 0x16, 0x38, 0x0E, 0x06, 0x06, 0x25, 0x01, 0x01, 0x37, 0x04, 0x07, 0x25, - 0x01, 0x04, 0x37, 0x01, 0x00, 0x25, 0x1A, 0x06, 0x03, 0x01, 0x08, 0x37, - 0x00, 0x00, 0x1B, 0x26, 0x05, 0x13, 0x2F, 0x06, 0x10, 0x86, 0x2E, 0x01, - 0x15, 0x0E, 0x06, 0x08, 0x25, 0xAD, 0x01, 0x00, 0x77, 0x3E, 0x04, 0x01, - 0x20, 0x00, 0x00, 0xCE, 0x01, 0x07, 0x17, 0x01, 0x01, 0x0F, 0x06, 0x02, - 0x72, 0x28, 0x00, 0x01, 0x03, 0x00, 0x29, 0x1A, 0x06, 0x05, 0x02, 0x00, - 0x87, 0x3E, 0x00, 0xCE, 0x25, 0x04, 0x74, 0x00, 0x01, 0x14, 0xD1, 0x01, - 0x01, 0xDE, 0x29, 0x26, 0x01, 0x00, 0xC8, 0x01, 0x16, 0xD1, 0xD7, 0x29, - 0x00, 0x00, 0x01, 0x0B, 0xDE, 0x4E, 0x26, 0x26, 0x01, 0x03, 0x08, 0xDD, - 0xDD, 0x18, 0x26, 0x58, 0x06, 0x02, 0x25, 0x00, 0xDD, 0x1D, 0x26, 0x06, - 0x05, 0x84, 0x44, 0xD8, 0x04, 0x77, 0x25, 0x04, 0x6C, 0x00, 0x21, 0x01, - 0x0F, 0xDE, 0x26, 0x92, 0x2C, 0x01, 0x86, 0x03, 0x10, 0x06, 0x0C, 0x01, - 0x04, 0x08, 0xDD, 0x80, 0x2E, 0xDE, 0x78, 0x2E, 0xDE, 0x04, 0x02, 0x5E, - 0xDD, 0x26, 0xDC, 0x84, 0x44, 0xD8, 0x00, 0x02, 0xA4, 0xA6, 0x08, 0xA2, - 0x08, 0xA5, 0x08, 0xA7, 0x08, 0xA3, 0x08, 0x27, 0x08, 0x03, 0x00, 0x01, - 0x01, 0xDE, 0x01, 0x27, 0x8E, 0x2E, 0x08, 0x91, 0x2E, 0x01, 0x01, 0x0B, - 0x08, 0x02, 0x00, 0x06, 0x04, 0x5E, 0x02, 0x00, 0x08, 0x83, 0x2C, 0x38, - 0x09, 0x26, 0x5B, 0x06, 0x24, 0x02, 0x00, 0x05, 0x04, 0x44, 0x5E, 0x44, - 0x5F, 0x01, 0x04, 0x09, 0x26, 0x58, 0x06, 0x03, 0x25, 0x01, 0x00, 0x26, - 0x01, 0x04, 0x08, 0x02, 0x00, 0x08, 0x03, 0x00, 0x44, 0x01, 0x04, 0x08, - 0x38, 0x08, 0x44, 0x04, 0x03, 0x25, 0x01, 0x7F, 0x03, 0x01, 0xDD, 0x94, - 0x2C, 0xDC, 0x7A, 0x01, 0x04, 0x19, 0x7A, 0x01, 0x04, 0x08, 0x01, 0x1C, - 0x32, 0x7A, 0x01, 0x20, 0xD8, 0x8D, 0x8E, 0x2E, 0xDA, 0x91, 0x2E, 0x26, - 0x01, 0x01, 0x0B, 0xDC, 0x90, 0x44, 0x26, 0x06, 0x0F, 0x5D, 0x38, 0x2C, - 0x26, 0xC7, 0x05, 0x02, 0x62, 0x28, 0xDC, 0x44, 0x5E, 0x44, 0x04, 0x6E, - 0x60, 0x01, 0x01, 0xDE, 0x01, 0x00, 0xDE, 0x02, 0x00, 0x06, 0x81, 0x5A, - 0x02, 0x00, 0xDC, 0xA4, 0x06, 0x0E, 0x01, 0x83, 0xFE, 0x01, 0xDC, 0x89, - 0xA4, 0x01, 0x04, 0x09, 0x26, 0xDC, 0x5D, 0xDA, 0xA6, 0x06, 0x16, 0x01, - 0x00, 0xDC, 0x8B, 0xA6, 0x01, 0x04, 0x09, 0x26, 0xDC, 0x01, 0x02, 0x09, - 0x26, 0xDC, 0x01, 0x00, 0xDE, 0x01, 0x03, 0x09, 0xD9, 0xA2, 0x06, 0x0C, - 0x01, 0x01, 0xDC, 0x01, 0x01, 0xDC, 0x82, 0x2E, 0x01, 0x08, 0x09, 0xDE, - 0xA5, 0x06, 0x19, 0x01, 0x0D, 0xDC, 0xA5, 0x01, 0x04, 0x09, 0x26, 0xDC, - 0x01, 0x02, 0x09, 0xDC, 0x42, 0x06, 0x03, 0x01, 0x03, 0xDB, 0x43, 0x06, - 0x03, 0x01, 0x01, 0xDB, 0xA7, 0x26, 0x06, 0x36, 0x01, 0x0A, 0xDC, 0x01, - 0x04, 0x09, 0x26, 0xDC, 0x5F, 0xDC, 0x40, 0x01, 0x00, 0x26, 0x01, 0x82, - 0x80, 0x80, 0x80, 0x00, 0x17, 0x06, 0x0A, 0x01, 0xFD, 0xFF, 0xFF, 0xFF, - 0x7F, 0x17, 0x01, 0x1D, 0xDC, 0x26, 0x01, 0x20, 0x0A, 0x06, 0x0C, 0xA0, - 0x11, 0x01, 0x01, 0x17, 0x06, 0x02, 0x26, 0xDC, 0x5C, 0x04, 0x6E, 0x60, - 0x04, 0x01, 0x25, 0xA3, 0x06, 0x0A, 0x01, 0x0B, 0xDC, 0x01, 0x02, 0xDC, - 0x01, 0x82, 0x00, 0xDC, 0x27, 0x26, 0x06, 0x1F, 0x01, 0x10, 0xDC, 0x01, - 0x04, 0x09, 0x26, 0xDC, 0x5F, 0xDC, 0x85, 0x2C, 0x01, 0x00, 0xA0, 0x0F, - 0x06, 0x0A, 0x26, 0x1E, 0x26, 0xDE, 0x84, 0x44, 0xD8, 0x5C, 0x04, 0x72, - 0x60, 0x04, 0x01, 0x25, 0x02, 0x01, 0x58, 0x05, 0x11, 0x01, 0x15, 0xDC, - 0x02, 0x01, 0x26, 0xDC, 0x26, 0x06, 0x06, 0x5D, 0x01, 0x00, 0xDE, 0x04, - 0x77, 0x25, 0x00, 0x00, 0x01, 0x10, 0xDE, 0x79, 0x2C, 0x26, 0xCC, 0x06, - 0x0C, 0xAB, 0x23, 0x26, 0x5E, 0xDD, 0x26, 0xDC, 0x84, 0x44, 0xD8, 0x04, - 0x0D, 0x26, 0xCA, 0x44, 0xAB, 0x22, 0x26, 0x5C, 0xDD, 0x26, 0xDE, 0x84, - 0x44, 0xD8, 0x00, 0x00, 0x9C, 0x01, 0x14, 0xDE, 0x01, 0x0C, 0xDD, 0x84, - 0x01, 0x0C, 0xD8, 0x00, 0x00, 0x51, 0x26, 0x01, 0x00, 0x0E, 0x06, 0x02, - 0x60, 0x00, 0xCE, 0x25, 0x04, 0x73, 0x00, 0x26, 0xDC, 0xD8, 0x00, 0x00, - 0x26, 0xDE, 0xD8, 0x00, 0x01, 0x03, 0x00, 0x41, 0x25, 0x26, 0x01, 0x10, - 0x17, 0x06, 0x06, 0x01, 0x04, 0xDE, 0x02, 0x00, 0xDE, 0x26, 0x01, 0x08, - 0x17, 0x06, 0x06, 0x01, 0x03, 0xDE, 0x02, 0x00, 0xDE, 0x26, 0x01, 0x20, - 0x17, 0x06, 0x06, 0x01, 0x05, 0xDE, 0x02, 0x00, 0xDE, 0x26, 0x01, 0x80, - 0x40, 0x17, 0x06, 0x06, 0x01, 0x06, 0xDE, 0x02, 0x00, 0xDE, 0x01, 0x04, - 0x17, 0x06, 0x06, 0x01, 0x02, 0xDE, 0x02, 0x00, 0xDE, 0x00, 0x00, 0x26, - 0x01, 0x08, 0x4F, 0xDE, 0xDE, 0x00, 0x00, 0x26, 0x01, 0x10, 0x4F, 0xDE, - 0xDC, 0x00, 0x00, 0x26, 0x52, 0x06, 0x02, 0x25, 0x00, 0xCE, 0x25, 0x04, - 0x76 -}; - -static const uint16_t t0_caddr[] = { - 0, - 5, - 10, - 15, - 20, - 25, - 30, - 35, - 40, - 44, - 48, - 52, - 56, - 60, - 64, - 68, - 72, - 76, - 80, - 84, - 88, - 92, - 96, - 100, - 104, - 108, - 112, - 116, - 120, - 124, - 129, - 134, - 139, - 144, - 149, - 154, - 159, - 164, - 169, - 174, - 179, - 184, - 189, - 194, - 199, - 204, - 209, - 214, - 219, - 224, - 229, - 234, - 239, - 244, - 249, - 254, - 259, - 264, - 269, - 274, - 279, - 284, - 289, - 294, - 303, - 316, - 320, - 345, - 351, - 370, - 381, - 422, - 542, - 546, - 611, - 626, - 637, - 655, - 684, - 694, - 730, - 740, - 818, - 832, - 838, - 897, - 916, - 951, - 1000, - 1076, - 1103, - 1134, - 1145, - 1497, - 1644, - 1668, - 1884, - 1898, - 1907, - 1911, - 2006, - 2027, - 2083, - 2090, - 2101, - 2117, - 2123, - 2134, - 2169, - 2181, - 2187, - 2202, - 2218, - 2411, - 2420, - 2433, - 2442, - 2449, - 2459, - 2565, - 2590, - 2603, - 2619, - 2637, - 2669, - 2703, - 3071, - 3107, - 3120, - 3134, - 3139, - 3144, - 3210, - 3218, - 3226 -}; - -#define T0_INTERPRETED 88 - -#define T0_ENTER(ip, rp, slot) do { \ - const unsigned char *t0_newip; \ - uint32_t t0_lnum; \ - t0_newip = &t0_codeblock[t0_caddr[(slot) - T0_INTERPRETED]]; \ - t0_lnum = t0_parse7E_unsigned(&t0_newip); \ - (rp) += t0_lnum; \ - *((rp) ++) = (uint32_t)((ip) - &t0_codeblock[0]) + (t0_lnum << 16); \ - (ip) = t0_newip; \ - } while (0) - -#define T0_DEFENTRY(name, slot) \ -void \ -name(void *ctx) \ -{ \ - t0_context *t0ctx = ctx; \ - t0ctx->ip = &t0_codeblock[0]; \ - T0_ENTER(t0ctx->ip, t0ctx->rp, slot); \ -} - -T0_DEFENTRY(br_ssl_hs_client_init_main, 169) - -#define T0_NEXT(t0ipp) (*(*(t0ipp)) ++) - -void -br_ssl_hs_client_run(void *t0ctx) -{ - uint32_t *dp, *rp; - const unsigned char *ip; - -#define T0_LOCAL(x) (*(rp - 2 - (x))) -#define T0_POP() (*-- dp) -#define T0_POPi() (*(int32_t *)(-- dp)) -#define T0_PEEK(x) (*(dp - 1 - (x))) -#define T0_PEEKi(x) (*(int32_t *)(dp - 1 - (x))) -#define T0_PUSH(v) do { *dp = (v); dp ++; } while (0) -#define T0_PUSHi(v) do { *(int32_t *)dp = (v); dp ++; } while (0) -#define T0_RPOP() (*-- rp) -#define T0_RPOPi() (*(int32_t *)(-- rp)) -#define T0_RPUSH(v) do { *rp = (v); rp ++; } while (0) -#define T0_RPUSHi(v) do { *(int32_t *)rp = (v); rp ++; } while (0) -#define T0_ROLL(x) do { \ - size_t t0len = (size_t)(x); \ - uint32_t t0tmp = *(dp - 1 - t0len); \ - memmove(dp - t0len - 1, dp - t0len, t0len * sizeof *dp); \ - *(dp - 1) = t0tmp; \ -} while (0) -#define T0_SWAP() do { \ - uint32_t t0tmp = *(dp - 2); \ - *(dp - 2) = *(dp - 1); \ - *(dp - 1) = t0tmp; \ -} while (0) -#define T0_ROT() do { \ - uint32_t t0tmp = *(dp - 3); \ - *(dp - 3) = *(dp - 2); \ - *(dp - 2) = *(dp - 1); \ - *(dp - 1) = t0tmp; \ -} while (0) -#define T0_NROT() do { \ - uint32_t t0tmp = *(dp - 1); \ - *(dp - 1) = *(dp - 2); \ - *(dp - 2) = *(dp - 3); \ - *(dp - 3) = t0tmp; \ -} while (0) -#define T0_PICK(x) do { \ - uint32_t t0depth = (x); \ - T0_PUSH(T0_PEEK(t0depth)); \ -} while (0) -#define T0_CO() do { \ - goto t0_exit; \ -} while (0) -#define T0_RET() goto t0_next - - dp = ((t0_context *)t0ctx)->dp; - rp = ((t0_context *)t0ctx)->rp; - ip = ((t0_context *)t0ctx)->ip; - goto t0_next; - for (;;) { - uint32_t t0x; - - t0_next: - t0x = T0_NEXT(&ip); - if (t0x < T0_INTERPRETED) { - switch (t0x) { - int32_t t0off; - - case 0: /* ret */ - t0x = T0_RPOP(); - rp -= (t0x >> 16); - t0x &= 0xFFFF; - if (t0x == 0) { - ip = NULL; - goto t0_exit; - } - ip = &t0_codeblock[t0x]; - break; - case 1: /* literal constant */ - T0_PUSHi(t0_parse7E_signed(&ip)); - break; - case 2: /* read local */ - T0_PUSH(T0_LOCAL(t0_parse7E_unsigned(&ip))); - break; - case 3: /* write local */ - T0_LOCAL(t0_parse7E_unsigned(&ip)) = T0_POP(); - break; - case 4: /* jump */ - t0off = t0_parse7E_signed(&ip); - ip += t0off; - break; - case 5: /* jump if */ - t0off = t0_parse7E_signed(&ip); - if (T0_POP()) { - ip += t0off; - } - break; - case 6: /* jump if not */ - t0off = t0_parse7E_signed(&ip); - if (!T0_POP()) { - ip += t0off; - } - break; - case 7: { - /* * */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(a * b); - - } - break; - case 8: { - /* + */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(a + b); - - } - break; - case 9: { - /* - */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(a - b); - - } - break; - case 10: { - /* < */ - - int32_t b = T0_POPi(); - int32_t a = T0_POPi(); - T0_PUSH(-(uint32_t)(a < b)); - - } - break; - case 11: { - /* << */ - - int c = (int)T0_POPi(); - uint32_t x = T0_POP(); - T0_PUSH(x << c); - - } - break; - case 12: { - /* <= */ - - int32_t b = T0_POPi(); - int32_t a = T0_POPi(); - T0_PUSH(-(uint32_t)(a <= b)); - - } - break; - case 13: { - /* <> */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(-(uint32_t)(a != b)); - - } - break; - case 14: { - /* = */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(-(uint32_t)(a == b)); - - } - break; - case 15: { - /* > */ - - int32_t b = T0_POPi(); - int32_t a = T0_POPi(); - T0_PUSH(-(uint32_t)(a > b)); - - } - break; - case 16: { - /* >= */ - - int32_t b = T0_POPi(); - int32_t a = T0_POPi(); - T0_PUSH(-(uint32_t)(a >= b)); - - } - break; - case 17: { - /* >> */ - - int c = (int)T0_POPi(); - int32_t x = T0_POPi(); - T0_PUSHi(x >> c); - - } - break; - case 18: { - /* anchor-dn-append-name */ - - size_t len; - - len = T0_POP(); - if (CTX->client_auth_vtable != NULL) { - (*CTX->client_auth_vtable)->append_name( - CTX->client_auth_vtable, ENG->pad, len); - } - - } - break; - case 19: { - /* anchor-dn-end-name */ - - if (CTX->client_auth_vtable != NULL) { - (*CTX->client_auth_vtable)->end_name( - CTX->client_auth_vtable); - } - - } - break; - case 20: { - /* anchor-dn-end-name-list */ - - if (CTX->client_auth_vtable != NULL) { - (*CTX->client_auth_vtable)->end_name_list( - CTX->client_auth_vtable); - } - - } - break; - case 21: { - /* anchor-dn-start-name */ - - size_t len; - - len = T0_POP(); - if (CTX->client_auth_vtable != NULL) { - (*CTX->client_auth_vtable)->start_name( - CTX->client_auth_vtable, len); - } - - } - break; - case 22: { - /* anchor-dn-start-name-list */ - - if (CTX->client_auth_vtable != NULL) { - (*CTX->client_auth_vtable)->start_name_list( - CTX->client_auth_vtable); - } - - } - break; - case 23: { - /* and */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(a & b); - - } - break; - case 24: { - /* begin-cert */ - - if (ENG->chain_len == 0) { - T0_PUSHi(-1); - } else { - ENG->cert_cur = ENG->chain->data; - ENG->cert_len = ENG->chain->data_len; - ENG->chain ++; - ENG->chain_len --; - T0_PUSH(ENG->cert_len); - } - - } - break; - case 25: { - /* bzero */ - - size_t len = (size_t)T0_POP(); - void *addr = (unsigned char *)ENG + (size_t)T0_POP(); - memset(addr, 0, len); - - } - break; - case 26: { - /* can-output? */ - - T0_PUSHi(-(ENG->hlen_out > 0)); - - } - break; - case 27: { - /* co */ - T0_CO(); - } - break; - case 28: { - /* compute-Finished-inner */ - - int prf_id = T0_POP(); - int from_client = T0_POPi(); - unsigned char tmp[48]; - br_tls_prf_seed_chunk seed; - - br_tls_prf_impl prf = br_ssl_engine_get_PRF(ENG, prf_id); - seed.data = tmp; - if (ENG->session.version >= BR_TLS12) { - seed.len = br_multihash_out(&ENG->mhash, prf_id, tmp); - } else { - br_multihash_out(&ENG->mhash, br_md5_ID, tmp); - br_multihash_out(&ENG->mhash, br_sha1_ID, tmp + 16); - seed.len = 36; - } - prf(ENG->pad, 12, ENG->session.master_secret, - sizeof ENG->session.master_secret, - from_client ? "client finished" : "server finished", - 1, &seed); - - } - break; - case 29: { - /* copy-cert-chunk */ - - size_t clen; - - clen = ENG->cert_len; - if (clen > sizeof ENG->pad) { - clen = sizeof ENG->pad; - } - memcpy(ENG->pad, ENG->cert_cur, clen); - ENG->cert_cur += clen; - ENG->cert_len -= clen; - T0_PUSH(clen); - - } - break; - case 30: { - /* copy-protocol-name */ - - size_t idx = T0_POP(); - size_t len = strlen(ENG->protocol_names[idx]); - memcpy(ENG->pad, ENG->protocol_names[idx], len); - T0_PUSH(len); - - } - break; - case 31: { - /* data-get8 */ - - size_t addr = T0_POP(); - T0_PUSH(t0_datablock[addr]); - - } - break; - case 32: { - /* discard-input */ - - ENG->hlen_in = 0; - - } - break; - case 33: { - /* do-client-sign */ - - size_t sig_len; - - sig_len = make_client_sign(CTX); - if (sig_len == 0) { - br_ssl_engine_fail(ENG, BR_ERR_INVALID_ALGORITHM); - T0_CO(); - } - T0_PUSH(sig_len); - - } - break; - case 34: { - /* do-ecdh */ - - unsigned prf_id = T0_POP(); - unsigned ecdhe = T0_POP(); - int x; - - x = make_pms_ecdh(CTX, ecdhe, prf_id); - if (x < 0) { - br_ssl_engine_fail(ENG, -x); - T0_CO(); - } else { - T0_PUSH(x); - } - - } - break; - case 35: { - /* do-rsa-encrypt */ - - int x; - - x = make_pms_rsa(CTX, T0_POP()); - if (x < 0) { - br_ssl_engine_fail(ENG, -x); - T0_CO(); - } else { - T0_PUSH(x); - } - - } - break; - case 36: { - /* do-static-ecdh */ - - unsigned prf_id = T0_POP(); - - if (make_pms_static_ecdh(CTX, prf_id) < 0) { - br_ssl_engine_fail(ENG, BR_ERR_INVALID_ALGORITHM); - T0_CO(); - } - - } - break; - case 37: { - /* drop */ - (void)T0_POP(); - } - break; - case 38: { - /* dup */ - T0_PUSH(T0_PEEK(0)); - } - break; - case 39: { - /* ext-ALPN-length */ - - size_t u, len; - - if (ENG->protocol_names_num == 0) { - T0_PUSH(0); - T0_RET(); - } - len = 6; - for (u = 0; u < ENG->protocol_names_num; u ++) { - len += 1 + strlen(ENG->protocol_names[u]); - } - T0_PUSH(len); - - } - break; - case 40: { - /* fail */ - - br_ssl_engine_fail(ENG, (int)T0_POPi()); - T0_CO(); - - } - break; - case 41: { - /* flush-record */ - - br_ssl_engine_flush_record(ENG); - - } - break; - case 42: { - /* get-client-chain */ - - uint32_t auth_types; - - auth_types = T0_POP(); - if (CTX->client_auth_vtable != NULL) { - br_ssl_client_certificate ux; - - (*CTX->client_auth_vtable)->choose(CTX->client_auth_vtable, - CTX, auth_types, &ux); - CTX->auth_type = (unsigned char)ux.auth_type; - CTX->hash_id = (unsigned char)ux.hash_id; - ENG->chain = ux.chain; - ENG->chain_len = ux.chain_len; - } else { - CTX->hash_id = 0; - ENG->chain_len = 0; - } - - } - break; - case 43: { - /* get-key-type-usages */ - - const br_x509_class *xc; - const br_x509_pkey *pk; - unsigned usages; - - xc = *(ENG->x509ctx); - pk = xc->get_pkey(ENG->x509ctx, &usages); - if (pk == NULL) { - T0_PUSH(0); - } else { - T0_PUSH(pk->key_type | usages); - } - - } - break; - case 44: { - /* get16 */ - - size_t addr = (size_t)T0_POP(); - T0_PUSH(*(uint16_t *)(void *)((unsigned char *)ENG + addr)); - - } - break; - case 45: { - /* get32 */ - - size_t addr = (size_t)T0_POP(); - T0_PUSH(*(uint32_t *)(void *)((unsigned char *)ENG + addr)); - - } - break; - case 46: { - /* get8 */ - - size_t addr = (size_t)T0_POP(); - T0_PUSH(*((unsigned char *)ENG + addr)); - - } - break; - case 47: { - /* has-input? */ - - T0_PUSHi(-(ENG->hlen_in != 0)); - - } - break; - case 48: { - /* memcmp */ - - size_t len = (size_t)T0_POP(); - void *addr2 = (unsigned char *)ENG + (size_t)T0_POP(); - void *addr1 = (unsigned char *)ENG + (size_t)T0_POP(); - int x = memcmp(addr1, addr2, len); - T0_PUSH((uint32_t)-(x == 0)); - - } - break; - case 49: { - /* memcpy */ - - size_t len = (size_t)T0_POP(); - void *src = (unsigned char *)ENG + (size_t)T0_POP(); - void *dst = (unsigned char *)ENG + (size_t)T0_POP(); - memcpy(dst, src, len); - - } - break; - case 50: { - /* mkrand */ - - size_t len = (size_t)T0_POP(); - void *addr = (unsigned char *)ENG + (size_t)T0_POP(); - br_hmac_drbg_generate(&ENG->rng, addr, len); - - } - break; - case 51: { - /* more-incoming-bytes? */ - - T0_PUSHi(ENG->hlen_in != 0 || !br_ssl_engine_recvrec_finished(ENG)); - - } - break; - case 52: { - /* multihash-init */ - - br_multihash_init(&ENG->mhash); - - } - break; - case 53: { - /* neg */ - - uint32_t a = T0_POP(); - T0_PUSH(-a); - - } - break; - case 54: { - /* not */ - - uint32_t a = T0_POP(); - T0_PUSH(~a); - - } - break; - case 55: { - /* or */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(a | b); - - } - break; - case 56: { - /* over */ - T0_PUSH(T0_PEEK(1)); - } - break; - case 57: { - /* read-chunk-native */ - - size_t clen = ENG->hlen_in; - if (clen > 0) { - uint32_t addr, len; - - len = T0_POP(); - addr = T0_POP(); - if ((size_t)len < clen) { - clen = (size_t)len; - } - memcpy((unsigned char *)ENG + addr, ENG->hbuf_in, clen); - if (ENG->record_type_in == BR_SSL_HANDSHAKE) { - br_multihash_update(&ENG->mhash, ENG->hbuf_in, clen); - } - T0_PUSH(addr + (uint32_t)clen); - T0_PUSH(len - (uint32_t)clen); - ENG->hbuf_in += clen; - ENG->hlen_in -= clen; - } - - } - break; - case 58: { - /* read8-native */ - - if (ENG->hlen_in > 0) { - unsigned char x; - - x = *ENG->hbuf_in ++; - if (ENG->record_type_in == BR_SSL_HANDSHAKE) { - br_multihash_update(&ENG->mhash, &x, 1); - } - T0_PUSH(x); - ENG->hlen_in --; - } else { - T0_PUSHi(-1); - } - - } - break; - case 59: { - /* set-server-curve */ - - const br_x509_class *xc; - const br_x509_pkey *pk; - - xc = *(ENG->x509ctx); - pk = xc->get_pkey(ENG->x509ctx, NULL); - CTX->server_curve = - (pk->key_type == BR_KEYTYPE_EC) ? pk->key.ec.curve : 0; - - } - break; - case 60: { - /* set16 */ - - size_t addr = (size_t)T0_POP(); - *(uint16_t *)(void *)((unsigned char *)ENG + addr) = (uint16_t)T0_POP(); - - } - break; - case 61: { - /* set32 */ - - size_t addr = (size_t)T0_POP(); - *(uint32_t *)(void *)((unsigned char *)ENG + addr) = (uint32_t)T0_POP(); - - } - break; - case 62: { - /* set8 */ - - size_t addr = (size_t)T0_POP(); - *((unsigned char *)ENG + addr) = (unsigned char)T0_POP(); - - } - break; - case 63: { - /* strlen */ - - void *str = (unsigned char *)ENG + (size_t)T0_POP(); - T0_PUSH((uint32_t)strlen(str)); - - } - break; - case 64: { - /* supported-curves */ - - uint32_t x = ENG->iec == NULL ? 0 : ENG->iec->supported_curves; - T0_PUSH(x); - - } - break; - case 65: { - /* supported-hash-functions */ - - int i; - unsigned x, num; - - x = 0; - num = 0; - for (i = br_sha1_ID; i <= br_sha512_ID; i ++) { - if (br_multihash_getimpl(&ENG->mhash, i)) { - x |= 1U << i; - num ++; - } - } - T0_PUSH(x); - T0_PUSH(num); - - } - break; - case 66: { - /* supports-ecdsa? */ - - T0_PUSHi(-(ENG->iecdsa != 0)); - - } - break; - case 67: { - /* supports-rsa-sign? */ - - T0_PUSHi(-(ENG->irsavrfy != 0)); - - } - break; - case 68: { - /* swap */ - T0_SWAP(); - } - break; - case 69: { - /* switch-aesccm-in */ - - int is_client, prf_id; - unsigned cipher_key_len, tag_len; - - tag_len = T0_POP(); - cipher_key_len = T0_POP(); - prf_id = T0_POP(); - is_client = T0_POP(); - br_ssl_engine_switch_ccm_in(ENG, is_client, prf_id, - ENG->iaes_ctrcbc, cipher_key_len, tag_len); - - } - break; - case 70: { - /* switch-aesccm-out */ - - int is_client, prf_id; - unsigned cipher_key_len, tag_len; - - tag_len = T0_POP(); - cipher_key_len = T0_POP(); - prf_id = T0_POP(); - is_client = T0_POP(); - br_ssl_engine_switch_ccm_out(ENG, is_client, prf_id, - ENG->iaes_ctrcbc, cipher_key_len, tag_len); - - } - break; - case 71: { - /* switch-aesgcm-in */ - - int is_client, prf_id; - unsigned cipher_key_len; - - cipher_key_len = T0_POP(); - prf_id = T0_POP(); - is_client = T0_POP(); - br_ssl_engine_switch_gcm_in(ENG, is_client, prf_id, - ENG->iaes_ctr, cipher_key_len); - - } - break; - case 72: { - /* switch-aesgcm-out */ - - int is_client, prf_id; - unsigned cipher_key_len; - - cipher_key_len = T0_POP(); - prf_id = T0_POP(); - is_client = T0_POP(); - br_ssl_engine_switch_gcm_out(ENG, is_client, prf_id, - ENG->iaes_ctr, cipher_key_len); - - } - break; - case 73: { - /* switch-cbc-in */ - - int is_client, prf_id, mac_id, aes; - unsigned cipher_key_len; - - cipher_key_len = T0_POP(); - aes = T0_POP(); - mac_id = T0_POP(); - prf_id = T0_POP(); - is_client = T0_POP(); - br_ssl_engine_switch_cbc_in(ENG, is_client, prf_id, mac_id, - aes ? ENG->iaes_cbcdec : ENG->ides_cbcdec, cipher_key_len); - - } - break; - case 74: { - /* switch-cbc-out */ - - int is_client, prf_id, mac_id, aes; - unsigned cipher_key_len; - - cipher_key_len = T0_POP(); - aes = T0_POP(); - mac_id = T0_POP(); - prf_id = T0_POP(); - is_client = T0_POP(); - br_ssl_engine_switch_cbc_out(ENG, is_client, prf_id, mac_id, - aes ? ENG->iaes_cbcenc : ENG->ides_cbcenc, cipher_key_len); - - } - break; - case 75: { - /* switch-chapol-in */ - - int is_client, prf_id; - - prf_id = T0_POP(); - is_client = T0_POP(); - br_ssl_engine_switch_chapol_in(ENG, is_client, prf_id); - - } - break; - case 76: { - /* switch-chapol-out */ - - int is_client, prf_id; - - prf_id = T0_POP(); - is_client = T0_POP(); - br_ssl_engine_switch_chapol_out(ENG, is_client, prf_id); - - } - break; - case 77: { - /* test-protocol-name */ - - size_t len = T0_POP(); - size_t u; - - for (u = 0; u < ENG->protocol_names_num; u ++) { - const char *name; - - name = ENG->protocol_names[u]; - if (len == strlen(name) && memcmp(ENG->pad, name, len) == 0) { - T0_PUSH(u); - T0_RET(); - } - } - T0_PUSHi(-1); - - } - break; - case 78: { - /* total-chain-length */ - - size_t u; - uint32_t total; - - total = 0; - for (u = 0; u < ENG->chain_len; u ++) { - total += 3 + (uint32_t)ENG->chain[u].data_len; - } - T0_PUSH(total); - - } - break; - case 79: { - /* u>> */ - - int c = (int)T0_POPi(); - uint32_t x = T0_POP(); - T0_PUSH(x >> c); - - } - break; - case 80: { - /* verify-SKE-sig */ - - size_t sig_len = T0_POP(); - int use_rsa = T0_POPi(); - int hash = T0_POPi(); - - T0_PUSH(verify_SKE_sig(CTX, hash, use_rsa, sig_len)); - - } - break; - case 81: { - /* write-blob-chunk */ - - size_t clen = ENG->hlen_out; - if (clen > 0) { - uint32_t addr, len; - - len = T0_POP(); - addr = T0_POP(); - if ((size_t)len < clen) { - clen = (size_t)len; - } - memcpy(ENG->hbuf_out, (unsigned char *)ENG + addr, clen); - if (ENG->record_type_out == BR_SSL_HANDSHAKE) { - br_multihash_update(&ENG->mhash, ENG->hbuf_out, clen); - } - T0_PUSH(addr + (uint32_t)clen); - T0_PUSH(len - (uint32_t)clen); - ENG->hbuf_out += clen; - ENG->hlen_out -= clen; - } - - } - break; - case 82: { - /* write8-native */ - - unsigned char x; - - x = (unsigned char)T0_POP(); - if (ENG->hlen_out > 0) { - if (ENG->record_type_out == BR_SSL_HANDSHAKE) { - br_multihash_update(&ENG->mhash, &x, 1); - } - *ENG->hbuf_out ++ = x; - ENG->hlen_out --; - T0_PUSHi(-1); - } else { - T0_PUSHi(0); - } - - } - break; - case 83: { - /* x509-append */ - - const br_x509_class *xc; - size_t len; - - xc = *(ENG->x509ctx); - len = T0_POP(); - xc->append(ENG->x509ctx, ENG->pad, len); - - } - break; - case 84: { - /* x509-end-cert */ - - const br_x509_class *xc; - - xc = *(ENG->x509ctx); - xc->end_cert(ENG->x509ctx); - - } - break; - case 85: { - /* x509-end-chain */ - - const br_x509_class *xc; - - xc = *(ENG->x509ctx); - T0_PUSH(xc->end_chain(ENG->x509ctx)); - - } - break; - case 86: { - /* x509-start-cert */ - - const br_x509_class *xc; - - xc = *(ENG->x509ctx); - xc->start_cert(ENG->x509ctx, T0_POP()); - - } - break; - case 87: { - /* x509-start-chain */ - - const br_x509_class *xc; - uint32_t bc; - - bc = T0_POP(); - xc = *(ENG->x509ctx); - xc->start_chain(ENG->x509ctx, bc ? ENG->server_name : NULL); - - } - break; - } - - } else { - T0_ENTER(ip, rp, t0x); - } - } -t0_exit: - ((t0_context *)t0ctx)->dp = dp; - ((t0_context *)t0ctx)->rp = rp; - ((t0_context *)t0ctx)->ip = ip; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ssl_hs_server.c b/src/tls/bearssl/ssl_hs_server.c deleted file mode 100644 index 7fc29b3c0..000000000 --- a/src/tls/bearssl/ssl_hs_server.c +++ /dev/null @@ -1,2014 +0,0 @@ -/* Automatically generated code; do not modify directly. */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include -#include - -typedef struct { - uint32_t *dp; - uint32_t *rp; - const unsigned char *ip; -} t0_context; - -static uint32_t -t0_parse7E_unsigned(const unsigned char **p) -{ - uint32_t x; - - x = 0; - for (;;) { - unsigned y; - - y = *(*p) ++; - x = (x << 7) | (uint32_t)(y & 0x7F); - if (y < 0x80) { - return x; - } - } -} - -static int32_t -t0_parse7E_signed(const unsigned char **p) -{ - int neg; - uint32_t x; - - neg = ((**p) >> 6) & 1; - x = (uint32_t)-neg; - for (;;) { - unsigned y; - - y = *(*p) ++; - x = (x << 7) | (uint32_t)(y & 0x7F); - if (y < 0x80) { - if (neg) { - return -(int32_t)~x - 1; - } else { - return (int32_t)x; - } - } - } -} - -#define T0_VBYTE(x, n) (unsigned char)((((uint32_t)(x) >> (n)) & 0x7F) | 0x80) -#define T0_FBYTE(x, n) (unsigned char)(((uint32_t)(x) >> (n)) & 0x7F) -#define T0_SBYTE(x) (unsigned char)((((uint32_t)(x) >> 28) + 0xF8) ^ 0xF8) -#define T0_INT1(x) T0_FBYTE(x, 0) -#define T0_INT2(x) T0_VBYTE(x, 7), T0_FBYTE(x, 0) -#define T0_INT3(x) T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) -#define T0_INT4(x) T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) -#define T0_INT5(x) T0_SBYTE(x), T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) - -/* static const unsigned char t0_datablock[]; */ - - -void br_ssl_hs_server_init_main(void *t0ctx); - -void br_ssl_hs_server_run(void *t0ctx); - - - -#include -#include - -#include "inner.h" - -/* - * This macro evaluates to a pointer to the current engine context. - */ -#define ENG ((br_ssl_engine_context *)(void *)((unsigned char *)t0ctx - offsetof(br_ssl_engine_context, cpu))) - - - - - -/* - * This macro evaluates to a pointer to the server context, under that - * specific name. It must be noted that since the engine context is the - * first field of the br_ssl_server_context structure ('eng'), then - * pointers values of both types are interchangeable, modulo an - * appropriate cast. This also means that "addresses" computed as offsets - * within the structure work for both kinds of context. - */ -#define CTX ((br_ssl_server_context *)ENG) - -/* - * Decrypt the pre-master secret (RSA key exchange). - */ -static void -do_rsa_decrypt(br_ssl_server_context *ctx, int prf_id, - unsigned char *epms, size_t len) -{ - uint32_t x; - unsigned char rpms[48]; - - /* - * Decrypt the PMS. - */ - x = (*ctx->policy_vtable)->do_keyx(ctx->policy_vtable, epms, &len); - - /* - * Set the first two bytes to the maximum supported client - * protocol version. These bytes are used for version rollback - * detection; forceing the two bytes will make the master secret - * wrong if the bytes are not correct. This process is - * recommended by RFC 5246 (section 7.4.7.1). - */ - br_enc16be(epms, ctx->client_max_version); - - /* - * Make a random PMS and copy it above the decrypted value if the - * decryption failed. Note that we use a constant-time conditional - * copy. - */ - br_hmac_drbg_generate(&ctx->eng.rng, rpms, sizeof rpms); - br_ccopy(x ^ 1, epms, rpms, sizeof rpms); - - /* - * Compute master secret. - */ - br_ssl_engine_compute_master(&ctx->eng, prf_id, epms, 48); - - /* - * Clear the pre-master secret from RAM: it is normally a buffer - * in the context, hence potentially long-lived. - */ - memset(epms, 0, len); -} - -/* - * Common part for ECDH and ECDHE. - */ -static void -ecdh_common(br_ssl_server_context *ctx, int prf_id, - unsigned char *xcoor, size_t xcoor_len, uint32_t ctl) -{ - unsigned char rpms[80]; - - if (xcoor_len > sizeof rpms) { - xcoor_len = sizeof rpms; - ctl = 0; - } - - /* - * Make a random PMS and copy it above the decrypted value if the - * decryption failed. Note that we use a constant-time conditional - * copy. - */ - br_hmac_drbg_generate(&ctx->eng.rng, rpms, xcoor_len); - br_ccopy(ctl ^ 1, xcoor, rpms, xcoor_len); - - /* - * Compute master secret. - */ - br_ssl_engine_compute_master(&ctx->eng, prf_id, xcoor, xcoor_len); - - /* - * Clear the pre-master secret from RAM: it is normally a buffer - * in the context, hence potentially long-lived. - */ - memset(xcoor, 0, xcoor_len); -} - -/* - * Do the ECDH key exchange (not ECDHE). - */ -static void -do_ecdh(br_ssl_server_context *ctx, int prf_id, - unsigned char *cpoint, size_t cpoint_len) -{ - uint32_t x; - - /* - * Finalise the key exchange. - */ - x = (*ctx->policy_vtable)->do_keyx(ctx->policy_vtable, - cpoint, &cpoint_len); - ecdh_common(ctx, prf_id, cpoint, cpoint_len, x); -} - -/* - * Do the full static ECDH key exchange. When this function is called, - * it has already been verified that the cipher suite uses ECDH (not ECDHE), - * and the client's public key (from its certificate) has type EC and is - * apt for key exchange. - */ -static void -do_static_ecdh(br_ssl_server_context *ctx, int prf_id) -{ - unsigned char cpoint[133]; - size_t cpoint_len; - const br_x509_class **xc; - const br_x509_pkey *pk; - - xc = ctx->eng.x509ctx; - pk = (*xc)->get_pkey(xc, NULL); - cpoint_len = pk->key.ec.qlen; - if (cpoint_len > sizeof cpoint) { - /* - * If the point is larger than our buffer then we need to - * restrict it. Length 2 is not a valid point length, so - * the ECDH will fail. - */ - cpoint_len = 2; - } - memcpy(cpoint, pk->key.ec.q, cpoint_len); - do_ecdh(ctx, prf_id, cpoint, cpoint_len); -} - -static size_t -hash_data(br_ssl_server_context *ctx, - void *dst, int hash_id, const void *src, size_t len) -{ - const br_hash_class *hf; - br_hash_compat_context hc; - - if (hash_id == 0) { - unsigned char tmp[36]; - - hf = br_multihash_getimpl(&ctx->eng.mhash, br_md5_ID); - if (hf == NULL) { - return 0; - } - hf->init(&hc.vtable); - hf->update(&hc.vtable, src, len); - hf->out(&hc.vtable, tmp); - hf = br_multihash_getimpl(&ctx->eng.mhash, br_sha1_ID); - if (hf == NULL) { - return 0; - } - hf->init(&hc.vtable); - hf->update(&hc.vtable, src, len); - hf->out(&hc.vtable, tmp + 16); - memcpy(dst, tmp, 36); - return 36; - } else { - hf = br_multihash_getimpl(&ctx->eng.mhash, hash_id); - if (hf == NULL) { - return 0; - } - hf->init(&hc.vtable); - hf->update(&hc.vtable, src, len); - hf->out(&hc.vtable, dst); - return (hf->desc >> BR_HASHDESC_OUT_OFF) & BR_HASHDESC_OUT_MASK; - } -} - -/* - * Do the ECDHE key exchange (part 1: generation of transient key, and - * computing of the point to send to the client). Returned value is the - * signature length (in bytes), or -x on error (with x being an error - * code). The encoded point is written in the ecdhe_point[] context buffer - * (length in ecdhe_point_len). - */ -static int -do_ecdhe_part1(br_ssl_server_context *ctx, int curve) -{ - unsigned algo_id; - unsigned mask; - const unsigned char *order; - size_t olen, glen; - size_t hv_len, sig_len; - - if (!((ctx->eng.iec->supported_curves >> curve) & 1)) { - return -BR_ERR_INVALID_ALGORITHM; - } - ctx->eng.ecdhe_curve = curve; - - /* - * Generate our private key. We need a non-zero random value - * which is lower than the curve order, in a "large enough" - * range. We force the top bit to 0 and bottom bit to 1, which - * does the trick. Note that contrary to what happens in ECDSA, - * this is not a problem if we do not cover the full range of - * possible values. - */ - order = ctx->eng.iec->order(curve, &olen); - mask = 0xFF; - while (mask >= order[0]) { - mask >>= 1; - } - br_hmac_drbg_generate(&ctx->eng.rng, ctx->ecdhe_key, olen); - ctx->ecdhe_key[0] &= mask; - ctx->ecdhe_key[olen - 1] |= 0x01; - ctx->ecdhe_key_len = olen; - - /* - * Compute our ECDH point. - */ - glen = ctx->eng.iec->mulgen(ctx->eng.ecdhe_point, - ctx->ecdhe_key, olen, curve); - ctx->eng.ecdhe_point_len = glen; - - /* - * Assemble the message to be signed, and possibly hash it. - */ - memcpy(ctx->eng.pad, ctx->eng.client_random, 32); - memcpy(ctx->eng.pad + 32, ctx->eng.server_random, 32); - ctx->eng.pad[64 + 0] = 0x03; - ctx->eng.pad[64 + 1] = 0x00; - ctx->eng.pad[64 + 2] = curve; - ctx->eng.pad[64 + 3] = ctx->eng.ecdhe_point_len; - memcpy(ctx->eng.pad + 64 + 4, - ctx->eng.ecdhe_point, ctx->eng.ecdhe_point_len); - hv_len = 64 + 4 + ctx->eng.ecdhe_point_len; - algo_id = ctx->sign_hash_id; - if (algo_id >= (unsigned)0xFF00) { - hv_len = hash_data(ctx, ctx->eng.pad, algo_id & 0xFF, - ctx->eng.pad, hv_len); - if (hv_len == 0) { - return -BR_ERR_INVALID_ALGORITHM; - } - } - - sig_len = (*ctx->policy_vtable)->do_sign(ctx->policy_vtable, - algo_id, ctx->eng.pad, hv_len, sizeof ctx->eng.pad); - return sig_len ? (int)sig_len : -BR_ERR_INVALID_ALGORITHM; -} - -/* - * Do the ECDHE key exchange (part 2: computation of the shared secret - * from the point sent by the client). - */ -static void -do_ecdhe_part2(br_ssl_server_context *ctx, int prf_id, - unsigned char *cpoint, size_t cpoint_len) -{ - int curve; - uint32_t ctl; - size_t xoff, xlen; - - curve = ctx->eng.ecdhe_curve; - - /* - * Finalise the key exchange. - */ - ctl = ctx->eng.iec->mul(cpoint, cpoint_len, - ctx->ecdhe_key, ctx->ecdhe_key_len, curve); - xoff = ctx->eng.iec->xoff(curve, &xlen); - ecdh_common(ctx, prf_id, cpoint + xoff, xlen, ctl); - - /* - * Clear the ECDHE private key. Forward Secrecy is achieved insofar - * as that key does not get stolen, so we'd better destroy it - * as soon as it ceases to be useful. - */ - memset(ctx->ecdhe_key, 0, ctx->ecdhe_key_len); -} - -/* - * Offset for hash value within the pad (when obtaining all hash values, - * in preparation for verification of the CertificateVerify message). - * Order is MD5, SHA-1, SHA-224, SHA-256, SHA-384, SHA-512; last value - * is used to get the total length. - */ -static const unsigned char HASH_PAD_OFF[] = { 0, 16, 36, 64, 96, 144, 208 }; - -/* - * OID for hash functions in RSA signatures. - */ -static const unsigned char HASH_OID_SHA1[] = { - 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A -}; - -static const unsigned char HASH_OID_SHA224[] = { - 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04 -}; - -static const unsigned char HASH_OID_SHA256[] = { - 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01 -}; - -static const unsigned char HASH_OID_SHA384[] = { - 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02 -}; - -static const unsigned char HASH_OID_SHA512[] = { - 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03 -}; - -static const unsigned char *HASH_OID[] = { - HASH_OID_SHA1, - HASH_OID_SHA224, - HASH_OID_SHA256, - HASH_OID_SHA384, - HASH_OID_SHA512 -}; - -/* - * Verify the signature in CertificateVerify. Returned value is 0 on - * success, or a non-zero error code. Lack of implementation of the - * designated signature algorithm is reported as a "bad signature" - * error (because it means that the peer did not honour our advertised - * set of supported signature algorithms). - */ -static int -verify_CV_sig(br_ssl_server_context *ctx, size_t sig_len) -{ - const br_x509_class **xc; - const br_x509_pkey *pk; - int id; - - id = ctx->hash_CV_id; - xc = ctx->eng.x509ctx; - pk = (*xc)->get_pkey(xc, NULL); - if (pk->key_type == BR_KEYTYPE_RSA) { - unsigned char tmp[64]; - const unsigned char *hash_oid; - - if (id == 0) { - hash_oid = NULL; - } else { - hash_oid = HASH_OID[id - 2]; - } - if (ctx->eng.irsavrfy == 0) { - return BR_ERR_BAD_SIGNATURE; - } - if (!ctx->eng.irsavrfy(ctx->eng.pad, sig_len, - hash_oid, ctx->hash_CV_len, &pk->key.rsa, tmp) - || memcmp(tmp, ctx->hash_CV, ctx->hash_CV_len) != 0) - { - return BR_ERR_BAD_SIGNATURE; - } - } else { - if (ctx->eng.iecdsa == 0) { - return BR_ERR_BAD_SIGNATURE; - } - if (!ctx->eng.iecdsa(ctx->eng.iec, - ctx->hash_CV, ctx->hash_CV_len, - &pk->key.ec, ctx->eng.pad, sig_len)) - { - return BR_ERR_BAD_SIGNATURE; - } - } - return 0; -} - - - -static const unsigned char t0_datablock[] = { - 0x00, 0x00, 0x0A, 0x00, 0x24, 0x00, 0x2F, 0x01, 0x24, 0x00, 0x35, 0x02, - 0x24, 0x00, 0x3C, 0x01, 0x44, 0x00, 0x3D, 0x02, 0x44, 0x00, 0x9C, 0x03, - 0x04, 0x00, 0x9D, 0x04, 0x05, 0xC0, 0x03, 0x40, 0x24, 0xC0, 0x04, 0x41, - 0x24, 0xC0, 0x05, 0x42, 0x24, 0xC0, 0x08, 0x20, 0x24, 0xC0, 0x09, 0x21, - 0x24, 0xC0, 0x0A, 0x22, 0x24, 0xC0, 0x0D, 0x30, 0x24, 0xC0, 0x0E, 0x31, - 0x24, 0xC0, 0x0F, 0x32, 0x24, 0xC0, 0x12, 0x10, 0x24, 0xC0, 0x13, 0x11, - 0x24, 0xC0, 0x14, 0x12, 0x24, 0xC0, 0x23, 0x21, 0x44, 0xC0, 0x24, 0x22, - 0x55, 0xC0, 0x25, 0x41, 0x44, 0xC0, 0x26, 0x42, 0x55, 0xC0, 0x27, 0x11, - 0x44, 0xC0, 0x28, 0x12, 0x55, 0xC0, 0x29, 0x31, 0x44, 0xC0, 0x2A, 0x32, - 0x55, 0xC0, 0x2B, 0x23, 0x04, 0xC0, 0x2C, 0x24, 0x05, 0xC0, 0x2D, 0x43, - 0x04, 0xC0, 0x2E, 0x44, 0x05, 0xC0, 0x2F, 0x13, 0x04, 0xC0, 0x30, 0x14, - 0x05, 0xC0, 0x31, 0x33, 0x04, 0xC0, 0x32, 0x34, 0x05, 0xC0, 0x9C, 0x06, - 0x04, 0xC0, 0x9D, 0x07, 0x04, 0xC0, 0xA0, 0x08, 0x04, 0xC0, 0xA1, 0x09, - 0x04, 0xC0, 0xAC, 0x26, 0x04, 0xC0, 0xAD, 0x27, 0x04, 0xC0, 0xAE, 0x28, - 0x04, 0xC0, 0xAF, 0x29, 0x04, 0xCC, 0xA8, 0x15, 0x04, 0xCC, 0xA9, 0x25, - 0x04, 0x00, 0x00 -}; - -static const unsigned char t0_codeblock[] = { - 0x00, 0x01, 0x00, 0x0B, 0x00, 0x00, 0x01, 0x00, 0x0E, 0x00, 0x00, 0x01, - 0x00, 0x0F, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x01, 0x01, 0x08, - 0x00, 0x00, 0x01, 0x01, 0x09, 0x00, 0x00, 0x01, 0x02, 0x08, 0x00, 0x00, - 0x01, 0x02, 0x09, 0x00, 0x00, 0x29, 0x29, 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_BAD_CCS), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_BAD_FINISHED), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_BAD_FRAGLEN), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_BAD_HANDSHAKE), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_BAD_PARAM), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_BAD_SECRENEG), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_BAD_SIGNATURE), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_BAD_VERSION), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_INVALID_ALGORITHM), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_LIMIT_EXCEEDED), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_NO_CLIENT_AUTH), 0x00, 0x00, 0x01, T0_INT1(BR_ERR_OK), - 0x00, 0x00, 0x01, T0_INT1(BR_ERR_OVERSIZED_ID), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_UNEXPECTED), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_WRONG_KEY_USAGE), 0x00, 0x00, 0x01, - T0_INT2(offsetof(br_ssl_engine_context, action)), 0x00, 0x00, 0x01, - T0_INT2(offsetof(br_ssl_engine_context, alert)), 0x00, 0x00, 0x01, - T0_INT2(offsetof(br_ssl_engine_context, application_data)), 0x00, 0x00, - 0x01, - T0_INT2(offsetof(br_ssl_engine_context, session) + offsetof(br_ssl_session_parameters, cipher_suite)), - 0x00, 0x00, 0x01, - T0_INT2(offsetof(br_ssl_server_context, client_max_version)), 0x00, - 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, client_random)), - 0x00, 0x00, 0x01, - T0_INT2(offsetof(br_ssl_server_context, client_suites)), 0x00, 0x00, - 0x01, T0_INT2(offsetof(br_ssl_server_context, client_suites_num)), - 0x00, 0x00, 0x01, - T0_INT2(offsetof(br_ssl_engine_context, close_received)), 0x00, 0x00, - 0x01, T0_INT2(offsetof(br_ssl_server_context, curves)), 0x00, 0x00, - 0x01, T0_INT2(offsetof(br_ssl_engine_context, ecdhe_point)), 0x00, - 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, ecdhe_point_len)), - 0x00, 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, flags)), - 0x00, 0x00, 0x01, T0_INT2(offsetof(br_ssl_server_context, hashes)), - 0x00, 0x00, 0x7B, 0x01, - T0_INT2(BR_MAX_CIPHER_SUITES * sizeof(br_suite_translated)), 0x00, - 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, log_max_frag_len)), - 0x00, 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, pad)), 0x00, - 0x00, 0x01, - T0_INT2(offsetof(br_ssl_engine_context, peer_log_max_frag_len)), 0x00, - 0x00, 0x01, - T0_INT2(offsetof(br_ssl_engine_context, protocol_names_num)), 0x00, - 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, record_type_in)), - 0x00, 0x00, 0x01, - T0_INT2(offsetof(br_ssl_engine_context, record_type_out)), 0x00, 0x00, - 0x01, T0_INT2(offsetof(br_ssl_engine_context, reneg)), 0x00, 0x00, - 0x01, T0_INT2(offsetof(br_ssl_engine_context, saved_finished)), 0x00, - 0x00, 0x01, - T0_INT2(offsetof(br_ssl_engine_context, selected_protocol)), 0x00, - 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, server_name)), - 0x00, 0x00, 0x01, - T0_INT2(offsetof(br_ssl_engine_context, server_random)), 0x00, 0x00, - 0x01, - T0_INT2(offsetof(br_ssl_engine_context, session) + offsetof(br_ssl_session_parameters, session_id)), - 0x00, 0x00, 0x01, - T0_INT2(offsetof(br_ssl_engine_context, session) + offsetof(br_ssl_session_parameters, session_id_len)), - 0x00, 0x00, 0x01, - T0_INT2(offsetof(br_ssl_engine_context, shutdown_recv)), 0x00, 0x00, - 0x01, T0_INT2(offsetof(br_ssl_server_context, sign_hash_id)), 0x00, - 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, suites_buf)), 0x00, - 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, suites_num)), 0x00, - 0x00, 0x01, - T0_INT2(offsetof(br_ssl_engine_context, session) + offsetof(br_ssl_session_parameters, version)), - 0x00, 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, version_in)), - 0x00, 0x00, 0x01, - T0_INT2(offsetof(br_ssl_engine_context, version_max)), 0x00, 0x00, - 0x01, T0_INT2(offsetof(br_ssl_engine_context, version_min)), 0x00, - 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, version_out)), - 0x00, 0x00, 0x09, 0x2A, 0x5D, 0x06, 0x02, 0x6A, 0x2B, 0x00, 0x00, 0x01, - 0x01, 0x00, 0x01, 0x03, 0x00, 0x9B, 0x2A, 0x63, 0x47, 0x9F, 0x2A, 0x05, - 0x04, 0x65, 0x01, 0x00, 0x00, 0x02, 0x00, 0x0F, 0x06, 0x02, 0x9F, 0x00, - 0x63, 0x04, 0x6B, 0x00, 0x06, 0x02, 0x6A, 0x2B, 0x00, 0x00, 0x2A, 0x8B, - 0x47, 0x05, 0x03, 0x01, 0x0C, 0x08, 0x47, 0x78, 0x2E, 0xA8, 0x1C, 0x85, - 0x01, 0x0C, 0x33, 0x00, 0x00, 0x2A, 0x22, 0x01, 0x08, 0x0C, 0x47, 0x61, - 0x22, 0x08, 0x00, 0x01, 0x03, 0x00, 0x77, 0x30, 0x02, 0x00, 0x38, 0x13, - 0x01, 0x01, 0x0C, 0x77, 0x42, 0x2C, 0x19, 0x38, 0x06, 0x07, 0x02, 0x00, - 0xD0, 0x03, 0x00, 0x04, 0x75, 0x01, 0x00, 0xC7, 0x02, 0x00, 0x2A, 0x19, - 0x13, 0x06, 0x02, 0x71, 0x2B, 0xD0, 0x04, 0x76, 0x00, 0x01, 0x00, 0x77, - 0x42, 0x01, 0x16, 0x89, 0x42, 0x01, 0x00, 0x8C, 0x40, 0x36, 0xB1, 0x35, - 0x06, 0x02, 0x73, 0x2B, 0x06, 0x0A, 0xD7, 0x01, 0x00, 0xD3, 0x01, 0x00, - 0xAD, 0x04, 0x80, 0x46, 0xD7, 0xD4, 0x29, 0xD9, 0x50, 0x06, 0x01, 0xD5, - 0xD8, 0x2C, 0x50, 0x06, 0x31, 0x01, 0x00, 0xAE, 0x2A, 0x5D, 0x06, 0x0F, - 0x01, 0x02, 0xA4, 0x05, 0x02, 0x37, 0x2B, 0x29, 0xB2, 0xB0, 0x2A, 0xC9, - 0x29, 0x04, 0x19, 0x2A, 0x5F, 0x06, 0x0B, 0x29, 0x01, 0x02, 0xA4, 0x05, - 0x02, 0x70, 0x2B, 0xB2, 0x04, 0x0A, 0xB4, 0x2A, 0x05, 0x04, 0x29, 0xAB, - 0x04, 0x02, 0xB3, 0xAF, 0x04, 0x01, 0xB2, 0x01, 0x00, 0xAD, 0x01, 0x00, - 0xD3, 0x3E, 0x01, 0x01, 0x77, 0x42, 0x01, 0x17, 0x89, 0x42, 0x00, 0x00, - 0x3A, 0x3A, 0x00, 0x01, 0x03, 0x00, 0x2C, 0x19, 0x38, 0x06, 0x04, 0xCF, - 0x29, 0x04, 0x78, 0x01, 0x02, 0x02, 0x00, 0xC6, 0x19, 0x38, 0x06, 0x04, - 0xCF, 0x29, 0x04, 0x78, 0x02, 0x00, 0x01, 0x84, 0x00, 0x08, 0x2B, 0x00, - 0x00, 0x81, 0x2F, 0x47, 0x12, 0x01, 0x01, 0x13, 0x37, 0x00, 0x00, 0x2A, - 0x05, 0x04, 0x29, 0x01, 0x7F, 0x00, 0x01, 0x00, 0xA2, 0x12, 0x01, 0x01, - 0x13, 0x5F, 0x06, 0x03, 0x61, 0x04, 0x75, 0x47, 0x29, 0x00, 0x00, 0x01, - 0x7F, 0xA1, 0xCF, 0x2A, 0x01, 0x07, 0x13, 0x01, 0x00, 0x3A, 0x0F, 0x06, - 0x0D, 0x29, 0x01, 0x10, 0x13, 0x06, 0x05, 0x01, 0x00, 0x77, 0x42, 0xC5, - 0x04, 0x33, 0x01, 0x01, 0x3A, 0x0F, 0x06, 0x2A, 0x29, 0x29, 0x8A, 0x30, - 0x01, 0x01, 0x0F, 0x01, 0x01, 0xA4, 0x39, 0x06, 0x18, 0xC8, 0x2C, 0x19, - 0x38, 0x06, 0x04, 0xCF, 0x29, 0x04, 0x78, 0x01, 0x80, 0x64, 0xC7, 0x01, - 0x01, 0x77, 0x42, 0x01, 0x17, 0x89, 0x42, 0x04, 0x03, 0x01, 0x00, 0xA1, - 0x04, 0x03, 0x73, 0x2B, 0x29, 0x04, 0xFF, 0x32, 0x01, 0x2A, 0x03, 0x00, - 0x09, 0x2A, 0x5D, 0x06, 0x02, 0x6A, 0x2B, 0x02, 0x00, 0x00, 0x00, 0x9C, - 0x01, 0x0F, 0x13, 0x00, 0x00, 0x76, 0x30, 0x01, 0x00, 0x3A, 0x0F, 0x06, - 0x10, 0x29, 0x2A, 0x01, 0x01, 0x0E, 0x06, 0x03, 0x29, 0x01, 0x02, 0x76, - 0x42, 0x01, 0x00, 0x04, 0x21, 0x01, 0x01, 0x3A, 0x0F, 0x06, 0x14, 0x29, - 0x01, 0x00, 0x76, 0x42, 0x2A, 0x01, 0x80, 0x64, 0x0F, 0x06, 0x05, 0x01, - 0x82, 0x00, 0x08, 0x2B, 0x5F, 0x04, 0x07, 0x29, 0x01, 0x82, 0x00, 0x08, - 0x2B, 0x29, 0x00, 0x00, 0x01, 0x00, 0x31, 0x06, 0x05, 0x3D, 0xA9, 0x39, - 0x04, 0x78, 0x2A, 0x06, 0x04, 0x01, 0x01, 0x91, 0x42, 0x00, 0x00, 0x01, - 0x1F, 0x13, 0x01, 0x12, 0x0F, 0x05, 0x02, 0x74, 0x2B, 0x78, 0x2E, 0x2A, - 0xCB, 0x05, 0x02, 0x73, 0x2B, 0xA8, 0x28, 0x00, 0x02, 0x87, 0x2E, 0x05, - 0x02, 0xBC, 0x00, 0xC0, 0xA7, 0xC0, 0xA7, 0x01, 0x7E, 0x03, 0x00, 0x2A, - 0x06, 0x17, 0xC2, 0x2A, 0x03, 0x01, 0x85, 0x47, 0xB6, 0x02, 0x01, 0x51, - 0x2A, 0x02, 0x00, 0x53, 0x06, 0x04, 0x03, 0x00, 0x04, 0x01, 0x29, 0x04, - 0x66, 0x9D, 0x9D, 0x02, 0x00, 0x61, 0x8C, 0x40, 0x00, 0x00, 0x31, 0x06, - 0x0B, 0x88, 0x30, 0x01, 0x14, 0x0E, 0x06, 0x02, 0x73, 0x2B, 0x04, 0x11, - 0xCF, 0x01, 0x07, 0x13, 0x2A, 0x01, 0x02, 0x0E, 0x06, 0x06, 0x06, 0x02, - 0x73, 0x2B, 0x04, 0x70, 0x29, 0xC3, 0x01, 0x01, 0x0E, 0x35, 0x39, 0x06, - 0x02, 0x66, 0x2B, 0x2A, 0x01, 0x01, 0xCA, 0x38, 0xB5, 0x00, 0x01, 0xBA, - 0x01, 0x0B, 0x0F, 0x05, 0x02, 0x73, 0x2B, 0x2A, 0x01, 0x03, 0x0F, 0x06, - 0x08, 0xC1, 0x06, 0x02, 0x6A, 0x2B, 0x47, 0x29, 0x00, 0x47, 0x5C, 0xC1, - 0xA7, 0x2A, 0x06, 0x23, 0xC1, 0xA7, 0x2A, 0x5B, 0x2A, 0x06, 0x18, 0x2A, - 0x01, 0x82, 0x00, 0x10, 0x06, 0x05, 0x01, 0x82, 0x00, 0x04, 0x01, 0x2A, - 0x03, 0x00, 0x85, 0x02, 0x00, 0xB6, 0x02, 0x00, 0x58, 0x04, 0x65, 0x9D, - 0x59, 0x04, 0x5A, 0x9D, 0x9D, 0x5A, 0x2A, 0x06, 0x02, 0x37, 0x00, 0x29, - 0x2D, 0x00, 0x02, 0x2A, 0x01, 0x20, 0x13, 0x05, 0x02, 0x74, 0x2B, 0x01, - 0x0F, 0x13, 0x03, 0x00, 0xB0, 0x95, 0x2E, 0x01, 0x86, 0x03, 0x11, 0x06, - 0x23, 0xC0, 0x2A, 0x01, 0x81, 0x7F, 0x13, 0x61, 0x01, 0x01, 0x12, 0x02, - 0x00, 0x0F, 0x05, 0x02, 0x6C, 0x2B, 0x01, 0x08, 0x12, 0x2A, 0x01, 0x02, - 0x0B, 0x3A, 0x01, 0x06, 0x10, 0x39, 0x06, 0x02, 0x6E, 0x2B, 0x04, 0x0D, - 0x02, 0x00, 0x01, 0x01, 0x0F, 0x06, 0x04, 0x01, 0x00, 0x04, 0x02, 0x01, - 0x02, 0x20, 0x05, 0x02, 0x6E, 0x2B, 0xC0, 0x2A, 0x03, 0x01, 0x2A, 0x01, - 0x84, 0x00, 0x10, 0x06, 0x02, 0x6F, 0x2B, 0x85, 0x47, 0xB6, 0x02, 0x01, - 0x55, 0x2A, 0x06, 0x01, 0x2B, 0x29, 0x9D, 0x00, 0x00, 0x1D, 0xBA, 0x01, - 0x0F, 0x0F, 0x05, 0x02, 0x73, 0x2B, 0x00, 0x0A, 0xBA, 0x01, 0x01, 0x0F, - 0x05, 0x02, 0x73, 0x2B, 0xC0, 0x2A, 0x03, 0x00, 0x79, 0x40, 0x7A, 0x01, - 0x20, 0xB6, 0xC2, 0x2A, 0x01, 0x20, 0x10, 0x06, 0x02, 0x72, 0x2B, 0x2A, - 0x90, 0x42, 0x8F, 0x47, 0xB6, 0x1A, 0x03, 0x01, 0xC0, 0xA7, 0x01, 0x00, - 0x03, 0x02, 0x01, 0x00, 0x03, 0x03, 0x83, 0xA2, 0x17, 0x3A, 0x08, 0x03, - 0x04, 0x03, 0x05, 0x2A, 0x06, 0x80, 0x6D, 0xC0, 0x2A, 0x03, 0x06, 0x02, - 0x01, 0x06, 0x0A, 0x2A, 0x78, 0x2E, 0x0F, 0x06, 0x04, 0x01, 0x7F, 0x03, - 0x03, 0x2A, 0x01, 0x81, 0x7F, 0x0F, 0x06, 0x0A, 0x8A, 0x30, 0x06, 0x02, - 0x6B, 0x2B, 0x01, 0x7F, 0x03, 0x02, 0x2A, 0x01, 0x81, 0xAC, 0x00, 0x0F, - 0x06, 0x11, 0x02, 0x00, 0x98, 0x2E, 0x11, 0x02, 0x00, 0x97, 0x2E, 0x0B, - 0x13, 0x06, 0x04, 0x01, 0x7F, 0x03, 0x00, 0xC4, 0x2A, 0x5D, 0x06, 0x03, - 0x29, 0x04, 0x26, 0x01, 0x00, 0xA4, 0x06, 0x0B, 0x01, 0x02, 0x0C, 0x7B, - 0x08, 0x02, 0x06, 0x47, 0x40, 0x04, 0x16, 0x29, 0x02, 0x05, 0x02, 0x04, - 0x11, 0x06, 0x02, 0x69, 0x2B, 0x02, 0x06, 0x02, 0x05, 0x40, 0x02, 0x05, - 0x01, 0x04, 0x08, 0x03, 0x05, 0x04, 0xFF, 0x0F, 0x29, 0x01, 0x00, 0x03, - 0x07, 0xC2, 0xA7, 0x2A, 0x06, 0x09, 0xC2, 0x05, 0x04, 0x01, 0x7F, 0x03, - 0x07, 0x04, 0x74, 0x9D, 0x01, 0x00, 0x8D, 0x42, 0x01, 0x88, 0x04, 0x82, - 0x41, 0x01, 0x84, 0x80, 0x80, 0x00, 0x7E, 0x41, 0x2A, 0x06, 0x80, 0x4E, - 0xC0, 0xA7, 0x2A, 0x06, 0x80, 0x47, 0xC0, 0x01, 0x00, 0x3A, 0x0F, 0x06, - 0x04, 0x29, 0xB9, 0x04, 0x39, 0x01, 0x01, 0x3A, 0x0F, 0x06, 0x04, 0x29, - 0xB7, 0x04, 0x2F, 0x01, 0x83, 0xFE, 0x01, 0x3A, 0x0F, 0x06, 0x04, 0x29, - 0xB8, 0x04, 0x23, 0x01, 0x0D, 0x3A, 0x0F, 0x06, 0x04, 0x29, 0xBE, 0x04, - 0x19, 0x01, 0x0A, 0x3A, 0x0F, 0x06, 0x04, 0x29, 0xBF, 0x04, 0x0F, 0x01, - 0x10, 0x3A, 0x0F, 0x06, 0x04, 0x29, 0xAC, 0x04, 0x05, 0x29, 0xBC, 0x01, - 0x00, 0x29, 0x04, 0xFF, 0x35, 0x9D, 0x9D, 0x02, 0x01, 0x02, 0x03, 0x13, - 0x03, 0x01, 0x02, 0x00, 0x5D, 0x06, 0x08, 0x79, 0x2E, 0x99, 0x40, 0x01, - 0x80, 0x56, 0xA3, 0x97, 0x2E, 0x2A, 0x02, 0x00, 0x10, 0x06, 0x03, 0x29, - 0x02, 0x00, 0x2A, 0x01, 0x86, 0x00, 0x0B, 0x06, 0x02, 0x6D, 0x2B, 0x02, - 0x00, 0x98, 0x2E, 0x0B, 0x06, 0x04, 0x01, 0x80, 0x46, 0xA3, 0x02, 0x01, - 0x06, 0x10, 0x95, 0x2E, 0x02, 0x00, 0x0D, 0x06, 0x05, 0x29, 0x95, 0x2E, - 0x04, 0x04, 0x01, 0x00, 0x03, 0x01, 0x2A, 0x95, 0x40, 0x2A, 0x96, 0x40, - 0x2A, 0x99, 0x40, 0x01, 0x86, 0x03, 0x11, 0x03, 0x08, 0x02, 0x02, 0x06, - 0x04, 0x01, 0x02, 0x8A, 0x42, 0x8A, 0x30, 0x05, 0x04, 0x01, 0x01, 0x8A, - 0x42, 0x02, 0x07, 0x05, 0x03, 0x01, 0x28, 0xA3, 0x44, 0x29, 0x01, 0x82, - 0x01, 0x07, 0x01, 0xFC, 0x80, 0x00, 0x39, 0x82, 0x2F, 0x13, 0x2A, 0x82, - 0x41, 0x2A, 0x01, 0x81, 0x7F, 0x13, 0x5E, 0x37, 0x47, 0x01, 0x08, 0x12, - 0x5E, 0x01, 0x02, 0x13, 0x39, 0x01, 0x0C, 0x0C, 0x03, 0x09, 0x7E, 0x2F, - 0x43, 0x13, 0x2A, 0x7E, 0x41, 0x05, 0x04, 0x01, 0x00, 0x03, 0x09, 0x02, - 0x01, 0x06, 0x03, 0x01, 0x7F, 0x00, 0x8F, 0x01, 0x20, 0x34, 0x01, 0x20, - 0x90, 0x42, 0x7B, 0x2A, 0x03, 0x05, 0x2A, 0x02, 0x04, 0x0B, 0x06, 0x80, - 0x49, 0x2A, 0x2E, 0x2A, 0x9C, 0x2A, 0x01, 0x0C, 0x12, 0x2A, 0x01, 0x01, - 0x0F, 0x47, 0x01, 0x02, 0x0F, 0x39, 0x06, 0x0A, 0x2A, 0x02, 0x09, 0x13, - 0x05, 0x04, 0x65, 0x01, 0x00, 0x2A, 0x02, 0x08, 0x05, 0x0E, 0x2A, 0x01, - 0x81, 0x70, 0x13, 0x01, 0x20, 0x0E, 0x06, 0x04, 0x65, 0x01, 0x00, 0x2A, - 0x2A, 0x06, 0x10, 0x02, 0x05, 0x63, 0x40, 0x02, 0x05, 0x40, 0x02, 0x05, - 0x01, 0x04, 0x08, 0x03, 0x05, 0x04, 0x01, 0x65, 0x01, 0x04, 0x08, 0x04, - 0xFF, 0x30, 0x29, 0x02, 0x05, 0x7B, 0x09, 0x01, 0x02, 0x12, 0x2A, 0x05, - 0x03, 0x01, 0x28, 0xA3, 0x7C, 0x42, 0x8C, 0x2E, 0x01, 0x83, 0xFF, 0x7F, - 0x0F, 0x06, 0x0D, 0x01, 0x03, 0xA4, 0x06, 0x04, 0x01, 0x80, 0x78, 0xA3, - 0x01, 0x00, 0x8C, 0x40, 0x18, 0x05, 0x03, 0x01, 0x28, 0xA3, 0x01, 0x00, - 0x00, 0x00, 0xB4, 0xB3, 0x00, 0x04, 0x78, 0x2E, 0xCE, 0x06, 0x16, 0xC0, - 0x2A, 0x01, 0x84, 0x00, 0x10, 0x06, 0x02, 0x6F, 0x2B, 0x2A, 0x03, 0x00, - 0x85, 0x47, 0xB6, 0x02, 0x00, 0x78, 0x2E, 0xA8, 0x27, 0x78, 0x2E, 0x2A, - 0xCC, 0x47, 0xCB, 0x03, 0x01, 0x03, 0x02, 0x02, 0x01, 0x02, 0x02, 0x39, - 0x06, 0x14, 0xC2, 0x2A, 0x03, 0x03, 0x85, 0x47, 0xB6, 0x02, 0x03, 0x78, - 0x2E, 0xA8, 0x02, 0x02, 0x06, 0x03, 0x26, 0x04, 0x01, 0x24, 0x9D, 0x00, - 0x00, 0xBA, 0x01, 0x10, 0x0F, 0x05, 0x02, 0x73, 0x2B, 0x00, 0x00, 0x9E, - 0xBA, 0x01, 0x14, 0x0E, 0x06, 0x02, 0x73, 0x2B, 0x85, 0x01, 0x0C, 0x08, - 0x01, 0x0C, 0xB6, 0x9D, 0x85, 0x2A, 0x01, 0x0C, 0x08, 0x01, 0x0C, 0x32, - 0x05, 0x02, 0x67, 0x2B, 0x00, 0x02, 0x03, 0x00, 0x03, 0x01, 0x02, 0x00, - 0x9A, 0x02, 0x01, 0x02, 0x00, 0x3C, 0x2A, 0x01, 0x00, 0x0F, 0x06, 0x02, - 0x65, 0x00, 0xD1, 0x04, 0x74, 0x00, 0xC0, 0x01, 0x01, 0x0E, 0x06, 0x02, - 0x68, 0x2B, 0xC2, 0x2A, 0x2A, 0x5F, 0x47, 0x01, 0x05, 0x11, 0x39, 0x06, - 0x02, 0x68, 0x2B, 0x01, 0x08, 0x08, 0x2A, 0x84, 0x30, 0x0B, 0x06, 0x0D, - 0x2A, 0x01, 0x01, 0x47, 0x0C, 0x3F, 0x2A, 0x84, 0x42, 0x86, 0x42, 0x04, - 0x01, 0x29, 0x00, 0x00, 0xC0, 0x8A, 0x30, 0x01, 0x00, 0x3A, 0x0F, 0x06, - 0x13, 0x29, 0x01, 0x01, 0x0F, 0x05, 0x02, 0x6B, 0x2B, 0xC2, 0x06, 0x02, - 0x6B, 0x2B, 0x01, 0x02, 0x8A, 0x42, 0x04, 0x28, 0x01, 0x02, 0x3A, 0x0F, - 0x06, 0x1F, 0x29, 0x01, 0x0D, 0x0F, 0x05, 0x02, 0x6B, 0x2B, 0xC2, 0x01, - 0x0C, 0x0F, 0x05, 0x02, 0x6B, 0x2B, 0x85, 0x01, 0x0C, 0xB6, 0x8B, 0x85, - 0x01, 0x0C, 0x32, 0x05, 0x02, 0x6B, 0x2B, 0x04, 0x03, 0x6B, 0x2B, 0x29, - 0x00, 0x00, 0xC0, 0xA7, 0xC0, 0xA7, 0x2A, 0x06, 0x1D, 0xC2, 0x06, 0x03, - 0xBC, 0x04, 0x15, 0xC0, 0x2A, 0x01, 0x81, 0x7F, 0x0D, 0x06, 0x0C, 0x2A, - 0x8D, 0x08, 0x01, 0x00, 0x47, 0x42, 0x8D, 0x47, 0xB6, 0x04, 0x01, 0xC9, - 0x04, 0x60, 0x9D, 0x9D, 0x00, 0x00, 0xBB, 0x2A, 0x5F, 0x06, 0x07, 0x29, - 0x06, 0x02, 0x69, 0x2B, 0x04, 0x74, 0x00, 0x00, 0xC3, 0x01, 0x03, 0xC1, - 0x47, 0x29, 0x47, 0x00, 0x00, 0xC0, 0xC9, 0x00, 0x03, 0x01, 0x00, 0x03, - 0x00, 0xC0, 0xA7, 0x2A, 0x06, 0x80, 0x50, 0xC2, 0x03, 0x01, 0xC2, 0x03, - 0x02, 0x02, 0x01, 0x01, 0x08, 0x0F, 0x06, 0x16, 0x02, 0x02, 0x01, 0x0F, - 0x0D, 0x06, 0x0D, 0x01, 0x01, 0x02, 0x02, 0x01, 0x10, 0x08, 0x0C, 0x02, - 0x00, 0x39, 0x03, 0x00, 0x04, 0x2A, 0x02, 0x01, 0x01, 0x02, 0x11, 0x02, - 0x01, 0x01, 0x06, 0x0D, 0x13, 0x02, 0x02, 0x01, 0x01, 0x0F, 0x02, 0x02, - 0x01, 0x03, 0x0F, 0x39, 0x13, 0x06, 0x11, 0x02, 0x00, 0x01, 0x01, 0x02, - 0x02, 0x62, 0x01, 0x02, 0x0C, 0x02, 0x01, 0x08, 0x0C, 0x39, 0x03, 0x00, - 0x04, 0xFF, 0x2C, 0x9D, 0x02, 0x00, 0x00, 0x00, 0xC0, 0xA7, 0xBD, 0x82, - 0x41, 0x9D, 0x00, 0x00, 0xC0, 0xA7, 0xC0, 0xA7, 0x01, 0x00, 0x7E, 0x41, - 0x2A, 0x06, 0x15, 0xC0, 0x2A, 0x01, 0x20, 0x0B, 0x06, 0x0B, 0x01, 0x01, - 0x47, 0x0C, 0x7E, 0x2F, 0x39, 0x7E, 0x41, 0x04, 0x01, 0x29, 0x04, 0x68, - 0x9D, 0x9D, 0x00, 0x00, 0x01, 0x02, 0x9A, 0xC3, 0x01, 0x08, 0x0C, 0xC3, - 0x08, 0x00, 0x00, 0x01, 0x03, 0x9A, 0xC3, 0x01, 0x08, 0x0C, 0xC3, 0x08, - 0x01, 0x08, 0x0C, 0xC3, 0x08, 0x00, 0x00, 0x01, 0x01, 0x9A, 0xC3, 0x00, - 0x00, 0x3D, 0x2A, 0x5D, 0x05, 0x01, 0x00, 0x29, 0xD1, 0x04, 0x76, 0x02, - 0x03, 0x00, 0x94, 0x30, 0x03, 0x01, 0x01, 0x00, 0x2A, 0x02, 0x01, 0x0B, - 0x06, 0x10, 0x2A, 0x01, 0x01, 0x0C, 0x93, 0x08, 0x2E, 0x02, 0x00, 0x0F, - 0x06, 0x01, 0x00, 0x61, 0x04, 0x6A, 0x29, 0x01, 0x7F, 0x00, 0x00, 0x2C, - 0x19, 0x38, 0x06, 0x04, 0xCF, 0x29, 0x04, 0x78, 0x01, 0x16, 0x89, 0x42, - 0x01, 0x00, 0xE2, 0x01, 0x00, 0xE1, 0x2C, 0x01, 0x17, 0x89, 0x42, 0x00, - 0x00, 0x01, 0x15, 0x89, 0x42, 0x47, 0x57, 0x29, 0x57, 0x29, 0x2C, 0x00, - 0x00, 0x01, 0x01, 0x47, 0xC6, 0x00, 0x00, 0xBB, 0x01, 0x01, 0x0F, 0x05, - 0x02, 0x73, 0x2B, 0x2A, 0xC9, 0x29, 0x00, 0x00, 0x47, 0x3A, 0x9A, 0x47, - 0x2A, 0x06, 0x05, 0xC3, 0x29, 0x62, 0x04, 0x78, 0x29, 0x00, 0x02, 0x03, - 0x00, 0x78, 0x2E, 0x9C, 0x03, 0x01, 0x02, 0x01, 0x01, 0x0F, 0x13, 0x02, - 0x01, 0x01, 0x04, 0x12, 0x01, 0x0F, 0x13, 0x02, 0x01, 0x01, 0x08, 0x12, - 0x01, 0x0F, 0x13, 0x01, 0x00, 0x3A, 0x0F, 0x06, 0x10, 0x29, 0x01, 0x00, - 0x01, 0x18, 0x02, 0x00, 0x06, 0x03, 0x4C, 0x04, 0x01, 0x4D, 0x04, 0x81, - 0x0D, 0x01, 0x01, 0x3A, 0x0F, 0x06, 0x10, 0x29, 0x01, 0x01, 0x01, 0x10, - 0x02, 0x00, 0x06, 0x03, 0x4C, 0x04, 0x01, 0x4D, 0x04, 0x80, 0x77, 0x01, - 0x02, 0x3A, 0x0F, 0x06, 0x10, 0x29, 0x01, 0x01, 0x01, 0x20, 0x02, 0x00, - 0x06, 0x03, 0x4C, 0x04, 0x01, 0x4D, 0x04, 0x80, 0x61, 0x01, 0x03, 0x3A, - 0x0F, 0x06, 0x0F, 0x29, 0x29, 0x01, 0x10, 0x02, 0x00, 0x06, 0x03, 0x4A, - 0x04, 0x01, 0x4B, 0x04, 0x80, 0x4C, 0x01, 0x04, 0x3A, 0x0F, 0x06, 0x0E, - 0x29, 0x29, 0x01, 0x20, 0x02, 0x00, 0x06, 0x03, 0x4A, 0x04, 0x01, 0x4B, - 0x04, 0x38, 0x01, 0x05, 0x3A, 0x0F, 0x06, 0x0C, 0x29, 0x29, 0x02, 0x00, - 0x06, 0x03, 0x4E, 0x04, 0x01, 0x4F, 0x04, 0x26, 0x2A, 0x01, 0x09, 0x10, - 0x06, 0x02, 0x6A, 0x2B, 0x47, 0x29, 0x2A, 0x01, 0x01, 0x13, 0x01, 0x04, - 0x0C, 0x01, 0x10, 0x08, 0x47, 0x01, 0x08, 0x13, 0x01, 0x10, 0x47, 0x09, - 0x02, 0x00, 0x06, 0x03, 0x48, 0x04, 0x01, 0x49, 0x00, 0x29, 0x00, 0x00, - 0x9C, 0x01, 0x0C, 0x12, 0x01, 0x02, 0x10, 0x00, 0x00, 0x9C, 0x01, 0x0C, - 0x12, 0x2A, 0x60, 0x47, 0x01, 0x03, 0x0B, 0x13, 0x00, 0x00, 0x9C, 0x01, - 0x0C, 0x12, 0x01, 0x01, 0x0F, 0x00, 0x00, 0x9C, 0x01, 0x0C, 0x12, 0x5F, - 0x00, 0x00, 0x1B, 0x01, 0x00, 0x75, 0x30, 0x2A, 0x06, 0x22, 0x01, 0x01, - 0x3A, 0x0F, 0x06, 0x06, 0x29, 0x01, 0x00, 0xA0, 0x04, 0x14, 0x01, 0x02, - 0x3A, 0x0F, 0x06, 0x0D, 0x29, 0x77, 0x30, 0x01, 0x01, 0x0F, 0x06, 0x03, - 0x01, 0x10, 0x39, 0x04, 0x01, 0x29, 0x04, 0x01, 0x29, 0x7D, 0x30, 0x05, - 0x33, 0x31, 0x06, 0x30, 0x88, 0x30, 0x01, 0x14, 0x3A, 0x0F, 0x06, 0x06, - 0x29, 0x01, 0x02, 0x39, 0x04, 0x22, 0x01, 0x15, 0x3A, 0x0F, 0x06, 0x09, - 0x29, 0xAA, 0x06, 0x03, 0x01, 0x7F, 0xA0, 0x04, 0x13, 0x01, 0x16, 0x3A, - 0x0F, 0x06, 0x06, 0x29, 0x01, 0x01, 0x39, 0x04, 0x07, 0x29, 0x01, 0x04, - 0x39, 0x01, 0x00, 0x29, 0x19, 0x06, 0x03, 0x01, 0x08, 0x39, 0x00, 0x00, - 0x1B, 0x2A, 0x05, 0x13, 0x31, 0x06, 0x10, 0x88, 0x30, 0x01, 0x15, 0x0F, - 0x06, 0x08, 0x29, 0xAA, 0x01, 0x00, 0x77, 0x42, 0x04, 0x01, 0x23, 0x00, - 0x00, 0xCF, 0x01, 0x07, 0x13, 0x01, 0x01, 0x10, 0x06, 0x02, 0x73, 0x2B, - 0x00, 0x01, 0x03, 0x00, 0x2C, 0x19, 0x06, 0x05, 0x02, 0x00, 0x89, 0x42, - 0x00, 0xCF, 0x29, 0x04, 0x74, 0x00, 0x01, 0x14, 0xD2, 0x01, 0x01, 0xE2, - 0x2C, 0x2A, 0x01, 0x00, 0xCA, 0x01, 0x16, 0xD2, 0xD6, 0x2C, 0x00, 0x00, - 0x01, 0x0B, 0xE2, 0x52, 0x2A, 0x2A, 0x01, 0x03, 0x08, 0xE1, 0xE1, 0x14, - 0x2A, 0x5D, 0x06, 0x02, 0x29, 0x00, 0xE1, 0x1E, 0x2A, 0x06, 0x05, 0x85, - 0x47, 0xDA, 0x04, 0x77, 0x29, 0x04, 0x6C, 0x00, 0x01, 0x00, 0xDC, 0x95, - 0x2E, 0x01, 0x86, 0x03, 0x11, 0x06, 0x05, 0x63, 0x01, 0x00, 0xDD, 0x08, - 0x50, 0x08, 0x01, 0x03, 0x08, 0x01, 0x0D, 0xE2, 0xE1, 0x01, 0x00, 0xDC, - 0xE2, 0x01, 0x01, 0xDC, 0x29, 0x95, 0x2E, 0x01, 0x86, 0x03, 0x11, 0x06, - 0x08, 0x01, 0x00, 0xDD, 0xE0, 0x01, 0x01, 0xDD, 0x29, 0x50, 0xE0, 0x16, - 0x15, 0x2A, 0x5D, 0x06, 0x02, 0x29, 0x00, 0xE0, 0x1F, 0x2A, 0x06, 0x05, - 0x85, 0x47, 0xDA, 0x04, 0x77, 0x29, 0x04, 0x6C, 0x00, 0x9E, 0x01, 0x14, - 0xE2, 0x01, 0x0C, 0xE1, 0x85, 0x01, 0x0C, 0xDA, 0x00, 0x04, 0x03, 0x00, - 0x01, 0x02, 0xE2, 0x01, 0x80, 0x46, 0x8A, 0x30, 0x01, 0x02, 0x0F, 0x06, - 0x0C, 0x02, 0x00, 0x06, 0x04, 0x01, 0x05, 0x04, 0x02, 0x01, 0x1D, 0x04, - 0x02, 0x01, 0x00, 0x03, 0x01, 0x86, 0x30, 0x06, 0x04, 0x01, 0x05, 0x04, - 0x02, 0x01, 0x00, 0x03, 0x02, 0x8C, 0x2E, 0x2A, 0x06, 0x05, 0x62, 0x21, - 0x01, 0x07, 0x08, 0x03, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x02, 0x03, - 0x08, 0x2A, 0x06, 0x03, 0x01, 0x02, 0x08, 0x08, 0xE1, 0x95, 0x2E, 0xE0, - 0x8E, 0x01, 0x04, 0x17, 0x8E, 0x01, 0x04, 0x08, 0x01, 0x1C, 0x34, 0x8E, - 0x01, 0x20, 0xDA, 0x01, 0x20, 0xE2, 0x8F, 0x01, 0x20, 0xDA, 0x78, 0x2E, - 0xE0, 0x01, 0x00, 0xE2, 0x02, 0x01, 0x02, 0x02, 0x08, 0x02, 0x03, 0x08, - 0x2A, 0x06, 0x80, 0x40, 0xE0, 0x02, 0x01, 0x2A, 0x06, 0x10, 0x01, 0x83, - 0xFE, 0x01, 0xE0, 0x01, 0x04, 0x09, 0x2A, 0xE0, 0x62, 0x8B, 0x47, 0xDB, - 0x04, 0x01, 0x29, 0x02, 0x02, 0x06, 0x0C, 0x01, 0x01, 0xE0, 0x01, 0x01, - 0xE0, 0x86, 0x30, 0x01, 0x08, 0x09, 0xE2, 0x02, 0x03, 0x2A, 0x06, 0x11, - 0x01, 0x10, 0xE0, 0x01, 0x04, 0x09, 0x2A, 0xE0, 0x64, 0x2A, 0xE0, 0x62, - 0x85, 0x47, 0xDB, 0x04, 0x01, 0x29, 0x04, 0x01, 0x29, 0x00, 0x00, 0x01, - 0x0E, 0xE2, 0x01, 0x00, 0xE1, 0x00, 0x03, 0x78, 0x2E, 0xCC, 0x05, 0x01, - 0x00, 0x7E, 0x2F, 0x2A, 0x01, 0x82, 0x80, 0x80, 0x80, 0x00, 0x13, 0x06, - 0x05, 0x29, 0x01, 0x1D, 0x04, 0x0E, 0x2A, 0x01, 0x83, 0xC0, 0x80, 0x80, - 0x00, 0x13, 0x2A, 0x06, 0x01, 0x47, 0x29, 0xA5, 0x03, 0x00, 0x02, 0x00, - 0x25, 0x2A, 0x5D, 0x06, 0x02, 0x37, 0x2B, 0x03, 0x01, 0x95, 0x2E, 0x01, - 0x86, 0x03, 0x11, 0x03, 0x02, 0x01, 0x0C, 0xE2, 0x02, 0x01, 0x80, 0x30, - 0x08, 0x02, 0x02, 0x01, 0x02, 0x13, 0x08, 0x01, 0x06, 0x08, 0xE1, 0x01, - 0x03, 0xE2, 0x02, 0x00, 0xE0, 0x7F, 0x80, 0x30, 0xDB, 0x02, 0x02, 0x06, - 0x1C, 0x92, 0x2E, 0x2A, 0x01, 0x83, 0xFE, 0x00, 0x0B, 0x06, 0x03, 0xE0, - 0x04, 0x0F, 0x01, 0x81, 0x7F, 0x13, 0xE2, 0x78, 0x2E, 0xCD, 0x01, 0x01, - 0x0C, 0x01, 0x03, 0x08, 0xE2, 0x02, 0x01, 0xE0, 0x85, 0x02, 0x01, 0xDA, - 0x00, 0x00, 0x56, 0x2A, 0x01, 0x00, 0x0F, 0x06, 0x02, 0x65, 0x00, 0xCF, - 0x29, 0x04, 0x73, 0x00, 0x2A, 0xE2, 0xDA, 0x00, 0x00, 0x01, 0x00, 0x78, - 0x2E, 0xCB, 0x06, 0x0C, 0x63, 0x3A, 0x06, 0x08, 0x01, 0x80, 0x41, 0xE2, - 0x01, 0x80, 0x42, 0xE2, 0x46, 0x06, 0x07, 0x61, 0x3A, 0x06, 0x03, 0x01, - 0x01, 0xE2, 0x45, 0x06, 0x08, 0x61, 0x3A, 0x06, 0x04, 0x01, 0x80, 0x40, - 0xE2, 0x47, 0x29, 0x00, 0x01, 0x01, 0x00, 0x03, 0x00, 0x46, 0x45, 0x39, - 0x05, 0x14, 0x01, 0x01, 0x01, 0x80, 0x7C, 0xDE, 0x03, 0x00, 0x01, 0x03, - 0x01, 0x80, 0x7C, 0xDE, 0x02, 0x00, 0x08, 0x47, 0x29, 0x00, 0x46, 0x06, - 0x07, 0x01, 0x01, 0x44, 0x29, 0xDE, 0x03, 0x00, 0x45, 0x06, 0x0A, 0x01, - 0x03, 0x44, 0x29, 0xDE, 0x02, 0x00, 0x08, 0x03, 0x00, 0x29, 0x02, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x01, 0x04, 0xDF, 0x01, 0x05, 0xDF, 0x01, 0x06, - 0xDF, 0x01, 0x03, 0xDF, 0x01, 0x02, 0xDF, 0x0A, 0x65, 0x00, 0x01, 0x03, - 0x00, 0x3A, 0x01, 0x01, 0x02, 0x00, 0x0C, 0x13, 0x05, 0x01, 0x00, 0x63, - 0x01, 0x03, 0x3B, 0x06, 0x07, 0x02, 0x00, 0xE2, 0x01, 0x02, 0x3B, 0xE2, - 0x00, 0x00, 0x2A, 0x01, 0x08, 0x54, 0xE2, 0xE2, 0x00, 0x00, 0x2A, 0x01, - 0x10, 0x54, 0xE2, 0xE0, 0x00, 0x00, 0x2A, 0x57, 0x06, 0x02, 0x29, 0x00, - 0xCF, 0x29, 0x04, 0x76 -}; - -static const uint16_t t0_caddr[] = { - 0, - 5, - 10, - 15, - 20, - 25, - 30, - 35, - 40, - 44, - 48, - 52, - 56, - 60, - 64, - 68, - 72, - 76, - 80, - 84, - 88, - 92, - 96, - 100, - 104, - 109, - 114, - 119, - 124, - 129, - 134, - 139, - 144, - 149, - 154, - 159, - 164, - 169, - 174, - 180, - 185, - 190, - 195, - 200, - 205, - 210, - 215, - 220, - 225, - 230, - 235, - 240, - 245, - 250, - 255, - 260, - 265, - 270, - 275, - 280, - 285, - 290, - 299, - 303, - 328, - 334, - 353, - 364, - 405, - 516, - 520, - 553, - 563, - 587, - 669, - 683, - 689, - 748, - 767, - 789, - 838, - 887, - 963, - 1065, - 1076, - 1670, - 1674, - 1741, - 1751, - 1782, - 1806, - 1852, - 1922, - 1962, - 1976, - 1985, - 1989, - 2084, - 2092, - 2128, - 2139, - 2155, - 2161, - 2172, - 2207, - 2233, - 2245, - 2251, - 2264, - 2279, - 2472, - 2481, - 2494, - 2503, - 2510, - 2616, - 2641, - 2654, - 2670, - 2688, - 2720, - 2793, - 2806, - 2987, - 2995, - 3122, - 3136, - 3141, - 3185, - 3242, - 3263, - 3290, - 3298, - 3306 -}; - -#define T0_INTERPRETED 93 - -#define T0_ENTER(ip, rp, slot) do { \ - const unsigned char *t0_newip; \ - uint32_t t0_lnum; \ - t0_newip = &t0_codeblock[t0_caddr[(slot) - T0_INTERPRETED]]; \ - t0_lnum = t0_parse7E_unsigned(&t0_newip); \ - (rp) += t0_lnum; \ - *((rp) ++) = (uint32_t)((ip) - &t0_codeblock[0]) + (t0_lnum << 16); \ - (ip) = t0_newip; \ - } while (0) - -#define T0_DEFENTRY(name, slot) \ -void \ -name(void *ctx) \ -{ \ - t0_context *t0ctx = ctx; \ - t0ctx->ip = &t0_codeblock[0]; \ - T0_ENTER(t0ctx->ip, t0ctx->rp, slot); \ -} - -T0_DEFENTRY(br_ssl_hs_server_init_main, 166) - -#define T0_NEXT(t0ipp) (*(*(t0ipp)) ++) - -void -br_ssl_hs_server_run(void *t0ctx) -{ - uint32_t *dp, *rp; - const unsigned char *ip; - -#define T0_LOCAL(x) (*(rp - 2 - (x))) -#define T0_POP() (*-- dp) -#define T0_POPi() (*(int32_t *)(-- dp)) -#define T0_PEEK(x) (*(dp - 1 - (x))) -#define T0_PEEKi(x) (*(int32_t *)(dp - 1 - (x))) -#define T0_PUSH(v) do { *dp = (v); dp ++; } while (0) -#define T0_PUSHi(v) do { *(int32_t *)dp = (v); dp ++; } while (0) -#define T0_RPOP() (*-- rp) -#define T0_RPOPi() (*(int32_t *)(-- rp)) -#define T0_RPUSH(v) do { *rp = (v); rp ++; } while (0) -#define T0_RPUSHi(v) do { *(int32_t *)rp = (v); rp ++; } while (0) -#define T0_ROLL(x) do { \ - size_t t0len = (size_t)(x); \ - uint32_t t0tmp = *(dp - 1 - t0len); \ - memmove(dp - t0len - 1, dp - t0len, t0len * sizeof *dp); \ - *(dp - 1) = t0tmp; \ -} while (0) -#define T0_SWAP() do { \ - uint32_t t0tmp = *(dp - 2); \ - *(dp - 2) = *(dp - 1); \ - *(dp - 1) = t0tmp; \ -} while (0) -#define T0_ROT() do { \ - uint32_t t0tmp = *(dp - 3); \ - *(dp - 3) = *(dp - 2); \ - *(dp - 2) = *(dp - 1); \ - *(dp - 1) = t0tmp; \ -} while (0) -#define T0_NROT() do { \ - uint32_t t0tmp = *(dp - 1); \ - *(dp - 1) = *(dp - 2); \ - *(dp - 2) = *(dp - 3); \ - *(dp - 3) = t0tmp; \ -} while (0) -#define T0_PICK(x) do { \ - uint32_t t0depth = (x); \ - T0_PUSH(T0_PEEK(t0depth)); \ -} while (0) -#define T0_CO() do { \ - goto t0_exit; \ -} while (0) -#define T0_RET() goto t0_next - - dp = ((t0_context *)t0ctx)->dp; - rp = ((t0_context *)t0ctx)->rp; - ip = ((t0_context *)t0ctx)->ip; - goto t0_next; - for (;;) { - uint32_t t0x; - - t0_next: - t0x = T0_NEXT(&ip); - if (t0x < T0_INTERPRETED) { - switch (t0x) { - int32_t t0off; - - case 0: /* ret */ - t0x = T0_RPOP(); - rp -= (t0x >> 16); - t0x &= 0xFFFF; - if (t0x == 0) { - ip = NULL; - goto t0_exit; - } - ip = &t0_codeblock[t0x]; - break; - case 1: /* literal constant */ - T0_PUSHi(t0_parse7E_signed(&ip)); - break; - case 2: /* read local */ - T0_PUSH(T0_LOCAL(t0_parse7E_unsigned(&ip))); - break; - case 3: /* write local */ - T0_LOCAL(t0_parse7E_unsigned(&ip)) = T0_POP(); - break; - case 4: /* jump */ - t0off = t0_parse7E_signed(&ip); - ip += t0off; - break; - case 5: /* jump if */ - t0off = t0_parse7E_signed(&ip); - if (T0_POP()) { - ip += t0off; - } - break; - case 6: /* jump if not */ - t0off = t0_parse7E_signed(&ip); - if (!T0_POP()) { - ip += t0off; - } - break; - case 7: { - /* * */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(a * b); - - } - break; - case 8: { - /* + */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(a + b); - - } - break; - case 9: { - /* - */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(a - b); - - } - break; - case 10: { - /* -rot */ - T0_NROT(); - } - break; - case 11: { - /* < */ - - int32_t b = T0_POPi(); - int32_t a = T0_POPi(); - T0_PUSH(-(uint32_t)(a < b)); - - } - break; - case 12: { - /* << */ - - int c = (int)T0_POPi(); - uint32_t x = T0_POP(); - T0_PUSH(x << c); - - } - break; - case 13: { - /* <= */ - - int32_t b = T0_POPi(); - int32_t a = T0_POPi(); - T0_PUSH(-(uint32_t)(a <= b)); - - } - break; - case 14: { - /* <> */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(-(uint32_t)(a != b)); - - } - break; - case 15: { - /* = */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(-(uint32_t)(a == b)); - - } - break; - case 16: { - /* > */ - - int32_t b = T0_POPi(); - int32_t a = T0_POPi(); - T0_PUSH(-(uint32_t)(a > b)); - - } - break; - case 17: { - /* >= */ - - int32_t b = T0_POPi(); - int32_t a = T0_POPi(); - T0_PUSH(-(uint32_t)(a >= b)); - - } - break; - case 18: { - /* >> */ - - int c = (int)T0_POPi(); - int32_t x = T0_POPi(); - T0_PUSHi(x >> c); - - } - break; - case 19: { - /* and */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(a & b); - - } - break; - case 20: { - /* begin-cert */ - - if (ENG->chain_len == 0) { - T0_PUSHi(-1); - } else { - ENG->cert_cur = ENG->chain->data; - ENG->cert_len = ENG->chain->data_len; - ENG->chain ++; - ENG->chain_len --; - T0_PUSH(ENG->cert_len); - } - - } - break; - case 21: { - /* begin-ta-name */ - - const br_x500_name *dn; - if (CTX->cur_dn_index >= CTX->num_tas) { - T0_PUSHi(-1); - } else { - if (CTX->ta_names == NULL) { - dn = &CTX->tas[CTX->cur_dn_index].dn; - } else { - dn = &CTX->ta_names[CTX->cur_dn_index]; - } - CTX->cur_dn_index ++; - CTX->cur_dn = dn->data; - CTX->cur_dn_len = dn->len; - T0_PUSH(CTX->cur_dn_len); - } - - } - break; - case 22: { - /* begin-ta-name-list */ - - CTX->cur_dn_index = 0; - - } - break; - case 23: { - /* bzero */ - - size_t len = (size_t)T0_POP(); - void *addr = (unsigned char *)ENG + (size_t)T0_POP(); - memset(addr, 0, len); - - } - break; - case 24: { - /* call-policy-handler */ - - int x; - br_ssl_server_choices choices; - - x = (*CTX->policy_vtable)->choose( - CTX->policy_vtable, CTX, &choices); - ENG->session.cipher_suite = choices.cipher_suite; - CTX->sign_hash_id = choices.algo_id; - ENG->chain = choices.chain; - ENG->chain_len = choices.chain_len; - T0_PUSHi(-(x != 0)); - - } - break; - case 25: { - /* can-output? */ - - T0_PUSHi(-(ENG->hlen_out > 0)); - - } - break; - case 26: { - /* check-resume */ - - if (ENG->session.session_id_len == 32 - && CTX->cache_vtable != NULL && (*CTX->cache_vtable)->load( - CTX->cache_vtable, CTX, &ENG->session)) - { - T0_PUSHi(-1); - } else { - T0_PUSH(0); - } - - } - break; - case 27: { - /* co */ - T0_CO(); - } - break; - case 28: { - /* compute-Finished-inner */ - - int prf_id = T0_POP(); - int from_client = T0_POPi(); - unsigned char tmp[48]; - br_tls_prf_seed_chunk seed; - - br_tls_prf_impl prf = br_ssl_engine_get_PRF(ENG, prf_id); - seed.data = tmp; - if (ENG->session.version >= BR_TLS12) { - seed.len = br_multihash_out(&ENG->mhash, prf_id, tmp); - } else { - br_multihash_out(&ENG->mhash, br_md5_ID, tmp); - br_multihash_out(&ENG->mhash, br_sha1_ID, tmp + 16); - seed.len = 36; - } - prf(ENG->pad, 12, ENG->session.master_secret, - sizeof ENG->session.master_secret, - from_client ? "client finished" : "server finished", - 1, &seed); - - } - break; - case 29: { - /* compute-hash-CV */ - - int i; - - for (i = 1; i <= 6; i ++) { - br_multihash_out(&ENG->mhash, i, - ENG->pad + HASH_PAD_OFF[i - 1]); - } - - } - break; - case 30: { - /* copy-cert-chunk */ - - size_t clen; - - clen = ENG->cert_len; - if (clen > sizeof ENG->pad) { - clen = sizeof ENG->pad; - } - memcpy(ENG->pad, ENG->cert_cur, clen); - ENG->cert_cur += clen; - ENG->cert_len -= clen; - T0_PUSH(clen); - - } - break; - case 31: { - /* copy-dn-chunk */ - - size_t clen; - - clen = CTX->cur_dn_len; - if (clen > sizeof ENG->pad) { - clen = sizeof ENG->pad; - } - memcpy(ENG->pad, CTX->cur_dn, clen); - CTX->cur_dn += clen; - CTX->cur_dn_len -= clen; - T0_PUSH(clen); - - } - break; - case 32: { - /* copy-hash-CV */ - - int id = T0_POP(); - size_t off, len; - - if (id == 0) { - off = 0; - len = 36; - } else { - if (br_multihash_getimpl(&ENG->mhash, id) == 0) { - T0_PUSH(0); - T0_RET(); - } - off = HASH_PAD_OFF[id - 1]; - len = HASH_PAD_OFF[id] - off; - } - memcpy(CTX->hash_CV, ENG->pad + off, len); - CTX->hash_CV_len = len; - CTX->hash_CV_id = id; - T0_PUSHi(-1); - - } - break; - case 33: { - /* copy-protocol-name */ - - size_t idx = T0_POP(); - size_t len = strlen(ENG->protocol_names[idx]); - memcpy(ENG->pad, ENG->protocol_names[idx], len); - T0_PUSH(len); - - } - break; - case 34: { - /* data-get8 */ - - size_t addr = T0_POP(); - T0_PUSH(t0_datablock[addr]); - - } - break; - case 35: { - /* discard-input */ - - ENG->hlen_in = 0; - - } - break; - case 36: { - /* do-ecdh */ - - int prf_id = T0_POPi(); - size_t len = T0_POP(); - do_ecdh(CTX, prf_id, ENG->pad, len); - - } - break; - case 37: { - /* do-ecdhe-part1 */ - - int curve = T0_POPi(); - T0_PUSHi(do_ecdhe_part1(CTX, curve)); - - } - break; - case 38: { - /* do-ecdhe-part2 */ - - int prf_id = T0_POPi(); - size_t len = T0_POP(); - do_ecdhe_part2(CTX, prf_id, ENG->pad, len); - - } - break; - case 39: { - /* do-rsa-decrypt */ - - int prf_id = T0_POPi(); - size_t len = T0_POP(); - do_rsa_decrypt(CTX, prf_id, ENG->pad, len); - - } - break; - case 40: { - /* do-static-ecdh */ - - do_static_ecdh(CTX, T0_POP()); - - } - break; - case 41: { - /* drop */ - (void)T0_POP(); - } - break; - case 42: { - /* dup */ - T0_PUSH(T0_PEEK(0)); - } - break; - case 43: { - /* fail */ - - br_ssl_engine_fail(ENG, (int)T0_POPi()); - T0_CO(); - - } - break; - case 44: { - /* flush-record */ - - br_ssl_engine_flush_record(ENG); - - } - break; - case 45: { - /* get-key-type-usages */ - - const br_x509_class *xc; - const br_x509_pkey *pk; - unsigned usages; - - xc = *(ENG->x509ctx); - pk = xc->get_pkey(ENG->x509ctx, &usages); - if (pk == NULL) { - T0_PUSH(0); - } else { - T0_PUSH(pk->key_type | usages); - } - - } - break; - case 46: { - /* get16 */ - - size_t addr = (size_t)T0_POP(); - T0_PUSH(*(uint16_t *)(void *)((unsigned char *)ENG + addr)); - - } - break; - case 47: { - /* get32 */ - - size_t addr = (size_t)T0_POP(); - T0_PUSH(*(uint32_t *)(void *)((unsigned char *)ENG + addr)); - - } - break; - case 48: { - /* get8 */ - - size_t addr = (size_t)T0_POP(); - T0_PUSH(*((unsigned char *)ENG + addr)); - - } - break; - case 49: { - /* has-input? */ - - T0_PUSHi(-(ENG->hlen_in != 0)); - - } - break; - case 50: { - /* memcmp */ - - size_t len = (size_t)T0_POP(); - void *addr2 = (unsigned char *)ENG + (size_t)T0_POP(); - void *addr1 = (unsigned char *)ENG + (size_t)T0_POP(); - int x = memcmp(addr1, addr2, len); - T0_PUSH((uint32_t)-(x == 0)); - - } - break; - case 51: { - /* memcpy */ - - size_t len = (size_t)T0_POP(); - void *src = (unsigned char *)ENG + (size_t)T0_POP(); - void *dst = (unsigned char *)ENG + (size_t)T0_POP(); - memcpy(dst, src, len); - - } - break; - case 52: { - /* mkrand */ - - size_t len = (size_t)T0_POP(); - void *addr = (unsigned char *)ENG + (size_t)T0_POP(); - br_hmac_drbg_generate(&ENG->rng, addr, len); - - } - break; - case 53: { - /* more-incoming-bytes? */ - - T0_PUSHi(ENG->hlen_in != 0 || !br_ssl_engine_recvrec_finished(ENG)); - - } - break; - case 54: { - /* multihash-init */ - - br_multihash_init(&ENG->mhash); - - } - break; - case 55: { - /* neg */ - - uint32_t a = T0_POP(); - T0_PUSH(-a); - - } - break; - case 56: { - /* not */ - - uint32_t a = T0_POP(); - T0_PUSH(~a); - - } - break; - case 57: { - /* or */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(a | b); - - } - break; - case 58: { - /* over */ - T0_PUSH(T0_PEEK(1)); - } - break; - case 59: { - /* pick */ - T0_PICK(T0_POP()); - } - break; - case 60: { - /* read-chunk-native */ - - size_t clen = ENG->hlen_in; - if (clen > 0) { - uint32_t addr, len; - - len = T0_POP(); - addr = T0_POP(); - if ((size_t)len < clen) { - clen = (size_t)len; - } - memcpy((unsigned char *)ENG + addr, ENG->hbuf_in, clen); - if (ENG->record_type_in == BR_SSL_HANDSHAKE) { - br_multihash_update(&ENG->mhash, ENG->hbuf_in, clen); - } - T0_PUSH(addr + (uint32_t)clen); - T0_PUSH(len - (uint32_t)clen); - ENG->hbuf_in += clen; - ENG->hlen_in -= clen; - } - - } - break; - case 61: { - /* read8-native */ - - if (ENG->hlen_in > 0) { - unsigned char x; - - x = *ENG->hbuf_in ++; - if (ENG->record_type_in == BR_SSL_HANDSHAKE) { - br_multihash_update(&ENG->mhash, &x, 1); - } - T0_PUSH(x); - ENG->hlen_in --; - } else { - T0_PUSHi(-1); - } - - } - break; - case 62: { - /* save-session */ - - if (CTX->cache_vtable != NULL) { - (*CTX->cache_vtable)->save( - CTX->cache_vtable, CTX, &ENG->session); - } - - } - break; - case 63: { - /* set-max-frag-len */ - - size_t max_frag_len = T0_POP(); - - br_ssl_engine_new_max_frag_len(ENG, max_frag_len); - - /* - * We must adjust our own output limit. Since we call this only - * after receiving a ClientHello and before beginning to send - * the ServerHello, the next output record should be empty at - * that point, so we can use max_frag_len as a limit. - */ - if (ENG->hlen_out > max_frag_len) { - ENG->hlen_out = max_frag_len; - } - - } - break; - case 64: { - /* set16 */ - - size_t addr = (size_t)T0_POP(); - *(uint16_t *)(void *)((unsigned char *)ENG + addr) = (uint16_t)T0_POP(); - - } - break; - case 65: { - /* set32 */ - - size_t addr = (size_t)T0_POP(); - *(uint32_t *)(void *)((unsigned char *)ENG + addr) = (uint32_t)T0_POP(); - - } - break; - case 66: { - /* set8 */ - - size_t addr = (size_t)T0_POP(); - *((unsigned char *)ENG + addr) = (unsigned char)T0_POP(); - - } - break; - case 67: { - /* supported-curves */ - - uint32_t x = ENG->iec == NULL ? 0 : ENG->iec->supported_curves; - T0_PUSH(x); - - } - break; - case 68: { - /* supported-hash-functions */ - - int i; - unsigned x, num; - - x = 0; - num = 0; - for (i = br_sha1_ID; i <= br_sha512_ID; i ++) { - if (br_multihash_getimpl(&ENG->mhash, i)) { - x |= 1U << i; - num ++; - } - } - T0_PUSH(x); - T0_PUSH(num); - - } - break; - case 69: { - /* supports-ecdsa? */ - - T0_PUSHi(-(ENG->iecdsa != 0)); - - } - break; - case 70: { - /* supports-rsa-sign? */ - - T0_PUSHi(-(ENG->irsavrfy != 0)); - - } - break; - case 71: { - /* swap */ - T0_SWAP(); - } - break; - case 72: { - /* switch-aesccm-in */ - - int is_client, prf_id; - unsigned cipher_key_len, tag_len; - - tag_len = T0_POP(); - cipher_key_len = T0_POP(); - prf_id = T0_POP(); - is_client = T0_POP(); - br_ssl_engine_switch_ccm_in(ENG, is_client, prf_id, - ENG->iaes_ctrcbc, cipher_key_len, tag_len); - - } - break; - case 73: { - /* switch-aesccm-out */ - - int is_client, prf_id; - unsigned cipher_key_len, tag_len; - - tag_len = T0_POP(); - cipher_key_len = T0_POP(); - prf_id = T0_POP(); - is_client = T0_POP(); - br_ssl_engine_switch_ccm_out(ENG, is_client, prf_id, - ENG->iaes_ctrcbc, cipher_key_len, tag_len); - - } - break; - case 74: { - /* switch-aesgcm-in */ - - int is_client, prf_id; - unsigned cipher_key_len; - - cipher_key_len = T0_POP(); - prf_id = T0_POP(); - is_client = T0_POP(); - br_ssl_engine_switch_gcm_in(ENG, is_client, prf_id, - ENG->iaes_ctr, cipher_key_len); - - } - break; - case 75: { - /* switch-aesgcm-out */ - - int is_client, prf_id; - unsigned cipher_key_len; - - cipher_key_len = T0_POP(); - prf_id = T0_POP(); - is_client = T0_POP(); - br_ssl_engine_switch_gcm_out(ENG, is_client, prf_id, - ENG->iaes_ctr, cipher_key_len); - - } - break; - case 76: { - /* switch-cbc-in */ - - int is_client, prf_id, mac_id, aes; - unsigned cipher_key_len; - - cipher_key_len = T0_POP(); - aes = T0_POP(); - mac_id = T0_POP(); - prf_id = T0_POP(); - is_client = T0_POP(); - br_ssl_engine_switch_cbc_in(ENG, is_client, prf_id, mac_id, - aes ? ENG->iaes_cbcdec : ENG->ides_cbcdec, cipher_key_len); - - } - break; - case 77: { - /* switch-cbc-out */ - - int is_client, prf_id, mac_id, aes; - unsigned cipher_key_len; - - cipher_key_len = T0_POP(); - aes = T0_POP(); - mac_id = T0_POP(); - prf_id = T0_POP(); - is_client = T0_POP(); - br_ssl_engine_switch_cbc_out(ENG, is_client, prf_id, mac_id, - aes ? ENG->iaes_cbcenc : ENG->ides_cbcenc, cipher_key_len); - - } - break; - case 78: { - /* switch-chapol-in */ - - int is_client, prf_id; - - prf_id = T0_POP(); - is_client = T0_POP(); - br_ssl_engine_switch_chapol_in(ENG, is_client, prf_id); - - } - break; - case 79: { - /* switch-chapol-out */ - - int is_client, prf_id; - - prf_id = T0_POP(); - is_client = T0_POP(); - br_ssl_engine_switch_chapol_out(ENG, is_client, prf_id); - - } - break; - case 80: { - /* ta-names-total-length */ - - size_t u, len; - - len = 0; - if (CTX->ta_names != NULL) { - for (u = 0; u < CTX->num_tas; u ++) { - len += CTX->ta_names[u].len + 2; - } - } else if (CTX->tas != NULL) { - for (u = 0; u < CTX->num_tas; u ++) { - len += CTX->tas[u].dn.len + 2; - } - } - T0_PUSH(len); - - } - break; - case 81: { - /* test-protocol-name */ - - size_t len = T0_POP(); - size_t u; - - for (u = 0; u < ENG->protocol_names_num; u ++) { - const char *name; - - name = ENG->protocol_names[u]; - if (len == strlen(name) && memcmp(ENG->pad, name, len) == 0) { - T0_PUSH(u); - T0_RET(); - } - } - T0_PUSHi(-1); - - } - break; - case 82: { - /* total-chain-length */ - - size_t u; - uint32_t total; - - total = 0; - for (u = 0; u < ENG->chain_len; u ++) { - total += 3 + (uint32_t)ENG->chain[u].data_len; - } - T0_PUSH(total); - - } - break; - case 83: { - /* u< */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(-(uint32_t)(a < b)); - - } - break; - case 84: { - /* u>> */ - - int c = (int)T0_POPi(); - uint32_t x = T0_POP(); - T0_PUSH(x >> c); - - } - break; - case 85: { - /* verify-CV-sig */ - - int err; - - err = verify_CV_sig(CTX, T0_POP()); - T0_PUSHi(err); - - } - break; - case 86: { - /* write-blob-chunk */ - - size_t clen = ENG->hlen_out; - if (clen > 0) { - uint32_t addr, len; - - len = T0_POP(); - addr = T0_POP(); - if ((size_t)len < clen) { - clen = (size_t)len; - } - memcpy(ENG->hbuf_out, (unsigned char *)ENG + addr, clen); - if (ENG->record_type_out == BR_SSL_HANDSHAKE) { - br_multihash_update(&ENG->mhash, ENG->hbuf_out, clen); - } - T0_PUSH(addr + (uint32_t)clen); - T0_PUSH(len - (uint32_t)clen); - ENG->hbuf_out += clen; - ENG->hlen_out -= clen; - } - - } - break; - case 87: { - /* write8-native */ - - unsigned char x; - - x = (unsigned char)T0_POP(); - if (ENG->hlen_out > 0) { - if (ENG->record_type_out == BR_SSL_HANDSHAKE) { - br_multihash_update(&ENG->mhash, &x, 1); - } - *ENG->hbuf_out ++ = x; - ENG->hlen_out --; - T0_PUSHi(-1); - } else { - T0_PUSHi(0); - } - - } - break; - case 88: { - /* x509-append */ - - const br_x509_class *xc; - size_t len; - - xc = *(ENG->x509ctx); - len = T0_POP(); - xc->append(ENG->x509ctx, ENG->pad, len); - - } - break; - case 89: { - /* x509-end-cert */ - - const br_x509_class *xc; - - xc = *(ENG->x509ctx); - xc->end_cert(ENG->x509ctx); - - } - break; - case 90: { - /* x509-end-chain */ - - const br_x509_class *xc; - - xc = *(ENG->x509ctx); - T0_PUSH(xc->end_chain(ENG->x509ctx)); - - } - break; - case 91: { - /* x509-start-cert */ - - const br_x509_class *xc; - - xc = *(ENG->x509ctx); - xc->start_cert(ENG->x509ctx, T0_POP()); - - } - break; - case 92: { - /* x509-start-chain */ - - const br_x509_class *xc; - uint32_t bc; - - bc = T0_POP(); - xc = *(ENG->x509ctx); - xc->start_chain(ENG->x509ctx, bc ? ENG->server_name : NULL); - - } - break; - } - - } else { - T0_ENTER(ip, rp, t0x); - } - } -t0_exit: - ((t0_context *)t0ctx)->dp = dp; - ((t0_context *)t0ctx)->rp = rp; - ((t0_context *)t0ctx)->ip = ip; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ssl_io.c b/src/tls/bearssl/ssl_io.c deleted file mode 100644 index 2a1a928e0..000000000 --- a/src/tls/bearssl/ssl_io.c +++ /dev/null @@ -1,325 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_ssl.h */ -void -br_sslio_init(br_sslio_context *ctx, - br_ssl_engine_context *engine, - int (*low_read)(void *read_context, - unsigned char *data, size_t len), - void *read_context, - int (*low_write)(void *write_context, - const unsigned char *data, size_t len), - void *write_context) -{ - ctx->engine = engine; - ctx->low_read = low_read; - ctx->read_context = read_context; - ctx->low_write = low_write; - ctx->write_context = write_context; -} - -/* - * Run the engine, until the specified target state is achieved, or - * an error occurs. The target state is SENDAPP, RECVAPP, or the - * combination of both (the combination matches either). When a match is - * achieved, this function returns 0. On error, it returns -1. - */ -static int -run_until(br_sslio_context *ctx, unsigned target) -{ - for (;;) { - unsigned state; - - state = br_ssl_engine_current_state(ctx->engine); - if (state & BR_SSL_CLOSED) { - return -1; - } - - /* - * If there is some record data to send, do it. This takes - * precedence over everything else. - */ - if (state & BR_SSL_SENDREC) { - unsigned char *buf; - size_t len; - int wlen; - - buf = br_ssl_engine_sendrec_buf(ctx->engine, &len); - wlen = ctx->low_write(ctx->write_context, buf, len); - if (wlen < 0) { - /* - * If we received a close_notify and we - * still send something, then we have our - * own response close_notify to send, and - * the peer is allowed by RFC 5246 not to - * wait for it. - */ - if (!ctx->engine->shutdown_recv) { - br_ssl_engine_fail( - ctx->engine, BR_ERR_IO); - } - return -1; - } - if (wlen > 0) { - br_ssl_engine_sendrec_ack(ctx->engine, wlen); - } - continue; - } - - /* - * If we reached our target, then we are finished. - */ - if (state & target) { - return 0; - } - - /* - * If some application data must be read, and we did not - * exit, then this means that we are trying to write data, - * and that's not possible until the application data is - * read. This may happen if using a shared in/out buffer, - * and the underlying protocol is not strictly half-duplex. - * This is unrecoverable here, so we report an error. - */ - if (state & BR_SSL_RECVAPP) { - return -1; - } - - /* - * If we reached that point, then either we are trying - * to read data and there is some, or the engine is stuck - * until a new record is obtained. - */ - if (state & BR_SSL_RECVREC) { - unsigned char *buf; - size_t len; - int rlen; - - buf = br_ssl_engine_recvrec_buf(ctx->engine, &len); - rlen = ctx->low_read(ctx->read_context, buf, len); - if (rlen < 0) { - br_ssl_engine_fail(ctx->engine, BR_ERR_IO); - return -1; - } - if (rlen > 0) { - br_ssl_engine_recvrec_ack(ctx->engine, rlen); - } - continue; - } - - /* - * We can reach that point if the target RECVAPP, and - * the state contains SENDAPP only. This may happen with - * a shared in/out buffer. In that case, we must flush - * the buffered data to "make room" for a new incoming - * record. - */ - br_ssl_engine_flush(ctx->engine, 0); - } -} - -/* see bearssl_ssl.h */ -int -br_sslio_read(br_sslio_context *ctx, void *dst, size_t len) -{ - unsigned char *buf; - size_t alen; - - if (len == 0) { - return 0; - } - if (run_until(ctx, BR_SSL_RECVAPP) < 0) { - return -1; - } - buf = br_ssl_engine_recvapp_buf(ctx->engine, &alen); - if (alen > len) { - alen = len; - } - memcpy(dst, buf, alen); - br_ssl_engine_recvapp_ack(ctx->engine, alen); - return (int)alen; -} - -/* see bearssl_ssl.h */ -int -br_sslio_read_all(br_sslio_context *ctx, void *dst, size_t len) -{ - unsigned char *buf; - - buf = dst; - while (len > 0) { - int rlen; - - rlen = br_sslio_read(ctx, buf, len); - if (rlen < 0) { - return -1; - } - buf += rlen; - len -= (size_t)rlen; - } - return 0; -} - -#ifdef ARDUINO -int br_sslio_read_available(br_sslio_context *ctx) -{ - size_t alen; - unsigned state = br_ssl_engine_current_state(ctx->engine); - - if (state & BR_SSL_RECVREC) { - unsigned char *buf; - size_t len; - int rlen; - - buf = br_ssl_engine_recvrec_buf(ctx->engine, &len); - rlen = ctx->low_read(ctx->read_context, buf, len); - if (rlen < 0) { - br_ssl_engine_fail(ctx->engine, BR_ERR_IO); - return -1; - } - if (rlen > 0) { - br_ssl_engine_recvrec_ack(ctx->engine, rlen); - } - } - br_ssl_engine_recvapp_buf(ctx->engine, &alen); - return (int)alen; -} - -int br_sslio_peek(br_sslio_context *ctx, void *dst, size_t len) -{ - unsigned char *buf; - size_t alen; - - if (len == 0) { - return 0; - } - unsigned state = br_ssl_engine_current_state(ctx->engine); - - if (state & BR_SSL_RECVREC) { - unsigned char *buf; - size_t len; - int rlen; - - buf = br_ssl_engine_recvrec_buf(ctx->engine, &len); - rlen = ctx->low_read(ctx->read_context, buf, len); - if (rlen < 0) { - br_ssl_engine_fail(ctx->engine, BR_ERR_IO); - return -1; - } - if (rlen > 0) { - br_ssl_engine_recvrec_ack(ctx->engine, rlen); - } - } - buf = br_ssl_engine_recvapp_buf(ctx->engine, &alen); - if (alen > len) { - alen = len; - } - memcpy(dst, buf, alen); - return (int)alen; -} -#endif - -/* see bearssl_ssl.h */ -int -br_sslio_write(br_sslio_context *ctx, const void *src, size_t len) -{ - unsigned char *buf; - size_t alen; - - if (len == 0) { - return 0; - } - if (run_until(ctx, BR_SSL_SENDAPP) < 0) { - return -1; - } - buf = br_ssl_engine_sendapp_buf(ctx->engine, &alen); - if (alen > len) { - alen = len; - } - memcpy(buf, src, alen); - br_ssl_engine_sendapp_ack(ctx->engine, alen); - return (int)alen; -} - -/* see bearssl_ssl.h */ -int -br_sslio_write_all(br_sslio_context *ctx, const void *src, size_t len) -{ - const unsigned char *buf; - - buf = src; - while (len > 0) { - int wlen; - - wlen = br_sslio_write(ctx, buf, len); - if (wlen < 0) { - return -1; - } - buf += wlen; - len -= (size_t)wlen; - } - return 0; -} - -/* see bearssl_ssl.h */ -int -br_sslio_flush(br_sslio_context *ctx) -{ - /* - * We trigger a flush. We know the data is gone when there is - * no longer any record data to send, and we can either read - * or write application data. The call to run_until() does the - * job because it ensures that any assembled record data is - * first sent down the wire before considering anything else. - */ - br_ssl_engine_flush(ctx->engine, 0); - return run_until(ctx, BR_SSL_SENDAPP | BR_SSL_RECVAPP); -} - -/* see bearssl_ssl.h */ -int -br_sslio_close(br_sslio_context *ctx) -{ - br_ssl_engine_close(ctx->engine); - while (br_ssl_engine_current_state(ctx->engine) != BR_SSL_CLOSED) { - /* - * Discard any incoming application data. - */ - size_t len; - - run_until(ctx, BR_SSL_RECVAPP); - if (br_ssl_engine_recvapp_buf(ctx->engine, &len) != NULL) { - br_ssl_engine_recvapp_ack(ctx->engine, len); - } - } - return br_ssl_engine_last_error(ctx->engine) == BR_ERR_OK; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ssl_keyexport.c b/src/tls/bearssl/ssl_keyexport.c deleted file mode 100644 index d5e7af489..000000000 --- a/src/tls/bearssl/ssl_keyexport.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * Supported cipher suites that use SHA-384 for the PRF when selected - * for TLS 1.2. All other cipher suites are deemed to use SHA-256. - */ -static const uint16_t suites_sha384[] = { - BR_TLS_RSA_WITH_AES_256_GCM_SHA384, - BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, - BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, - BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, - BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, - BR_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, - BR_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, - BR_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - BR_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 -}; - -/* see bearssl_ssl.h */ -int -br_ssl_key_export(br_ssl_engine_context *cc, - void *dst, size_t len, const char *label, - const void *context, size_t context_len) -{ - br_tls_prf_seed_chunk chunks[4]; - br_tls_prf_impl iprf; - size_t num_chunks, u; - unsigned char tmp[2]; - int prf_id; - - if (cc->application_data != 1) { - return 0; - } - chunks[0].data = cc->client_random; - chunks[0].len = sizeof cc->client_random; - chunks[1].data = cc->server_random; - chunks[1].len = sizeof cc->server_random; - if (context != NULL) { - br_enc16be(tmp, (unsigned)context_len); - chunks[2].data = tmp; - chunks[2].len = 2; - chunks[3].data = context; - chunks[3].len = context_len; - num_chunks = 4; - } else { - num_chunks = 2; - } - prf_id = BR_SSLPRF_SHA256; - for (u = 0; u < (sizeof suites_sha384) / sizeof(uint16_t); u ++) { - if (suites_sha384[u] == cc->session.cipher_suite) { - prf_id = BR_SSLPRF_SHA384; - } - } - iprf = br_ssl_engine_get_PRF(cc, prf_id); - iprf(dst, len, - cc->session.master_secret, sizeof cc->session.master_secret, - label, num_chunks, chunks); - return 1; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ssl_lru.c b/src/tls/bearssl/ssl_lru.c deleted file mode 100644 index 42fabe2c5..000000000 --- a/src/tls/bearssl/ssl_lru.c +++ /dev/null @@ -1,542 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * Each entry consists in a fixed number of bytes. Entries are concatenated - * in the store block. "Addresses" are really offsets in the block, - * expressed over 32 bits (so the cache may have size at most 4 GB, which - * "ought to be enough for everyone"). The "null address" is 0xFFFFFFFF. - * Note that since the storage block alignment is in no way guaranteed, we - * perform only accesses that can handle unaligned data. - * - * Two concurrent data structures are maintained: - * - * -- Entries are organised in a doubly-linked list; saved entries are added - * at the head, and loaded entries are moved to the head. Eviction uses - * the list tail (this is the LRU algorithm). - * - * -- Entries are indexed with a binary tree: all left descendants of a - * node have a lower session ID (in lexicographic order), while all - * right descendants have a higher session ID. The tree is heuristically - * balanced. - * - * Entry format: - * - * session ID 32 bytes - * master secret 48 bytes - * protocol version 2 bytes (big endian) - * cipher suite 2 bytes (big endian) - * list prev 4 bytes (big endian) - * list next 4 bytes (big endian) - * tree left child 4 bytes (big endian) - * tree right child 4 bytes (big endian) - * - * If an entry has a protocol version set to 0, then it is "disabled": - * it was a session pushed to the cache at some point, but it has - * been explicitly removed. - * - * We need to keep the tree balanced because an attacker could make - * handshakes, selecting some specific sessions (by reusing them) to - * try to make us make an imbalanced tree that makes lookups expensive - * (a denial-of-service attack that would persist as long as the cache - * remains, i.e. even after the attacker made all his connections). - * To do that, we replace the session ID (or the start of the session ID) - * with a HMAC value computed over the replaced part; the hash function - * implementation and the key are obtained from the server context upon - * first save() call. - * - * Theoretically, an attacker could use the exact timing of the lookup - * to infer the current tree topology, and try to revive entries to make - * it as unbalanced as possible. However, since the session ID are - * chosen randomly by the server, and the attacker cannot see the - * indexing values and must thus rely on blind selection, it should be - * exponentially difficult for the attacker to maintain a large - * imbalance. - */ -#define SESSION_ID_LEN 32 -#define MASTER_SECRET_LEN 48 - -#define SESSION_ID_OFF 0 -#define MASTER_SECRET_OFF 32 -#define VERSION_OFF 80 -#define CIPHER_SUITE_OFF 82 -#define LIST_PREV_OFF 84 -#define LIST_NEXT_OFF 88 -#define TREE_LEFT_OFF 92 -#define TREE_RIGHT_OFF 96 - -#define LRU_ENTRY_LEN 100 - -#define ADDR_NULL ((uint32_t)-1) - -#define GETSET(name, off) \ -static inline uint32_t get_ ## name(br_ssl_session_cache_lru *cc, uint32_t x) \ -{ \ - return br_dec32be(cc->store + x + (off)); \ -} \ -static inline void set_ ## name(br_ssl_session_cache_lru *cc, \ - uint32_t x, uint32_t val) \ -{ \ - br_enc32be(cc->store + x + (off), val); \ -} - -GETSET(prev, LIST_PREV_OFF) -GETSET(next, LIST_NEXT_OFF) -GETSET(left, TREE_LEFT_OFF) -GETSET(right, TREE_RIGHT_OFF) - -/* - * Transform the session ID by replacing the first N bytes with a HMAC - * value computed over these bytes, using the random key K (the HMAC - * value is truncated if needed). HMAC will use the same hash function - * as the DRBG in the SSL server context, so with SHA-256, SHA-384, - * or SHA-1, depending on what is available. - * - * The risk of collision is considered too small to be a concern; and - * the impact of a collision is low (the handshake won't succeed). This - * risk is much lower than any transmission error, which would lead to - * the same consequences. - * - * Source and destination arrays msut be disjoint. - */ -static void -mask_id(br_ssl_session_cache_lru *cc, - const unsigned char *src, unsigned char *dst) -{ - br_hmac_key_context hkc; - br_hmac_context hc; - - memcpy(dst, src, SESSION_ID_LEN); - br_hmac_key_init(&hkc, cc->hash, cc->index_key, sizeof cc->index_key); - br_hmac_init(&hc, &hkc, SESSION_ID_LEN); - br_hmac_update(&hc, src, SESSION_ID_LEN); - br_hmac_out(&hc, dst); -} - -/* - * Find a node by ID. Returned value is the node address, or ADDR_NULL if - * the node is not found. - * - * If addr_link is not NULL, then '*addr_link' is set to the address of the - * last followed link. If the found node is the root, or if the tree is - * empty, then '*addr_link' is set to ADDR_NULL. - */ -static uint32_t -find_node(br_ssl_session_cache_lru *cc, const unsigned char *id, - uint32_t *addr_link) -{ - uint32_t x, y; - - x = cc->root; - y = ADDR_NULL; - while (x != ADDR_NULL) { - int r; - - r = memcmp(id, cc->store + x + SESSION_ID_OFF, SESSION_ID_LEN); - if (r < 0) { - y = x + TREE_LEFT_OFF; - x = get_left(cc, x); - } else if (r == 0) { - if (addr_link != NULL) { - *addr_link = y; - } - return x; - } else { - y = x + TREE_RIGHT_OFF; - x = get_right(cc, x); - } - } - if (addr_link != NULL) { - *addr_link = y; - } - return ADDR_NULL; -} - -/* - * For node x, find its replacement upon removal. - * - * -- If node x has no child, then this returns ADDR_NULL. - * -- Otherwise, if node x has a left child, then the replacement is the - * rightmost left-descendent. - * -- Otherwise, the replacement is the leftmost right-descendent. - * - * If a node is returned, then '*al' is set to the address of the field - * that points to that node. Otherwise (node x has no child), '*al' is - * set to ADDR_NULL. - * - * Note that the replacement node, when found, is always a descendent - * of node 'x', so it cannot be the tree root. Thus, '*al' can be set - * to ADDR_NULL only when no node is found and ADDR_NULL is returned. - */ -static uint32_t -find_replacement_node(br_ssl_session_cache_lru *cc, uint32_t x, uint32_t *al) -{ - uint32_t y1, y2; - - y1 = get_left(cc, x); - if (y1 != ADDR_NULL) { - y2 = x + TREE_LEFT_OFF; - for (;;) { - uint32_t z; - - z = get_right(cc, y1); - if (z == ADDR_NULL) { - *al = y2; - return y1; - } - y2 = y1 + TREE_RIGHT_OFF; - y1 = z; - } - } - y1 = get_right(cc, x); - if (y1 != ADDR_NULL) { - y2 = x + TREE_RIGHT_OFF; - for (;;) { - uint32_t z; - - z = get_left(cc, y1); - if (z == ADDR_NULL) { - *al = y2; - return y1; - } - y2 = y1 + TREE_LEFT_OFF; - y1 = z; - } - } - *al = ADDR_NULL; - return ADDR_NULL; -} - -/* - * Set the link at address 'alx' to point to node 'x'. If 'alx' is - * ADDR_NULL, then this sets the tree root to 'x'. - */ -static inline void -set_link(br_ssl_session_cache_lru *cc, uint32_t alx, uint32_t x) -{ - if (alx == ADDR_NULL) { - cc->root = x; - } else { - br_enc32be(cc->store + alx, x); - } -} - -/* - * Remove node 'x' from the tree. This function shall not be called if - * node 'x' is not part of the tree. - */ -static void -remove_node(br_ssl_session_cache_lru *cc, uint32_t x) -{ - uint32_t alx, y, aly; - - /* - * Removal algorithm: - * ------------------ - * - * - If we remove the root, then the tree becomes empty. - * - * - If the removed node has no child, then we can simply remove - * it, with nothing else to do. - * - * - Otherwise, the removed node must be replaced by either its - * rightmost left-descendent, or its leftmost right-descendent. - * The replacement node itself must be removed from its current - * place. By definition, that replacement node has either no - * child, or at most a single child that will replace it in the - * tree. - */ - - /* - * Find node back and its ancestor link. If the node was the - * root, then alx is set to ADDR_NULL. - */ - find_node(cc, cc->store + x + SESSION_ID_OFF, &alx); - - /* - * Find replacement node 'y', and 'aly' is set to the address of - * the link to that replacement node. If the removed node has no - * child, then both 'y' and 'aly' are set to ADDR_NULL. - */ - y = find_replacement_node(cc, x, &aly); - - if (y != ADDR_NULL) { - uint32_t z; - - /* - * The unlinked replacement node may have one child (but - * not two) that takes its place. - */ - z = get_left(cc, y); - if (z == ADDR_NULL) { - z = get_right(cc, y); - } - set_link(cc, aly, z); - - /* - * Link the replacement node in its new place, overwriting - * the current link to the node 'x' (which removes 'x'). - */ - set_link(cc, alx, y); - - /* - * The replacement node adopts the left and right children - * of the removed node. Note that this also works even if - * the replacement node was a direct descendent of the - * removed node, since we unlinked it previously. - */ - set_left(cc, y, get_left(cc, x)); - set_right(cc, y, get_right(cc, x)); - } else { - /* - * No replacement, we simply unlink the node 'x'. - */ - set_link(cc, alx, ADDR_NULL); - } -} - -static void -lru_save(const br_ssl_session_cache_class **ctx, - br_ssl_server_context *server_ctx, - const br_ssl_session_parameters *params) -{ - br_ssl_session_cache_lru *cc; - unsigned char id[SESSION_ID_LEN]; - uint32_t x, alx; - - cc = (br_ssl_session_cache_lru *)ctx; - - /* - * If the buffer is too small, we don't record anything. This - * test avoids problems in subsequent code. - */ - if (cc->store_len < LRU_ENTRY_LEN) { - return; - } - - /* - * Upon the first save in a session cache instance, we obtain - * a random key for our indexing. - */ - if (!cc->init_done) { - br_hmac_drbg_generate(&server_ctx->eng.rng, - cc->index_key, sizeof cc->index_key); - cc->hash = br_hmac_drbg_get_hash(&server_ctx->eng.rng); - cc->init_done = 1; - } - mask_id(cc, params->session_id, id); - - /* - * Look for the node in the tree. If the same ID is already used, - * then reject it. This is a collision event, which should be - * exceedingly rare. - * Note: we do NOT record the emplacement here, because the - * removal of an entry may change the tree topology. - */ - if (find_node(cc, id, NULL) != ADDR_NULL) { - return; - } - - /* - * Find some room for the new parameters. If the cache is not - * full yet, add it to the end of the area and bump the pointer up. - * Otherwise, evict the list tail entry. Note that we already - * filtered out the case of a ridiculously small buffer that - * cannot hold any entry at all; thus, if there is no room for an - * extra entry, then the cache cannot be empty. - */ - if (cc->store_ptr > (cc->store_len - LRU_ENTRY_LEN)) { - /* - * Evict tail. If the buffer has room for a single entry, - * then this may also be the head. - */ - x = cc->tail; - cc->tail = get_prev(cc, x); - if (cc->tail == ADDR_NULL) { - cc->head = ADDR_NULL; - } else { - set_next(cc, cc->tail, ADDR_NULL); - } - - /* - * Remove the node from the tree. - */ - remove_node(cc, x); - } else { - /* - * Allocate room for new node. - */ - x = cc->store_ptr; - cc->store_ptr += LRU_ENTRY_LEN; - } - - /* - * Find the emplacement for the new node, and link it. - */ - find_node(cc, id, &alx); - set_link(cc, alx, x); - set_left(cc, x, ADDR_NULL); - set_right(cc, x, ADDR_NULL); - - /* - * New entry becomes new list head. It may also become the list - * tail if the cache was empty at that point. - */ - if (cc->head == ADDR_NULL) { - cc->tail = x; - } else { - set_prev(cc, cc->head, x); - } - set_prev(cc, x, ADDR_NULL); - set_next(cc, x, cc->head); - cc->head = x; - - /* - * Fill data in the entry. - */ - memcpy(cc->store + x + SESSION_ID_OFF, id, SESSION_ID_LEN); - memcpy(cc->store + x + MASTER_SECRET_OFF, - params->master_secret, MASTER_SECRET_LEN); - br_enc16be(cc->store + x + VERSION_OFF, params->version); - br_enc16be(cc->store + x + CIPHER_SUITE_OFF, params->cipher_suite); -} - -static int -lru_load(const br_ssl_session_cache_class **ctx, - br_ssl_server_context *server_ctx, - br_ssl_session_parameters *params) -{ - br_ssl_session_cache_lru *cc; - unsigned char id[SESSION_ID_LEN]; - uint32_t x; - - (void)server_ctx; - cc = (br_ssl_session_cache_lru *)ctx; - if (!cc->init_done) { - return 0; - } - mask_id(cc, params->session_id, id); - x = find_node(cc, id, NULL); - if (x != ADDR_NULL) { - unsigned version; - - version = br_dec16be(cc->store + x + VERSION_OFF); - if (version == 0) { - /* - * Entry is disabled, we pretend we did not find it. - * Notably, we don't move it to the front of the - * LRU list. - */ - return 0; - } - params->version = version; - params->cipher_suite = br_dec16be( - cc->store + x + CIPHER_SUITE_OFF); - memcpy(params->master_secret, - cc->store + x + MASTER_SECRET_OFF, - MASTER_SECRET_LEN); - if (x != cc->head) { - /* - * Found node is not at list head, so move - * it to the head. - */ - uint32_t p, n; - - p = get_prev(cc, x); - n = get_next(cc, x); - set_next(cc, p, n); - if (n == ADDR_NULL) { - cc->tail = p; - } else { - set_prev(cc, n, p); - } - set_prev(cc, cc->head, x); - set_next(cc, x, cc->head); - set_prev(cc, x, ADDR_NULL); - cc->head = x; - } - return 1; - } - return 0; -} - -static const br_ssl_session_cache_class lru_class = { - sizeof(br_ssl_session_cache_lru), - &lru_save, - &lru_load -}; - -/* see inner.h */ -void -br_ssl_session_cache_lru_init(br_ssl_session_cache_lru *cc, - unsigned char *store, size_t store_len) -{ - cc->vtable = &lru_class; - cc->store = store; - cc->store_len = store_len; - cc->store_ptr = 0; - cc->init_done = 0; - cc->head = ADDR_NULL; - cc->tail = ADDR_NULL; - cc->root = ADDR_NULL; -} - -/* see bearssl_ssl.h */ -void br_ssl_session_cache_lru_forget( - br_ssl_session_cache_lru *cc, const unsigned char *id) -{ - unsigned char mid[SESSION_ID_LEN]; - uint32_t addr; - - /* - * If the cache is not initialised yet, then it is empty, and - * there is nothing to forget. - */ - if (!cc->init_done) { - return; - } - - /* - * Look for the node in the tree. If found, the entry is marked - * as "disabled"; it will be reused in due course, as it ages - * through the list. - * - * We do not go through the complex moves of actually releasing - * the entry right away because explicitly forgetting sessions - * should be a rare event, meant mostly for testing purposes, - * so this is not worth the extra code size. - */ - mask_id(cc, id, mid); - addr = find_node(cc, mid, NULL); - if (addr != ADDR_NULL) { - br_enc16be(cc->store + addr + VERSION_OFF, 0); - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ssl_rec_cbc.c b/src/tls/bearssl/ssl_rec_cbc.c deleted file mode 100644 index 47980242b..000000000 --- a/src/tls/bearssl/ssl_rec_cbc.c +++ /dev/null @@ -1,445 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -static void -in_cbc_init(br_sslrec_in_cbc_context *cc, - const br_block_cbcdec_class *bc_impl, - const void *bc_key, size_t bc_key_len, - const br_hash_class *dig_impl, - const void *mac_key, size_t mac_key_len, size_t mac_out_len, - const void *iv) -{ - cc->vtable = &br_sslrec_in_cbc_vtable; - cc->seq = 0; - bc_impl->init(&cc->bc.vtable, bc_key, bc_key_len); - br_hmac_key_init(&cc->mac, dig_impl, mac_key, mac_key_len); - cc->mac_len = mac_out_len; - if (iv == NULL) { - memset(cc->iv, 0, sizeof cc->iv); - cc->explicit_IV = 1; - } else { - memcpy(cc->iv, iv, bc_impl->block_size); - cc->explicit_IV = 0; - } -} - -static int -cbc_check_length(const br_sslrec_in_cbc_context *cc, size_t rlen) -{ - /* - * Plaintext size: at most 16384 bytes - * Padding: at most 256 bytes - * MAC: mac_len extra bytes - * TLS 1.1+: each record has an explicit IV - * - * Minimum length includes at least one byte of padding, and the - * MAC. - * - * Total length must be a multiple of the block size. - */ - size_t blen; - size_t min_len, max_len; - - blen = cc->bc.vtable->block_size; - min_len = (blen + cc->mac_len) & ~(blen - 1); - max_len = (16384 + 256 + cc->mac_len) & ~(blen - 1); - if (cc->explicit_IV) { - min_len += blen; - max_len += blen; - } - return min_len <= rlen && rlen <= max_len; -} - -/* - * Rotate array buf[] of length 'len' to the left (towards low indices) - * by 'num' bytes if ctl is 1; otherwise, leave it unchanged. This is - * constant-time. 'num' MUST be lower than 'len'. 'len' MUST be lower - * than or equal to 64. - */ -static void -cond_rotate(uint32_t ctl, unsigned char *buf, size_t len, size_t num) -{ - unsigned char tmp[64]; - size_t u, v; - - for (u = 0, v = num; u < len; u ++) { - tmp[u] = MUX(ctl, buf[v], buf[u]); - if (++ v == len) { - v = 0; - } - } - memcpy(buf, tmp, len); -} - -static unsigned char * -cbc_decrypt(br_sslrec_in_cbc_context *cc, - int record_type, unsigned version, void *data, size_t *data_len) -{ - /* - * We represent all lengths on 32-bit integers, because: - * -- SSL record lengths always fit in 32 bits; - * -- our constant-time primitives operate on 32-bit integers. - */ - unsigned char *buf; - uint32_t u, v, len, blen, min_len, max_len; - uint32_t good, pad_len, rot_count, len_withmac, len_nomac; - unsigned char tmp1[64], tmp2[64]; - int i; - br_hmac_context hc; - - buf = data; - len = *data_len; - blen = cc->bc.vtable->block_size; - - /* - * Decrypt data, and skip the explicit IV (if applicable). Note - * that the total length is supposed to have been verified by - * the caller. If there is an explicit IV, then we actually - * "decrypt" it using the implicit IV (from previous record), - * which is useless but harmless. - */ - cc->bc.vtable->run(&cc->bc.vtable, cc->iv, data, len); - if (cc->explicit_IV) { - buf += blen; - len -= blen; - } - - /* - * Compute minimum and maximum length of plaintext + MAC. These - * lengths can be inferred from the outside: they are not secret. - */ - min_len = (cc->mac_len + 256 < len) ? len - 256 : cc->mac_len; - max_len = len - 1; - - /* - * Use the last decrypted byte to compute the actual payload - * length. Take care not to underflow (we use unsigned types). - */ - pad_len = buf[max_len]; - good = LE(pad_len, (uint32_t)(max_len - min_len)); - len = MUX(good, (uint32_t)(max_len - pad_len), min_len); - - /* - * Check padding contents: all padding bytes must be equal to - * the value of pad_len. - */ - for (u = min_len; u < max_len; u ++) { - good &= LT(u, len) | EQ(buf[u], pad_len); - } - - /* - * Extract the MAC value. This is done in one pass, but results - * in a "rotated" MAC value depending on where it actually - * occurs. The 'rot_count' value is set to the offset of the - * first MAC byte within tmp1[]. - * - * min_len and max_len are also adjusted to the minimum and - * maximum lengths of the plaintext alone (without the MAC). - */ - len_withmac = (uint32_t)len; - len_nomac = len_withmac - cc->mac_len; - min_len -= cc->mac_len; - rot_count = 0; - memset(tmp1, 0, cc->mac_len); - v = 0; - for (u = min_len; u < max_len; u ++) { - tmp1[v] |= MUX(GE(u, len_nomac) & LT(u, len_withmac), - buf[u], 0x00); - rot_count = MUX(EQ(u, len_nomac), v, rot_count); - if (++ v == cc->mac_len) { - v = 0; - } - } - max_len -= cc->mac_len; - - /* - * Rotate back the MAC value. The loop below does the constant-time - * rotation in time n*log n for a MAC output of length n. We assume - * that the MAC output length is no more than 64 bytes, so the - * rotation count fits on 6 bits. - */ - for (i = 5; i >= 0; i --) { - uint32_t rc; - - rc = (uint32_t)1 << i; - cond_rotate(rot_count >> i, tmp1, cc->mac_len, rc); - rot_count &= ~rc; - } - - /* - * Recompute the HMAC value. The input is the concatenation of - * the sequence number (8 bytes), the record header (5 bytes), - * and the payload. - * - * At that point, min_len is the minimum plaintext length, but - * max_len still includes the MAC length. - */ - br_enc64be(tmp2, cc->seq ++); - tmp2[8] = (unsigned char)record_type; - br_enc16be(tmp2 + 9, version); - br_enc16be(tmp2 + 11, len_nomac); - br_hmac_init(&hc, &cc->mac, cc->mac_len); - br_hmac_update(&hc, tmp2, 13); - br_hmac_outCT(&hc, buf, len_nomac, min_len, max_len, tmp2); - - /* - * Compare the extracted and recomputed MAC values. - */ - for (u = 0; u < cc->mac_len; u ++) { - good &= EQ0(tmp1[u] ^ tmp2[u]); - } - - /* - * Check that the plaintext length is valid. The previous - * check was on the encrypted length, but the padding may have - * turned shorter than expected. - * - * Once this final test is done, the critical "constant-time" - * section ends and we can make conditional jumps again. - */ - good &= LE(len_nomac, 16384); - - if (!good) { - return 0; - } - *data_len = len_nomac; - return buf; -} - -/* see bearssl_ssl.h */ -const br_sslrec_in_cbc_class br_sslrec_in_cbc_vtable = { - { - sizeof(br_sslrec_in_cbc_context), - (int (*)(const br_sslrec_in_class *const *, size_t)) - &cbc_check_length, - (unsigned char *(*)(const br_sslrec_in_class **, - int, unsigned, void *, size_t *)) - &cbc_decrypt - }, - (void (*)(const br_sslrec_in_cbc_class **, - const br_block_cbcdec_class *, const void *, size_t, - const br_hash_class *, const void *, size_t, size_t, - const void *)) - &in_cbc_init -}; - -/* - * For CBC output: - * - * -- With TLS 1.1+, there is an explicit IV. Generation method uses - * HMAC, computed over the current sequence number, and the current MAC - * key. The resulting value is truncated to the size of a block, and - * added at the head of the plaintext; it will get encrypted along with - * the data. This custom generation mechanism is "safe" under the - * assumption that HMAC behaves like a random oracle; since the MAC for - * a record is computed over the concatenation of the sequence number, - * the record header and the plaintext, the HMAC-for-IV will not collide - * with the normal HMAC. - * - * -- With TLS 1.0, for application data, we want to enforce a 1/n-1 - * split, as a countermeasure against chosen-plaintext attacks. We thus - * need to leave some room in the buffer for that extra record. - */ - -static void -out_cbc_init(br_sslrec_out_cbc_context *cc, - const br_block_cbcenc_class *bc_impl, - const void *bc_key, size_t bc_key_len, - const br_hash_class *dig_impl, - const void *mac_key, size_t mac_key_len, size_t mac_out_len, - const void *iv) -{ - cc->vtable = &br_sslrec_out_cbc_vtable; - cc->seq = 0; - bc_impl->init(&cc->bc.vtable, bc_key, bc_key_len); - br_hmac_key_init(&cc->mac, dig_impl, mac_key, mac_key_len); - cc->mac_len = mac_out_len; - if (iv == NULL) { - memset(cc->iv, 0, sizeof cc->iv); - cc->explicit_IV = 1; - } else { - memcpy(cc->iv, iv, bc_impl->block_size); - cc->explicit_IV = 0; - } -} - -static void -cbc_max_plaintext(const br_sslrec_out_cbc_context *cc, - size_t *start, size_t *end) -{ - size_t blen, len; - - blen = cc->bc.vtable->block_size; - if (cc->explicit_IV) { - *start += blen; - } else { - *start += 4 + ((cc->mac_len + blen + 1) & ~(blen - 1)); - } - len = (*end - *start) & ~(blen - 1); - len -= 1 + cc->mac_len; - if (len > 16384) { - len = 16384; - } - *end = *start + len; -} - -static unsigned char * -cbc_encrypt(br_sslrec_out_cbc_context *cc, - int record_type, unsigned version, void *data, size_t *data_len) -{ - unsigned char *buf, *rbuf; - size_t len, blen, plen; - unsigned char tmp[13]; - br_hmac_context hc; - - buf = data; - len = *data_len; - blen = cc->bc.vtable->block_size; - - /* - * If using TLS 1.0, with more than one byte of plaintext, and - * the record is application data, then we need to compute - * a "split". We do not perform the split on other record types - * because it turned out that some existing, deployed - * implementations of SSL/TLS do not tolerate the splitting of - * some message types (in particular the Finished message). - * - * If using TLS 1.1+, then there is an explicit IV. We produce - * that IV by adding an extra initial plaintext block, whose - * value is computed with HMAC over the record sequence number. - */ - if (cc->explicit_IV) { - /* - * We use here the fact that all the HMAC variants we - * support can produce at least 16 bytes, while all the - * block ciphers we support have blocks of no more than - * 16 bytes. Thus, we can always truncate the HMAC output - * down to the block size. - */ - br_enc64be(tmp, cc->seq); - br_hmac_init(&hc, &cc->mac, blen); - br_hmac_update(&hc, tmp, 8); - br_hmac_out(&hc, buf - blen); - rbuf = buf - blen - 5; - } else { - if (len > 1 && record_type == BR_SSL_APPLICATION_DATA) { - /* - * To do the split, we use a recursive invocation; - * since we only give one byte to the inner call, - * the recursion stops there. - * - * We need to compute the exact size of the extra - * record, so that the two resulting records end up - * being sequential in RAM. - * - * We use here the fact that cbc_max_plaintext() - * adjusted the start offset to leave room for the - * initial fragment. - */ - size_t xlen; - - rbuf = buf - 4 - - ((cc->mac_len + blen + 1) & ~(blen - 1)); - rbuf[0] = buf[0]; - xlen = 1; - rbuf = cbc_encrypt(cc, record_type, - version, rbuf, &xlen); - buf ++; - len --; - } else { - rbuf = buf - 5; - } - } - - /* - * Compute MAC. - */ - br_enc64be(tmp, cc->seq ++); - tmp[8] = record_type; - br_enc16be(tmp + 9, version); - br_enc16be(tmp + 11, len); - br_hmac_init(&hc, &cc->mac, cc->mac_len); - br_hmac_update(&hc, tmp, 13); - br_hmac_update(&hc, buf, len); - br_hmac_out(&hc, buf + len); - len += cc->mac_len; - - /* - * Add padding. - */ - plen = blen - (len & (blen - 1)); - memset(buf + len, (unsigned)plen - 1, plen); - len += plen; - - /* - * If an explicit IV is used, the corresponding extra block was - * already put in place earlier; we just have to account for it - * here. - */ - if (cc->explicit_IV) { - buf -= blen; - len += blen; - } - - /* - * Encrypt the whole thing. If there is an explicit IV, we also - * encrypt it, which is fine (encryption of a uniformly random - * block is still a uniformly random block). - */ - cc->bc.vtable->run(&cc->bc.vtable, cc->iv, buf, len); - - /* - * Add the header and return. - */ - buf[-5] = record_type; - br_enc16be(buf - 4, version); - br_enc16be(buf - 2, len); - *data_len = (size_t)((buf + len) - rbuf); - return rbuf; -} - -/* see bearssl_ssl.h */ -const br_sslrec_out_cbc_class br_sslrec_out_cbc_vtable = { - { - sizeof(br_sslrec_out_cbc_context), - (void (*)(const br_sslrec_out_class *const *, - size_t *, size_t *)) - &cbc_max_plaintext, - (unsigned char *(*)(const br_sslrec_out_class **, - int, unsigned, void *, size_t *)) - &cbc_encrypt - }, - (void (*)(const br_sslrec_out_cbc_class **, - const br_block_cbcenc_class *, const void *, size_t, - const br_hash_class *, const void *, size_t, size_t, - const void *)) - &out_cbc_init -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ssl_rec_ccm.c b/src/tls/bearssl/ssl_rec_ccm.c deleted file mode 100644 index f46c30ac0..000000000 --- a/src/tls/bearssl/ssl_rec_ccm.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * CCM initialisation. This does everything except setting the vtable, - * which depends on whether this is a context for encrypting or for - * decrypting. - */ -static void -gen_ccm_init(br_sslrec_ccm_context *cc, - const br_block_ctrcbc_class *bc_impl, - const void *key, size_t key_len, - const void *iv, size_t tag_len) -{ - cc->seq = 0; - bc_impl->init(&cc->bc.vtable, key, key_len); - memcpy(cc->iv, iv, sizeof cc->iv); - cc->tag_len = tag_len; -} - -static void -in_ccm_init(br_sslrec_ccm_context *cc, - const br_block_ctrcbc_class *bc_impl, - const void *key, size_t key_len, - const void *iv, size_t tag_len) -{ - cc->vtable.in = &br_sslrec_in_ccm_vtable; - gen_ccm_init(cc, bc_impl, key, key_len, iv, tag_len); -} - -static int -ccm_check_length(const br_sslrec_ccm_context *cc, size_t rlen) -{ - /* - * CCM overhead is 8 bytes for nonce_explicit, and the tag - * (normally 8 or 16 bytes, depending on cipher suite). - */ - size_t over; - - over = 8 + cc->tag_len; - return rlen >= over && rlen <= (16384 + over); -} - -static unsigned char * -ccm_decrypt(br_sslrec_ccm_context *cc, - int record_type, unsigned version, void *data, size_t *data_len) -{ - br_ccm_context zc; - unsigned char *buf; - unsigned char nonce[12], header[13]; - size_t len; - - buf = (unsigned char *)data + 8; - len = *data_len - (8 + cc->tag_len); - - /* - * Make nonce (implicit + explicit parts). - */ - memcpy(nonce, cc->iv, sizeof cc->iv); - memcpy(nonce + 4, data, 8); - - /* - * Assemble synthetic header for the AAD. - */ - br_enc64be(header, cc->seq ++); - header[8] = (unsigned char)record_type; - br_enc16be(header + 9, version); - br_enc16be(header + 11, len); - - /* - * Perform CCM decryption. - */ - br_ccm_init(&zc, &cc->bc.vtable); - br_ccm_reset(&zc, nonce, sizeof nonce, sizeof header, len, cc->tag_len); - br_ccm_aad_inject(&zc, header, sizeof header); - br_ccm_flip(&zc); - br_ccm_run(&zc, 0, buf, len); - if (!br_ccm_check_tag(&zc, buf + len)) { - return NULL; - } - *data_len = len; - return buf; -} - -/* see bearssl_ssl.h */ -const br_sslrec_in_ccm_class br_sslrec_in_ccm_vtable = { - { - sizeof(br_sslrec_ccm_context), - (int (*)(const br_sslrec_in_class *const *, size_t)) - &ccm_check_length, - (unsigned char *(*)(const br_sslrec_in_class **, - int, unsigned, void *, size_t *)) - &ccm_decrypt - }, - (void (*)(const br_sslrec_in_ccm_class **, - const br_block_ctrcbc_class *, const void *, size_t, - const void *, size_t)) - &in_ccm_init -}; - -static void -out_ccm_init(br_sslrec_ccm_context *cc, - const br_block_ctrcbc_class *bc_impl, - const void *key, size_t key_len, - const void *iv, size_t tag_len) -{ - cc->vtable.out = &br_sslrec_out_ccm_vtable; - gen_ccm_init(cc, bc_impl, key, key_len, iv, tag_len); -} - -static void -ccm_max_plaintext(const br_sslrec_ccm_context *cc, - size_t *start, size_t *end) -{ - size_t len; - - *start += 8; - len = *end - *start - cc->tag_len; - if (len > 16384) { - len = 16384; - } - *end = *start + len; -} - -static unsigned char * -ccm_encrypt(br_sslrec_ccm_context *cc, - int record_type, unsigned version, void *data, size_t *data_len) -{ - br_ccm_context zc; - unsigned char *buf; - unsigned char nonce[12], header[13]; - size_t len; - - buf = (unsigned char *)data; - len = *data_len; - - /* - * Make nonce; the explicit part is an encoding of the sequence - * number. - */ - memcpy(nonce, cc->iv, sizeof cc->iv); - br_enc64be(nonce + 4, cc->seq); - - /* - * Assemble synthetic header for the AAD. - */ - br_enc64be(header, cc->seq ++); - header[8] = (unsigned char)record_type; - br_enc16be(header + 9, version); - br_enc16be(header + 11, len); - - /* - * Perform CCM encryption. - */ - br_ccm_init(&zc, &cc->bc.vtable); - br_ccm_reset(&zc, nonce, sizeof nonce, sizeof header, len, cc->tag_len); - br_ccm_aad_inject(&zc, header, sizeof header); - br_ccm_flip(&zc); - br_ccm_run(&zc, 1, buf, len); - br_ccm_get_tag(&zc, buf + len); - - /* - * Assemble header and adjust pointer/length. - */ - len += 8 + cc->tag_len; - buf -= 13; - memcpy(buf + 5, nonce + 4, 8); - buf[0] = (unsigned char)record_type; - br_enc16be(buf + 1, version); - br_enc16be(buf + 3, len); - *data_len = len + 5; - return buf; -} - -/* see bearssl_ssl.h */ -const br_sslrec_out_ccm_class br_sslrec_out_ccm_vtable = { - { - sizeof(br_sslrec_ccm_context), - (void (*)(const br_sslrec_out_class *const *, - size_t *, size_t *)) - &ccm_max_plaintext, - (unsigned char *(*)(const br_sslrec_out_class **, - int, unsigned, void *, size_t *)) - &ccm_encrypt - }, - (void (*)(const br_sslrec_out_ccm_class **, - const br_block_ctrcbc_class *, const void *, size_t, - const void *, size_t)) - &out_ccm_init -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ssl_rec_chapol.c b/src/tls/bearssl/ssl_rec_chapol.c deleted file mode 100644 index bb612f6e7..000000000 --- a/src/tls/bearssl/ssl_rec_chapol.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -static void -gen_chapol_init(br_sslrec_chapol_context *cc, - br_chacha20_run ichacha, br_poly1305_run ipoly, - const void *key, const void *iv) -{ - cc->seq = 0; - cc->ichacha = ichacha; - cc->ipoly = ipoly; - memcpy(cc->key, key, sizeof cc->key); - memcpy(cc->iv, iv, sizeof cc->iv); -} - -static void -gen_chapol_process(br_sslrec_chapol_context *cc, - int record_type, unsigned version, void *data, size_t len, - void *tag, int encrypt) -{ - unsigned char header[13]; - unsigned char nonce[12]; - uint64_t seq; - size_t u; - - seq = cc->seq ++; - br_enc64be(header, seq); - header[8] = (unsigned char)record_type; - br_enc16be(header + 9, version); - br_enc16be(header + 11, len); - memcpy(nonce, cc->iv, 12); - for (u = 0; u < 8; u ++) { - nonce[11 - u] ^= (unsigned char)seq; - seq >>= 8; - } - cc->ipoly(cc->key, nonce, data, len, header, sizeof header, - tag, cc->ichacha, encrypt); -} - -static void -in_chapol_init(br_sslrec_chapol_context *cc, - br_chacha20_run ichacha, br_poly1305_run ipoly, - const void *key, const void *iv) -{ - cc->vtable.in = &br_sslrec_in_chapol_vtable; - gen_chapol_init(cc, ichacha, ipoly, key, iv); -} - -static int -chapol_check_length(const br_sslrec_chapol_context *cc, size_t rlen) -{ - /* - * Overhead is just the authentication tag (16 bytes). - */ - (void)cc; - return rlen >= 16 && rlen <= (16384 + 16); -} - -static unsigned char * -chapol_decrypt(br_sslrec_chapol_context *cc, - int record_type, unsigned version, void *data, size_t *data_len) -{ - unsigned char *buf; - size_t u, len; - unsigned char tag[16]; - unsigned bad; - - buf = data; - len = *data_len - 16; - gen_chapol_process(cc, record_type, version, buf, len, tag, 0); - bad = 0; - for (u = 0; u < 16; u ++) { - bad |= tag[u] ^ buf[len + u]; - } - if (bad) { - return NULL; - } - *data_len = len; - return buf; -} - -/* see bearssl_ssl.h */ -const br_sslrec_in_chapol_class br_sslrec_in_chapol_vtable = { - { - sizeof(br_sslrec_chapol_context), - (int (*)(const br_sslrec_in_class *const *, size_t)) - &chapol_check_length, - (unsigned char *(*)(const br_sslrec_in_class **, - int, unsigned, void *, size_t *)) - &chapol_decrypt - }, - (void (*)(const br_sslrec_in_chapol_class **, - br_chacha20_run, br_poly1305_run, - const void *, const void *)) - &in_chapol_init -}; - -static void -out_chapol_init(br_sslrec_chapol_context *cc, - br_chacha20_run ichacha, br_poly1305_run ipoly, - const void *key, const void *iv) -{ - cc->vtable.out = &br_sslrec_out_chapol_vtable; - gen_chapol_init(cc, ichacha, ipoly, key, iv); -} - -static void -chapol_max_plaintext(const br_sslrec_chapol_context *cc, - size_t *start, size_t *end) -{ - size_t len; - - (void)cc; - len = *end - *start - 16; - if (len > 16384) { - len = 16384; - } - *end = *start + len; -} - -static unsigned char * -chapol_encrypt(br_sslrec_chapol_context *cc, - int record_type, unsigned version, void *data, size_t *data_len) -{ - unsigned char *buf; - size_t len; - - buf = data; - len = *data_len; - gen_chapol_process(cc, record_type, version, buf, len, buf + len, 1); - buf -= 5; - buf[0] = (unsigned char)record_type; - br_enc16be(buf + 1, version); - br_enc16be(buf + 3, len + 16); - *data_len = len + 21; - return buf; -} - -/* see bearssl_ssl.h */ -const br_sslrec_out_chapol_class br_sslrec_out_chapol_vtable = { - { - sizeof(br_sslrec_chapol_context), - (void (*)(const br_sslrec_out_class *const *, - size_t *, size_t *)) - &chapol_max_plaintext, - (unsigned char *(*)(const br_sslrec_out_class **, - int, unsigned, void *, size_t *)) - &chapol_encrypt - }, - (void (*)(const br_sslrec_out_chapol_class **, - br_chacha20_run, br_poly1305_run, - const void *, const void *)) - &out_chapol_init -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ssl_rec_gcm.c b/src/tls/bearssl/ssl_rec_gcm.c deleted file mode 100644 index 4492f1ca9..000000000 --- a/src/tls/bearssl/ssl_rec_gcm.c +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* - * GCM initialisation. This does everything except setting the vtable, - * which depends on whether this is a context for encrypting or for - * decrypting. - */ -static void -gen_gcm_init(br_sslrec_gcm_context *cc, - const br_block_ctr_class *bc_impl, - const void *key, size_t key_len, - br_ghash gh_impl, - const void *iv) -{ - unsigned char tmp[12]; - - cc->seq = 0; - bc_impl->init(&cc->bc.vtable, key, key_len); - cc->gh = gh_impl; - memcpy(cc->iv, iv, sizeof cc->iv); - memset(cc->h, 0, sizeof cc->h); - memset(tmp, 0, sizeof tmp); - bc_impl->run(&cc->bc.vtable, tmp, 0, cc->h, sizeof cc->h); -} - -static void -in_gcm_init(br_sslrec_gcm_context *cc, - const br_block_ctr_class *bc_impl, - const void *key, size_t key_len, - br_ghash gh_impl, - const void *iv) -{ - cc->vtable.in = &br_sslrec_in_gcm_vtable; - gen_gcm_init(cc, bc_impl, key, key_len, gh_impl, iv); -} - -static int -gcm_check_length(const br_sslrec_gcm_context *cc, size_t rlen) -{ - /* - * GCM adds a fixed overhead: - * 8 bytes for the nonce_explicit (before the ciphertext) - * 16 bytes for the authentication tag (after the ciphertext) - */ - (void)cc; - return rlen >= 24 && rlen <= (16384 + 24); -} - -/* - * Compute the authentication tag. The value written in 'tag' must still - * be CTR-encrypted. - */ -static void -do_tag(br_sslrec_gcm_context *cc, - int record_type, unsigned version, - void *data, size_t len, void *tag) -{ - unsigned char header[13]; - unsigned char footer[16]; - - /* - * Compute authentication tag. Three elements must be injected in - * sequence, each possibly 0-padded to reach a length multiple - * of the block size: the 13-byte header (sequence number, record - * type, protocol version, record length), the cipher text, and - * the word containing the encodings of the bit lengths of the two - * other elements. - */ - br_enc64be(header, cc->seq ++); - header[8] = (unsigned char)record_type; - br_enc16be(header + 9, version); - br_enc16be(header + 11, len); - br_enc64be(footer, (uint64_t)(sizeof header) << 3); - br_enc64be(footer + 8, (uint64_t)len << 3); - memset(tag, 0, 16); - cc->gh(tag, cc->h, header, sizeof header); - cc->gh(tag, cc->h, data, len); - cc->gh(tag, cc->h, footer, sizeof footer); -} - -/* - * Do CTR encryption. This also does CTR encryption of a single block at - * address 'xortag' with the counter value appropriate for the final - * processing of the authentication tag. - */ -static void -do_ctr(br_sslrec_gcm_context *cc, const void *nonce, void *data, size_t len, - void *xortag) -{ - unsigned char iv[12]; - - memcpy(iv, cc->iv, 4); - memcpy(iv + 4, nonce, 8); - cc->bc.vtable->run(&cc->bc.vtable, iv, 2, data, len); - cc->bc.vtable->run(&cc->bc.vtable, iv, 1, xortag, 16); -} - -static unsigned char * -gcm_decrypt(br_sslrec_gcm_context *cc, - int record_type, unsigned version, void *data, size_t *data_len) -{ - unsigned char *buf; - size_t len, u; - uint32_t bad; - unsigned char tag[16]; - - buf = (unsigned char *)data + 8; - len = *data_len - 24; - do_tag(cc, record_type, version, buf, len, tag); - do_ctr(cc, data, buf, len, tag); - - /* - * Compare the computed tag with the value from the record. It - * is possibly useless to do a constant-time comparison here, - * but it does not hurt. - */ - bad = 0; - for (u = 0; u < 16; u ++) { - bad |= tag[u] ^ buf[len + u]; - } - if (bad) { - return NULL; - } - *data_len = len; - return buf; -} - -/* see bearssl_ssl.h */ -const br_sslrec_in_gcm_class br_sslrec_in_gcm_vtable = { - { - sizeof(br_sslrec_gcm_context), - (int (*)(const br_sslrec_in_class *const *, size_t)) - &gcm_check_length, - (unsigned char *(*)(const br_sslrec_in_class **, - int, unsigned, void *, size_t *)) - &gcm_decrypt - }, - (void (*)(const br_sslrec_in_gcm_class **, - const br_block_ctr_class *, const void *, size_t, - br_ghash, const void *)) - &in_gcm_init -}; - -static void -out_gcm_init(br_sslrec_gcm_context *cc, - const br_block_ctr_class *bc_impl, - const void *key, size_t key_len, - br_ghash gh_impl, - const void *iv) -{ - cc->vtable.out = &br_sslrec_out_gcm_vtable; - gen_gcm_init(cc, bc_impl, key, key_len, gh_impl, iv); -} - -static void -gcm_max_plaintext(const br_sslrec_gcm_context *cc, - size_t *start, size_t *end) -{ - size_t len; - - (void)cc; - *start += 8; - len = *end - *start - 16; - if (len > 16384) { - len = 16384; - } - *end = *start + len; -} - -static unsigned char * -gcm_encrypt(br_sslrec_gcm_context *cc, - int record_type, unsigned version, void *data, size_t *data_len) -{ - unsigned char *buf; - size_t u, len; - unsigned char tmp[16]; - - buf = (unsigned char *)data; - len = *data_len; - memset(tmp, 0, sizeof tmp); - br_enc64be(buf - 8, cc->seq); - do_ctr(cc, buf - 8, buf, len, tmp); - do_tag(cc, record_type, version, buf, len, buf + len); - for (u = 0; u < 16; u ++) { - buf[len + u] ^= tmp[u]; - } - len += 24; - buf -= 13; - buf[0] = (unsigned char)record_type; - br_enc16be(buf + 1, version); - br_enc16be(buf + 3, len); - *data_len = len + 5; - return buf; -} - -/* see bearssl_ssl.h */ -const br_sslrec_out_gcm_class br_sslrec_out_gcm_vtable = { - { - sizeof(br_sslrec_gcm_context), - (void (*)(const br_sslrec_out_class *const *, - size_t *, size_t *)) - &gcm_max_plaintext, - (unsigned char *(*)(const br_sslrec_out_class **, - int, unsigned, void *, size_t *)) - &gcm_encrypt - }, - (void (*)(const br_sslrec_out_gcm_class **, - const br_block_ctr_class *, const void *, size_t, - br_ghash, const void *)) - &out_gcm_init -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ssl_scert_single_ec.c b/src/tls/bearssl/ssl_scert_single_ec.c deleted file mode 100644 index 164709b1c..000000000 --- a/src/tls/bearssl/ssl_scert_single_ec.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -static int -se_choose(const br_ssl_server_policy_class **pctx, - const br_ssl_server_context *cc, - br_ssl_server_choices *choices) -{ - br_ssl_server_policy_ec_context *pc; - const br_suite_translated *st; - size_t u, st_num; - unsigned hash_id; - - pc = (br_ssl_server_policy_ec_context *)pctx; - st = br_ssl_server_get_client_suites(cc, &st_num); - hash_id = br_ssl_choose_hash(br_ssl_server_get_client_hashes(cc) >> 8); - if (cc->eng.session.version < BR_TLS12) { - hash_id = br_sha1_ID; - } - choices->chain = pc->chain; - choices->chain_len = pc->chain_len; - for (u = 0; u < st_num; u ++) { - unsigned tt; - - tt = st[u][1]; - switch (tt >> 12) { - case BR_SSLKEYX_ECDH_RSA: - if ((pc->allowed_usages & BR_KEYTYPE_KEYX) != 0 - && pc->cert_issuer_key_type == BR_KEYTYPE_RSA) - { - choices->cipher_suite = st[u][0]; - return 1; - } - break; - case BR_SSLKEYX_ECDH_ECDSA: - if ((pc->allowed_usages & BR_KEYTYPE_KEYX) != 0 - && pc->cert_issuer_key_type == BR_KEYTYPE_EC) - { - choices->cipher_suite = st[u][0]; - return 1; - } - break; - case BR_SSLKEYX_ECDHE_ECDSA: - if ((pc->allowed_usages & BR_KEYTYPE_SIGN) != 0 - && hash_id != 0) - { - choices->cipher_suite = st[u][0]; - choices->algo_id = hash_id + 0xFF00; - return 1; - } - break; - } - } - return 0; -} - -static uint32_t -se_do_keyx(const br_ssl_server_policy_class **pctx, - unsigned char *data, size_t *len) -{ - br_ssl_server_policy_ec_context *pc; - uint32_t r; - size_t xoff, xlen; - - pc = (br_ssl_server_policy_ec_context *)pctx; - r = pc->iec->mul(data, *len, pc->sk->x, pc->sk->xlen, pc->sk->curve); - xoff = pc->iec->xoff(pc->sk->curve, &xlen); - memmove(data, data + xoff, xlen); - *len = xlen; - return r; -} - -static size_t -se_do_sign(const br_ssl_server_policy_class **pctx, - unsigned algo_id, unsigned char *data, size_t hv_len, size_t len) -{ - br_ssl_server_policy_ec_context *pc; - unsigned char hv[64]; - const br_hash_class *hc; - - algo_id &= 0xFF; - pc = (br_ssl_server_policy_ec_context *)pctx; - hc = br_multihash_getimpl(pc->mhash, algo_id); - if (hc == NULL) { - return 0; - } - memcpy(hv, data, hv_len); - if (len < 139) { - return 0; - } - return pc->iecdsa(pc->iec, hc, hv, pc->sk, data); -} - -static const br_ssl_server_policy_class se_policy_vtable = { - sizeof(br_ssl_server_policy_ec_context), - se_choose, - se_do_keyx, - se_do_sign -}; - -/* see bearssl_ssl.h */ -void -br_ssl_server_set_single_ec(br_ssl_server_context *cc, - const br_x509_certificate *chain, size_t chain_len, - const br_ec_private_key *sk, unsigned allowed_usages, - unsigned cert_issuer_key_type, - const br_ec_impl *iec, br_ecdsa_sign iecdsa) -{ - cc->chain_handler.single_ec.vtable = &se_policy_vtable; - cc->chain_handler.single_ec.chain = chain; - cc->chain_handler.single_ec.chain_len = chain_len; - cc->chain_handler.single_ec.sk = sk; - cc->chain_handler.single_ec.allowed_usages = allowed_usages; - cc->chain_handler.single_ec.cert_issuer_key_type = cert_issuer_key_type; - cc->chain_handler.single_ec.mhash = &cc->eng.mhash; - cc->chain_handler.single_ec.iec = iec; - cc->chain_handler.single_ec.iecdsa = iecdsa; - cc->policy_vtable = &cc->chain_handler.single_ec.vtable; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ssl_scert_single_rsa.c b/src/tls/bearssl/ssl_scert_single_rsa.c deleted file mode 100644 index d8ebac1aa..000000000 --- a/src/tls/bearssl/ssl_scert_single_rsa.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -static int -sr_choose(const br_ssl_server_policy_class **pctx, - const br_ssl_server_context *cc, - br_ssl_server_choices *choices) -{ - br_ssl_server_policy_rsa_context *pc; - const br_suite_translated *st; - size_t u, st_num; - unsigned hash_id; - int fh; - - pc = (br_ssl_server_policy_rsa_context *)pctx; - st = br_ssl_server_get_client_suites(cc, &st_num); - if (cc->eng.session.version < BR_TLS12) { - hash_id = 0; - fh = 1; - } else { - hash_id = br_ssl_choose_hash( - br_ssl_server_get_client_hashes(cc)); - fh = (hash_id != 0); - } - choices->chain = pc->chain; - choices->chain_len = pc->chain_len; - for (u = 0; u < st_num; u ++) { - unsigned tt; - - tt = st[u][1]; - switch (tt >> 12) { - case BR_SSLKEYX_RSA: - if ((pc->allowed_usages & BR_KEYTYPE_KEYX) != 0) { - choices->cipher_suite = st[u][0]; - return 1; - } - break; - case BR_SSLKEYX_ECDHE_RSA: - if ((pc->allowed_usages & BR_KEYTYPE_SIGN) != 0 && fh) { - choices->cipher_suite = st[u][0]; - choices->algo_id = hash_id + 0xFF00; - return 1; - } - break; - } - } - return 0; -} - -static uint32_t -sr_do_keyx(const br_ssl_server_policy_class **pctx, - unsigned char *data, size_t *len) -{ - br_ssl_server_policy_rsa_context *pc; - - pc = (br_ssl_server_policy_rsa_context *)pctx; - return br_rsa_ssl_decrypt(pc->irsacore, pc->sk, data, *len); -} - -/* - * OID for hash functions in RSA signatures. - */ -static const unsigned char HASH_OID_SHA1[] = { - 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A -}; - -static const unsigned char HASH_OID_SHA224[] = { - 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04 -}; - -static const unsigned char HASH_OID_SHA256[] = { - 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01 -}; - -static const unsigned char HASH_OID_SHA384[] = { - 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02 -}; - -static const unsigned char HASH_OID_SHA512[] = { - 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03 -}; - -static const unsigned char *HASH_OID[] = { - HASH_OID_SHA1, - HASH_OID_SHA224, - HASH_OID_SHA256, - HASH_OID_SHA384, - HASH_OID_SHA512 -}; - -static size_t -sr_do_sign(const br_ssl_server_policy_class **pctx, - unsigned algo_id, unsigned char *data, size_t hv_len, size_t len) -{ - br_ssl_server_policy_rsa_context *pc; - unsigned char hv[64]; - size_t sig_len; - const unsigned char *hash_oid; - - pc = (br_ssl_server_policy_rsa_context *)pctx; - memcpy(hv, data, hv_len); - algo_id &= 0xFF; - if (algo_id == 0) { - hash_oid = NULL; - } else if (algo_id >= 2 && algo_id <= 6) { - hash_oid = HASH_OID[algo_id - 2]; - } else { - return 0; - } - sig_len = (pc->sk->n_bitlen + 7) >> 3; - if (len < sig_len) { - return 0; - } - return pc->irsasign(hash_oid, hv, hv_len, pc->sk, data) ? sig_len : 0; -} - -static const br_ssl_server_policy_class sr_policy_vtable = { - sizeof(br_ssl_server_policy_rsa_context), - sr_choose, - sr_do_keyx, - sr_do_sign -}; - -/* see bearssl_ssl.h */ -void -br_ssl_server_set_single_rsa(br_ssl_server_context *cc, - const br_x509_certificate *chain, size_t chain_len, - const br_rsa_private_key *sk, unsigned allowed_usages, - br_rsa_private irsacore, br_rsa_pkcs1_sign irsasign) -{ - cc->chain_handler.single_rsa.vtable = &sr_policy_vtable; - cc->chain_handler.single_rsa.chain = chain; - cc->chain_handler.single_rsa.chain_len = chain_len; - cc->chain_handler.single_rsa.sk = sk; - cc->chain_handler.single_rsa.allowed_usages = allowed_usages; - cc->chain_handler.single_rsa.irsacore = irsacore; - cc->chain_handler.single_rsa.irsasign = irsasign; - cc->policy_vtable = &cc->chain_handler.single_rsa.vtable; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ssl_server.c b/src/tls/bearssl/ssl_server.c deleted file mode 100644 index 22fa641e1..000000000 --- a/src/tls/bearssl/ssl_server.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_ssl.h */ -void -br_ssl_server_zero(br_ssl_server_context *cc) -{ - /* - * For really standard C, we should explicitly set to NULL all - * pointers, and 0 all other fields. However, on all our target - * architectures, a direct memset() will work, be faster, and - * use a lot less code. - */ - memset(cc, 0, sizeof *cc); -} - -/* see bearssl_ssl.h */ -int -br_ssl_server_reset(br_ssl_server_context *cc) -{ - br_ssl_engine_set_buffer(&cc->eng, NULL, 0, 0); - if (!br_ssl_engine_init_rand(&cc->eng)) { - return 0; - } - cc->eng.reneg = 0; - br_ssl_engine_hs_reset(&cc->eng, - br_ssl_hs_server_init_main, br_ssl_hs_server_run); - return br_ssl_engine_last_error(&cc->eng) == BR_ERR_OK; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ssl_server_full_ec.c b/src/tls/bearssl/ssl_server_full_ec.c deleted file mode 100644 index 3c7792594..000000000 --- a/src/tls/bearssl/ssl_server_full_ec.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_ssl.h */ -void -br_ssl_server_init_full_ec(br_ssl_server_context *cc, - const br_x509_certificate *chain, size_t chain_len, - unsigned cert_issuer_key_type, const br_ec_private_key *sk) -{ - /* - * The "full" profile supports all implemented cipher suites. - * - * Rationale for suite order, from most important to least - * important rule: - * - * -- Don't use 3DES if AES is available. - * -- Try to have Forward Secrecy (ECDHE suite) if possible. - * -- ChaCha20+Poly1305 is better than AES/GCM (faster, smaller). - * -- GCM is better than CCM and CBC. CCM is better than CBC. - * -- CCM is better than CCM_8. - * -- AES-128 is preferred over AES-256 (AES-128 is already - * strong enough, and AES-256 is 40% more expensive). - * - * Note that for ECDH suites, the list will be automatically - * filtered based on the issuing CA key type. - */ - static const uint16_t suites[] = { - BR_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, - BR_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, - BR_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, - BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, - BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, - BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, - BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, - BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, - BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, - BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, - BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, - BR_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, - BR_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, - BR_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, - BR_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, - BR_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, - BR_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, - BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, - BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, - BR_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, - BR_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, - BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, - BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, - BR_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, - BR_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, - BR_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA - }; - - /* - * All hash functions are activated. - * Note: the X.509 validation engine will nonetheless refuse to - * validate signatures that use MD5 as hash function. - */ - static const br_hash_class *hashes[] = { - &br_md5_vtable, - &br_sha1_vtable, - &br_sha224_vtable, - &br_sha256_vtable, - &br_sha384_vtable, - &br_sha512_vtable - }; - - int id; - - /* - * Reset server context and set supported versions from TLS-1.0 - * to TLS-1.2 (inclusive). - */ - br_ssl_server_zero(cc); - br_ssl_engine_set_versions(&cc->eng, BR_TLS10, BR_TLS12); - - /* - * Set suites and elliptic curve implementation (for ECDHE). - */ - br_ssl_engine_set_suites(&cc->eng, suites, - (sizeof suites) / (sizeof suites[0])); - br_ssl_engine_set_default_ec(&cc->eng); - - /* - * Set the "server policy": handler for the certificate chain - * and private key operations. - */ - br_ssl_server_set_single_ec(cc, chain, chain_len, sk, - BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN, - cert_issuer_key_type, - br_ssl_engine_get_ec(&cc->eng), -#if BR_LOMUL - br_ecdsa_i15_sign_asn1 -#else - br_ecdsa_i31_sign_asn1 -#endif - ); - - /* - * Set supported hash functions. - */ - for (id = br_md5_ID; id <= br_sha512_ID; id ++) { - const br_hash_class *hc; - - hc = hashes[id - 1]; - br_ssl_engine_set_hash(&cc->eng, id, hc); - } - - /* - * Set the PRF implementations. - */ - br_ssl_engine_set_prf10(&cc->eng, &br_tls10_prf); - br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf); - br_ssl_engine_set_prf_sha384(&cc->eng, &br_tls12_sha384_prf); - - /* - * Symmetric encryption. - */ - br_ssl_engine_set_default_aes_cbc(&cc->eng); - br_ssl_engine_set_default_aes_ccm(&cc->eng); - br_ssl_engine_set_default_aes_gcm(&cc->eng); - br_ssl_engine_set_default_des_cbc(&cc->eng); - br_ssl_engine_set_default_chapol(&cc->eng); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ssl_server_full_rsa.c b/src/tls/bearssl/ssl_server_full_rsa.c deleted file mode 100644 index 3ce698a8a..000000000 --- a/src/tls/bearssl/ssl_server_full_rsa.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_ssl.h */ -void -br_ssl_server_init_full_rsa(br_ssl_server_context *cc, - const br_x509_certificate *chain, size_t chain_len, - const br_rsa_private_key *sk) -{ - /* - * The "full" profile supports all implemented cipher suites. - * - * Rationale for suite order, from most important to least - * important rule: - * - * -- Don't use 3DES if AES is available. - * -- Try to have Forward Secrecy (ECDHE suite) if possible. - * -- ChaCha20+Poly1305 is better than AES/GCM (faster, smaller). - * -- GCM is better than CBC. - * -- AES-128 is preferred over AES-256 (AES-128 is already - * strong enough, and AES-256 is 40% more expensive). - */ - static const uint16_t suites[] = { - BR_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, - BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - BR_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, - BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, - BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, - BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, - BR_TLS_RSA_WITH_AES_128_GCM_SHA256, - BR_TLS_RSA_WITH_AES_256_GCM_SHA384, - BR_TLS_RSA_WITH_AES_128_CCM, - BR_TLS_RSA_WITH_AES_256_CCM, - BR_TLS_RSA_WITH_AES_128_CCM_8, - BR_TLS_RSA_WITH_AES_256_CCM_8, - BR_TLS_RSA_WITH_AES_128_CBC_SHA256, - BR_TLS_RSA_WITH_AES_256_CBC_SHA256, - BR_TLS_RSA_WITH_AES_128_CBC_SHA, - BR_TLS_RSA_WITH_AES_256_CBC_SHA, - BR_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, - BR_TLS_RSA_WITH_3DES_EDE_CBC_SHA - }; - - /* - * All hash functions are activated. - * Note: the X.509 validation engine will nonetheless refuse to - * validate signatures that use MD5 as hash function. - */ - static const br_hash_class *hashes[] = { - &br_md5_vtable, - &br_sha1_vtable, - &br_sha224_vtable, - &br_sha256_vtable, - &br_sha384_vtable, - &br_sha512_vtable - }; - - int id; - - /* - * Reset server context and set supported versions from TLS-1.0 - * to TLS-1.2 (inclusive). - */ - br_ssl_server_zero(cc); - br_ssl_engine_set_versions(&cc->eng, BR_TLS10, BR_TLS12); - - /* - * Set suites and elliptic curve implementation (for ECDHE). - */ - br_ssl_engine_set_suites(&cc->eng, suites, - (sizeof suites) / (sizeof suites[0])); - br_ssl_engine_set_default_ec(&cc->eng); - - /* - * Set the "server policy": handler for the certificate chain - * and private key operations. - */ - br_ssl_server_set_single_rsa(cc, chain, chain_len, sk, - BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN, - br_rsa_private_get_default(), - br_rsa_pkcs1_sign_get_default()); - - /* - * Set supported hash functions. - */ - for (id = br_md5_ID; id <= br_sha512_ID; id ++) { - const br_hash_class *hc; - - hc = hashes[id - 1]; - br_ssl_engine_set_hash(&cc->eng, id, hc); - } - - /* - * Set the PRF implementations. - */ - br_ssl_engine_set_prf10(&cc->eng, &br_tls10_prf); - br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf); - br_ssl_engine_set_prf_sha384(&cc->eng, &br_tls12_sha384_prf); - - /* - * Symmetric encryption. - */ - br_ssl_engine_set_default_aes_cbc(&cc->eng); - br_ssl_engine_set_default_aes_ccm(&cc->eng); - br_ssl_engine_set_default_aes_gcm(&cc->eng); - br_ssl_engine_set_default_des_cbc(&cc->eng); - br_ssl_engine_set_default_chapol(&cc->eng); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ssl_server_mine2c.c b/src/tls/bearssl/ssl_server_mine2c.c deleted file mode 100644 index 19a7b2346..000000000 --- a/src/tls/bearssl/ssl_server_mine2c.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_ssl.h */ -void -br_ssl_server_init_mine2c(br_ssl_server_context *cc, - const br_x509_certificate *chain, size_t chain_len, - const br_rsa_private_key *sk) -{ - static const uint16_t suites[] = { - BR_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 - }; - - /* - * Reset server context and set supported versions to TLS-1.2 (only). - */ - br_ssl_server_zero(cc); - br_ssl_engine_set_versions(&cc->eng, BR_TLS12, BR_TLS12); - - /* - * Set suites and elliptic curve implementation (for ECDHE). - */ - br_ssl_engine_set_suites(&cc->eng, suites, - (sizeof suites) / (sizeof suites[0])); - br_ssl_engine_set_ec(&cc->eng, &br_ec_all_m15); - - /* - * Set the "server policy": handler for the certificate chain - * and private key operations. - */ - br_ssl_server_set_single_rsa(cc, chain, chain_len, sk, - BR_KEYTYPE_SIGN, 0, br_rsa_i31_pkcs1_sign); - - /* - * Set supported hash functions. - */ - br_ssl_engine_set_hash(&cc->eng, br_sha256_ID, &br_sha256_vtable); - - /* - * Set the PRF implementations. - */ - br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf); - - /* - * Symmetric encryption. - */ - br_ssl_engine_set_default_chapol(&cc->eng); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ssl_server_mine2g.c b/src/tls/bearssl/ssl_server_mine2g.c deleted file mode 100644 index 1afbb9c90..000000000 --- a/src/tls/bearssl/ssl_server_mine2g.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_ssl.h */ -void -br_ssl_server_init_mine2g(br_ssl_server_context *cc, - const br_x509_certificate *chain, size_t chain_len, - const br_rsa_private_key *sk) -{ - static const uint16_t suites[] = { - BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - }; - - /* - * Reset server context and set supported versions to TLS-1.2 (only). - */ - br_ssl_server_zero(cc); - br_ssl_engine_set_versions(&cc->eng, BR_TLS12, BR_TLS12); - - /* - * Set suites and elliptic curve implementation (for ECDHE). - */ - br_ssl_engine_set_suites(&cc->eng, suites, - (sizeof suites) / (sizeof suites[0])); - br_ssl_engine_set_ec(&cc->eng, &br_ec_all_m15); - - /* - * Set the "server policy": handler for the certificate chain - * and private key operations. - */ - br_ssl_server_set_single_rsa(cc, chain, chain_len, sk, - BR_KEYTYPE_SIGN, 0, br_rsa_i31_pkcs1_sign); - - /* - * Set supported hash functions. - */ - br_ssl_engine_set_hash(&cc->eng, br_sha256_ID, &br_sha256_vtable); - - /* - * Set the PRF implementations. - */ - br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf); - - /* - * Symmetric encryption. - */ - br_ssl_engine_set_default_aes_gcm(&cc->eng); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ssl_server_minf2c.c b/src/tls/bearssl/ssl_server_minf2c.c deleted file mode 100644 index ef4794680..000000000 --- a/src/tls/bearssl/ssl_server_minf2c.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_ssl.h */ -void -br_ssl_server_init_minf2c(br_ssl_server_context *cc, - const br_x509_certificate *chain, size_t chain_len, - const br_ec_private_key *sk) -{ - static const uint16_t suites[] = { - BR_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 - }; - - /* - * Reset server context and set supported versions to TLS-1.2 (only). - */ - br_ssl_server_zero(cc); - br_ssl_engine_set_versions(&cc->eng, BR_TLS12, BR_TLS12); - - /* - * Set suites and elliptic curve implementation (for ECDHE). - */ - br_ssl_engine_set_suites(&cc->eng, suites, - (sizeof suites) / (sizeof suites[0])); - br_ssl_engine_set_ec(&cc->eng, &br_ec_all_m15); - - /* - * Set the "server policy": handler for the certificate chain - * and private key operations. - */ - br_ssl_server_set_single_ec(cc, chain, chain_len, sk, - BR_KEYTYPE_SIGN, 0, &br_ec_all_m15, br_ecdsa_i31_sign_asn1); - - /* - * Set supported hash functions. - */ - br_ssl_engine_set_hash(&cc->eng, br_sha256_ID, &br_sha256_vtable); - - /* - * Set the PRF implementations. - */ - br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf); - - /* - * Symmetric encryption. - */ - br_ssl_engine_set_default_chapol(&cc->eng); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ssl_server_minf2g.c b/src/tls/bearssl/ssl_server_minf2g.c deleted file mode 100644 index 60096afaa..000000000 --- a/src/tls/bearssl/ssl_server_minf2g.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_ssl.h */ -void -br_ssl_server_init_minf2g(br_ssl_server_context *cc, - const br_x509_certificate *chain, size_t chain_len, - const br_ec_private_key *sk) -{ - static const uint16_t suites[] = { - BR_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - }; - - /* - * Reset server context and set supported versions to TLS-1.2 (only). - */ - br_ssl_server_zero(cc); - br_ssl_engine_set_versions(&cc->eng, BR_TLS12, BR_TLS12); - - /* - * Set suites and elliptic curve implementation (for ECDHE). - */ - br_ssl_engine_set_suites(&cc->eng, suites, - (sizeof suites) / (sizeof suites[0])); - br_ssl_engine_set_ec(&cc->eng, &br_ec_all_m15); - - /* - * Set the "server policy": handler for the certificate chain - * and private key operations. - */ - br_ssl_server_set_single_ec(cc, chain, chain_len, sk, - BR_KEYTYPE_SIGN, 0, &br_ec_all_m15, br_ecdsa_i31_sign_asn1); - - /* - * Set supported hash functions. - */ - br_ssl_engine_set_hash(&cc->eng, br_sha256_ID, &br_sha256_vtable); - - /* - * Set the PRF implementations. - */ - br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf); - - /* - * Symmetric encryption. - */ - br_ssl_engine_set_default_aes_gcm(&cc->eng); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ssl_server_minr2g.c b/src/tls/bearssl/ssl_server_minr2g.c deleted file mode 100644 index 529bab59e..000000000 --- a/src/tls/bearssl/ssl_server_minr2g.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_ssl.h */ -void -br_ssl_server_init_minr2g(br_ssl_server_context *cc, - const br_x509_certificate *chain, size_t chain_len, - const br_rsa_private_key *sk) -{ - static const uint16_t suites[] = { - BR_TLS_RSA_WITH_AES_128_GCM_SHA256 - }; - - /* - * Reset server context and set supported versions to TLS-1.2 (only). - */ - br_ssl_server_zero(cc); - br_ssl_engine_set_versions(&cc->eng, BR_TLS12, BR_TLS12); - - /* - * Set suites. - */ - br_ssl_engine_set_suites(&cc->eng, suites, - (sizeof suites) / (sizeof suites[0])); - - /* - * Set the "server policy": handler for the certificate chain - * and private key operations. - */ - br_ssl_server_set_single_rsa(cc, chain, chain_len, sk, - BR_KEYTYPE_KEYX, br_rsa_i31_private, 0); - - /* - * Set supported hash functions. - */ - br_ssl_engine_set_hash(&cc->eng, br_sha256_ID, &br_sha256_vtable); - - /* - * Set the PRF implementations. - */ - br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf); - - /* - * Symmetric encryption. - */ - br_ssl_engine_set_default_aes_gcm(&cc->eng); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ssl_server_minu2g.c b/src/tls/bearssl/ssl_server_minu2g.c deleted file mode 100644 index fb63d69a3..000000000 --- a/src/tls/bearssl/ssl_server_minu2g.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_ssl.h */ -void -br_ssl_server_init_minu2g(br_ssl_server_context *cc, - const br_x509_certificate *chain, size_t chain_len, - const br_ec_private_key *sk) -{ - static const uint16_t suites[] = { - BR_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 - }; - - /* - * Reset server context and set supported versions to TLS-1.2 (only). - */ - br_ssl_server_zero(cc); - br_ssl_engine_set_versions(&cc->eng, BR_TLS12, BR_TLS12); - - /* - * Set suites. - */ - br_ssl_engine_set_suites(&cc->eng, suites, - (sizeof suites) / (sizeof suites[0])); - - /* - * Set the "server policy": handler for the certificate chain - * and private key operations. - */ - br_ssl_server_set_single_ec(cc, chain, chain_len, sk, - BR_KEYTYPE_KEYX, BR_KEYTYPE_RSA, &br_ec_all_m15, 0); - - /* - * Set supported hash functions. - */ - br_ssl_engine_set_hash(&cc->eng, br_sha256_ID, &br_sha256_vtable); - - /* - * Set the PRF implementations. - */ - br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf); - - /* - * Symmetric encryption. - */ - br_ssl_engine_set_default_aes_gcm(&cc->eng); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/ssl_server_minv2g.c b/src/tls/bearssl/ssl_server_minv2g.c deleted file mode 100644 index 149ab75dc..000000000 --- a/src/tls/bearssl/ssl_server_minv2g.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_ssl.h */ -void -br_ssl_server_init_minv2g(br_ssl_server_context *cc, - const br_x509_certificate *chain, size_t chain_len, - const br_ec_private_key *sk) -{ - static const uint16_t suites[] = { - BR_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 - }; - - /* - * Reset server context and set supported versions to TLS-1.2 (only). - */ - br_ssl_server_zero(cc); - br_ssl_engine_set_versions(&cc->eng, BR_TLS12, BR_TLS12); - - /* - * Set suites. - */ - br_ssl_engine_set_suites(&cc->eng, suites, - (sizeof suites) / (sizeof suites[0])); - - /* - * Set the "server policy": handler for the certificate chain - * and private key operations. - */ - br_ssl_server_set_single_ec(cc, chain, chain_len, sk, - BR_KEYTYPE_KEYX, BR_KEYTYPE_EC, &br_ec_all_m15, 0); - - /* - * Set supported hash functions. - */ - br_ssl_engine_set_hash(&cc->eng, br_sha256_ID, &br_sha256_vtable); - - /* - * Set the PRF implementations. - */ - br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf); - - /* - * Symmetric encryption. - */ - br_ssl_engine_set_default_aes_gcm(&cc->eng); -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/sysrng.c b/src/tls/bearssl/sysrng.c deleted file mode 100644 index 8829d5a07..000000000 --- a/src/tls/bearssl/sysrng.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#define BR_ENABLE_INTRINSICS 1 -#include "inner.h" - -#if BR_USE_URANDOM -#include -#include -#include -#include -#endif - -#if BR_USE_WIN32_RAND -#include -#include -#pragma comment(lib, "advapi32") -#endif - -#if BR_RDRAND -BR_TARGETS_X86_UP -BR_TARGET("rdrnd") -static int -seeder_rdrand(const br_prng_class **ctx) -{ - unsigned char tmp[32]; - size_t u; - - for (u = 0; u < sizeof tmp; u += sizeof(uint32_t)) { - int j; - uint32_t x; - - /* - * We use the 32-bit intrinsic so that code is compatible - * with both 32-bit and 64-bit architectures. - * - * Intel recommends trying at least 10 times in case of - * failure. - */ - for (j = 0; j < 10; j ++) { - if (_rdrand32_step(&x)) { - goto next_word; - } - } - return 0; - next_word: - br_enc32le(tmp + u, x); - } - (*ctx)->update(ctx, tmp, sizeof tmp); - return 1; -} -BR_TARGETS_X86_DOWN - -static int -rdrand_supported(void) -{ - /* - * The RDRND support is bit 30 of ECX, as returned by CPUID. - */ - return br_cpuid(0, 0, 0x40000000, 0); -} - -#endif - -#if BR_USE_URANDOM -static int -seeder_urandom(const br_prng_class **ctx) -{ - int f; - - f = open("/dev/urandom", O_RDONLY); - if (f >= 0) { - unsigned char tmp[32]; - size_t u; - - for (u = 0; u < sizeof tmp;) { - ssize_t len; - - len = read(f, tmp + u, (sizeof tmp) - u); - if (len < 0) { - if (errno == EINTR) { - continue; - } - break; - } - u += (size_t)len; - } - close(f); - if (u == sizeof tmp) { - (*ctx)->update(ctx, tmp, sizeof tmp); - return 1; - } - } - return 0; -} -#endif - -#if BR_USE_WIN32_RAND -static int -seeder_win32(const br_prng_class **ctx) -{ - HCRYPTPROV hp; - - if (CryptAcquireContext(&hp, 0, 0, PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) - { - BYTE buf[32]; - BOOL r; - - r = CryptGenRandom(hp, sizeof buf, buf); - CryptReleaseContext(hp, 0); - if (r) { - (*ctx)->update(ctx, buf, sizeof buf); - return 1; - } - } - return 0; -} -#endif - -/* see bearssl_rand.h */ -br_prng_seeder -br_prng_seeder_system(const char **name) -{ -#if BR_RDRAND - if (rdrand_supported()) { - if (name != NULL) { - *name = "rdrand"; - } - return &seeder_rdrand; - } -#endif -#if BR_USE_URANDOM - if (name != NULL) { - *name = "urandom"; - } - return &seeder_urandom; -#elif BR_USE_WIN32_RAND - if (name != NULL) { - *name = "win32"; - } - return &seeder_win32; -#endif - if (name != NULL) { - *name = "none"; - } - return 0; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/x509_decoder.c b/src/tls/bearssl/x509_decoder.c deleted file mode 100644 index 615e7db0e..000000000 --- a/src/tls/bearssl/x509_decoder.c +++ /dev/null @@ -1,778 +0,0 @@ -/* Automatically generated code; do not modify directly. */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include -#include - -typedef struct { - uint32_t *dp; - uint32_t *rp; - const unsigned char *ip; -} t0_context; - -static uint32_t -t0_parse7E_unsigned(const unsigned char **p) -{ - uint32_t x; - - x = 0; - for (;;) { - unsigned y; - - y = *(*p) ++; - x = (x << 7) | (uint32_t)(y & 0x7F); - if (y < 0x80) { - return x; - } - } -} - -static int32_t -t0_parse7E_signed(const unsigned char **p) -{ - int neg; - uint32_t x; - - neg = ((**p) >> 6) & 1; - x = (uint32_t)-neg; - for (;;) { - unsigned y; - - y = *(*p) ++; - x = (x << 7) | (uint32_t)(y & 0x7F); - if (y < 0x80) { - if (neg) { - return -(int32_t)~x - 1; - } else { - return (int32_t)x; - } - } - } -} - -#define T0_VBYTE(x, n) (unsigned char)((((uint32_t)(x) >> (n)) & 0x7F) | 0x80) -#define T0_FBYTE(x, n) (unsigned char)(((uint32_t)(x) >> (n)) & 0x7F) -#define T0_SBYTE(x) (unsigned char)((((uint32_t)(x) >> 28) + 0xF8) ^ 0xF8) -#define T0_INT1(x) T0_FBYTE(x, 0) -#define T0_INT2(x) T0_VBYTE(x, 7), T0_FBYTE(x, 0) -#define T0_INT3(x) T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) -#define T0_INT4(x) T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) -#define T0_INT5(x) T0_SBYTE(x), T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) - -/* static const unsigned char t0_datablock[]; */ - - -void br_x509_decoder_init_main(void *t0ctx); - -void br_x509_decoder_run(void *t0ctx); - - - -#include "inner.h" - - - - - -#include "inner.h" - -#define CTX ((br_x509_decoder_context *)(void *)((unsigned char *)t0ctx - offsetof(br_x509_decoder_context, cpu))) -#define CONTEXT_NAME br_x509_decoder_context - -/* see bearssl_x509.h */ -void -br_x509_decoder_init(br_x509_decoder_context *ctx, - void (*append_dn)(void *ctx, const void *buf, size_t len), - void *append_dn_ctx) -{ - memset(ctx, 0, sizeof *ctx); - /* obsolete - ctx->err = 0; - ctx->hbuf = NULL; - ctx->hlen = 0; - */ - ctx->append_dn = append_dn; - ctx->append_dn_ctx = append_dn_ctx; - ctx->cpu.dp = &ctx->dp_stack[0]; - ctx->cpu.rp = &ctx->rp_stack[0]; - br_x509_decoder_init_main(&ctx->cpu); - br_x509_decoder_run(&ctx->cpu); -} - -/* see bearssl_x509.h */ -void -br_x509_decoder_push(br_x509_decoder_context *ctx, - const void *data, size_t len) -{ - ctx->hbuf = data; - ctx->hlen = len; - br_x509_decoder_run(&ctx->cpu); -} - - - -static const unsigned char t0_datablock[] = { - 0x00, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x09, - 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x05, 0x09, 0x2A, 0x86, - 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0E, 0x09, 0x2A, 0x86, 0x48, 0x86, - 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, - 0x01, 0x01, 0x0C, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, - 0x0D, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x08, 0x2A, 0x86, - 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22, - 0x05, 0x2B, 0x81, 0x04, 0x00, 0x23, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, - 0x04, 0x01, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x01, 0x08, - 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x08, 0x2A, 0x86, 0x48, - 0xCE, 0x3D, 0x04, 0x03, 0x03, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, - 0x03, 0x04, 0x00, 0x1F, 0x03, 0xFC, 0x07, 0x7F, 0x0B, 0x5E, 0x0F, 0x1F, - 0x12, 0xFE, 0x16, 0xBF, 0x1A, 0x9F, 0x1E, 0x7E, 0x22, 0x3F, 0x26, 0x1E, - 0x29, 0xDF, 0x00, 0x1F, 0x03, 0xFD, 0x07, 0x9F, 0x0B, 0x7E, 0x0F, 0x3F, - 0x13, 0x1E, 0x16, 0xDF, 0x1A, 0xBF, 0x1E, 0x9E, 0x22, 0x5F, 0x26, 0x3E, - 0x29, 0xFF, 0x03, 0x55, 0x1D, 0x13 -}; - -static const unsigned char t0_codeblock[] = { - 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00, 0x11, 0x00, 0x00, 0x01, - 0x01, 0x09, 0x00, 0x00, 0x01, 0x01, 0x0A, 0x00, 0x00, 0x1A, 0x1A, 0x00, - 0x00, 0x01, T0_INT1(BR_ERR_X509_BAD_BOOLEAN), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_BAD_TAG_CLASS), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_BAD_TAG_VALUE), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_BAD_TIME), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_EXTRA_ELEMENT), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_INDEFINITE_LENGTH), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_INNER_TRUNC), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_LIMIT_EXCEEDED), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_NOT_CONSTRUCTED), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_NOT_PRIMITIVE), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_OVERFLOW), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_PARTIAL_BYTE), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_UNEXPECTED), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_UNSUPPORTED), 0x00, 0x00, 0x01, - T0_INT1(BR_KEYTYPE_EC), 0x00, 0x00, 0x01, T0_INT1(BR_KEYTYPE_RSA), - 0x00, 0x00, 0x01, T0_INT2(offsetof(CONTEXT_NAME, copy_dn)), 0x00, 0x00, - 0x01, T0_INT2(offsetof(CONTEXT_NAME, decoded)), 0x00, 0x00, 0x01, - T0_INT2(offsetof(CONTEXT_NAME, isCA)), 0x00, 0x00, 0x01, - T0_INT2(offsetof(br_x509_decoder_context, pkey_data)), 0x01, - T0_INT2(BR_X509_BUFSIZE_KEY), 0x00, 0x00, 0x01, - T0_INT2(offsetof(CONTEXT_NAME, notafter_days)), 0x00, 0x00, 0x01, - T0_INT2(offsetof(CONTEXT_NAME, notafter_seconds)), 0x00, 0x00, 0x01, - T0_INT2(offsetof(CONTEXT_NAME, notbefore_days)), 0x00, 0x00, 0x01, - T0_INT2(offsetof(CONTEXT_NAME, notbefore_seconds)), 0x00, 0x00, 0x01, - T0_INT2(offsetof(CONTEXT_NAME, pad)), 0x00, 0x00, 0x01, - T0_INT2(offsetof(CONTEXT_NAME, signer_hash_id)), 0x00, 0x00, 0x01, - T0_INT2(offsetof(CONTEXT_NAME, signer_key_type)), 0x00, 0x00, 0x01, - 0x80, 0x45, 0x00, 0x00, 0x01, 0x80, 0x4E, 0x00, 0x00, 0x01, 0x80, 0x54, - 0x00, 0x00, 0x01, 0x81, 0x36, 0x00, 0x02, 0x03, 0x00, 0x03, 0x01, 0x1B, - 0x02, 0x01, 0x13, 0x26, 0x02, 0x00, 0x0F, 0x15, 0x00, 0x00, 0x05, 0x02, - 0x34, 0x1D, 0x00, 0x00, 0x06, 0x02, 0x35, 0x1D, 0x00, 0x00, 0x01, 0x10, - 0x4F, 0x00, 0x00, 0x11, 0x05, 0x02, 0x38, 0x1D, 0x4C, 0x00, 0x00, 0x11, - 0x05, 0x02, 0x38, 0x1D, 0x4D, 0x00, 0x00, 0x06, 0x02, 0x30, 0x1D, 0x00, - 0x00, 0x1B, 0x19, 0x01, 0x08, 0x0E, 0x26, 0x29, 0x19, 0x09, 0x00, 0x00, - 0x01, 0x30, 0x0A, 0x1B, 0x01, 0x00, 0x01, 0x09, 0x4B, 0x05, 0x02, 0x2F, - 0x1D, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x01, 0x80, 0x5A, 0x00, 0x00, - 0x01, 0x80, 0x62, 0x00, 0x00, 0x01, 0x80, 0x6B, 0x00, 0x00, 0x01, 0x80, - 0x74, 0x00, 0x00, 0x01, 0x80, 0x7D, 0x00, 0x00, 0x01, 0x3D, 0x00, 0x00, - 0x20, 0x11, 0x06, 0x04, 0x2B, 0x6B, 0x7A, 0x71, 0x00, 0x04, 0x01, 0x00, - 0x3D, 0x25, 0x01, 0x00, 0x3C, 0x25, 0x01, 0x87, 0xFF, 0xFF, 0x7F, 0x6D, - 0x6D, 0x70, 0x1B, 0x01, 0x20, 0x11, 0x06, 0x11, 0x1A, 0x4C, 0x6B, 0x70, - 0x01, 0x02, 0x50, 0x6E, 0x01, 0x02, 0x12, 0x06, 0x02, 0x39, 0x1D, 0x51, - 0x70, 0x01, 0x02, 0x50, 0x6C, 0x6D, 0x7A, 0x6D, 0x7A, 0x6D, 0x65, 0x43, - 0x24, 0x42, 0x24, 0x65, 0x41, 0x24, 0x40, 0x24, 0x51, 0x01, 0x01, 0x3C, - 0x25, 0x6D, 0x7A, 0x01, 0x00, 0x3C, 0x25, 0x6D, 0x6D, 0x60, 0x05, 0x02, - 0x39, 0x1D, 0x74, 0x1C, 0x06, 0x1C, 0x7A, 0x61, 0x6D, 0x3F, 0x68, 0x03, - 0x00, 0x3F, 0x26, 0x02, 0x00, 0x09, 0x26, 0x02, 0x00, 0x0A, 0x68, 0x03, - 0x01, 0x51, 0x51, 0x02, 0x00, 0x02, 0x01, 0x18, 0x04, 0x1E, 0x5A, 0x1C, - 0x06, 0x18, 0x64, 0x03, 0x02, 0x51, 0x61, 0x1B, 0x03, 0x03, 0x1B, 0x3F, - 0x23, 0x0D, 0x06, 0x02, 0x33, 0x1D, 0x62, 0x02, 0x02, 0x02, 0x03, 0x17, - 0x04, 0x02, 0x39, 0x1D, 0x51, 0x01, 0x00, 0x3E, 0x25, 0x71, 0x01, 0x21, - 0x5B, 0x01, 0x22, 0x5B, 0x1B, 0x01, 0x23, 0x11, 0x06, 0x28, 0x1A, 0x4C, - 0x6B, 0x6D, 0x1B, 0x06, 0x1D, 0x6D, 0x60, 0x1A, 0x70, 0x1B, 0x01, 0x01, - 0x11, 0x06, 0x03, 0x63, 0x1A, 0x70, 0x01, 0x04, 0x50, 0x6B, 0x4A, 0x1C, - 0x06, 0x03, 0x5F, 0x04, 0x01, 0x7B, 0x51, 0x51, 0x04, 0x60, 0x51, 0x51, - 0x04, 0x08, 0x01, 0x7F, 0x11, 0x05, 0x02, 0x38, 0x1D, 0x1A, 0x51, 0x6D, - 0x60, 0x06, 0x80, 0x63, 0x75, 0x1C, 0x06, 0x06, 0x01, 0x02, 0x3B, 0x04, - 0x80, 0x57, 0x76, 0x1C, 0x06, 0x06, 0x01, 0x03, 0x3B, 0x04, 0x80, 0x4D, - 0x77, 0x1C, 0x06, 0x06, 0x01, 0x04, 0x3B, 0x04, 0x80, 0x43, 0x78, 0x1C, - 0x06, 0x05, 0x01, 0x05, 0x3B, 0x04, 0x3A, 0x79, 0x1C, 0x06, 0x05, 0x01, - 0x06, 0x3B, 0x04, 0x31, 0x55, 0x1C, 0x06, 0x05, 0x01, 0x02, 0x3A, 0x04, - 0x28, 0x56, 0x1C, 0x06, 0x05, 0x01, 0x03, 0x3A, 0x04, 0x1F, 0x57, 0x1C, - 0x06, 0x05, 0x01, 0x04, 0x3A, 0x04, 0x16, 0x58, 0x1C, 0x06, 0x05, 0x01, - 0x05, 0x3A, 0x04, 0x0D, 0x59, 0x1C, 0x06, 0x05, 0x01, 0x06, 0x3A, 0x04, - 0x04, 0x01, 0x00, 0x01, 0x00, 0x04, 0x04, 0x01, 0x00, 0x01, 0x00, 0x46, - 0x25, 0x45, 0x25, 0x7A, 0x61, 0x7A, 0x51, 0x1A, 0x01, 0x01, 0x3D, 0x25, - 0x73, 0x30, 0x1D, 0x00, 0x00, 0x01, 0x81, 0x06, 0x00, 0x01, 0x54, 0x0D, - 0x06, 0x02, 0x32, 0x1D, 0x1B, 0x03, 0x00, 0x0A, 0x02, 0x00, 0x00, 0x00, - 0x6D, 0x71, 0x1B, 0x01, 0x01, 0x11, 0x06, 0x08, 0x63, 0x01, 0x01, 0x15, - 0x3E, 0x25, 0x04, 0x01, 0x2B, 0x7A, 0x00, 0x00, 0x70, 0x01, 0x06, 0x50, - 0x6F, 0x00, 0x00, 0x70, 0x01, 0x03, 0x50, 0x6B, 0x72, 0x06, 0x02, 0x37, - 0x1D, 0x00, 0x00, 0x26, 0x1B, 0x06, 0x07, 0x21, 0x1B, 0x06, 0x01, 0x16, - 0x04, 0x76, 0x2B, 0x00, 0x00, 0x01, 0x01, 0x50, 0x6A, 0x01, 0x01, 0x10, - 0x06, 0x02, 0x2C, 0x1D, 0x72, 0x27, 0x00, 0x00, 0x60, 0x05, 0x02, 0x39, - 0x1D, 0x47, 0x1C, 0x06, 0x04, 0x01, 0x17, 0x04, 0x12, 0x48, 0x1C, 0x06, - 0x04, 0x01, 0x18, 0x04, 0x0A, 0x49, 0x1C, 0x06, 0x04, 0x01, 0x19, 0x04, - 0x02, 0x39, 0x1D, 0x00, 0x04, 0x70, 0x1B, 0x01, 0x17, 0x01, 0x18, 0x4B, - 0x05, 0x02, 0x2F, 0x1D, 0x01, 0x18, 0x11, 0x03, 0x00, 0x4D, 0x6B, 0x66, - 0x02, 0x00, 0x06, 0x0C, 0x01, 0x80, 0x64, 0x08, 0x03, 0x01, 0x66, 0x02, - 0x01, 0x09, 0x04, 0x0E, 0x1B, 0x01, 0x32, 0x0D, 0x06, 0x04, 0x01, 0x80, - 0x64, 0x09, 0x01, 0x8E, 0x6C, 0x09, 0x03, 0x01, 0x02, 0x01, 0x01, 0x82, - 0x6D, 0x08, 0x02, 0x01, 0x01, 0x03, 0x09, 0x01, 0x04, 0x0C, 0x09, 0x02, - 0x01, 0x01, 0x80, 0x63, 0x09, 0x01, 0x80, 0x64, 0x0C, 0x0A, 0x02, 0x01, - 0x01, 0x83, 0x0F, 0x09, 0x01, 0x83, 0x10, 0x0C, 0x09, 0x03, 0x03, 0x01, - 0x01, 0x01, 0x0C, 0x67, 0x2A, 0x01, 0x01, 0x0E, 0x02, 0x01, 0x01, 0x04, - 0x07, 0x28, 0x02, 0x01, 0x01, 0x80, 0x64, 0x07, 0x27, 0x02, 0x01, 0x01, - 0x83, 0x10, 0x07, 0x28, 0x1F, 0x15, 0x06, 0x03, 0x01, 0x18, 0x09, 0x5D, - 0x09, 0x52, 0x1B, 0x01, 0x05, 0x14, 0x02, 0x03, 0x09, 0x03, 0x03, 0x01, - 0x1F, 0x15, 0x01, 0x01, 0x26, 0x67, 0x02, 0x03, 0x09, 0x2A, 0x03, 0x03, - 0x01, 0x00, 0x01, 0x17, 0x67, 0x01, 0x9C, 0x10, 0x08, 0x03, 0x02, 0x01, - 0x00, 0x01, 0x3B, 0x67, 0x01, 0x3C, 0x08, 0x02, 0x02, 0x09, 0x03, 0x02, - 0x01, 0x00, 0x01, 0x3C, 0x67, 0x02, 0x02, 0x09, 0x03, 0x02, 0x72, 0x1B, - 0x01, 0x2E, 0x11, 0x06, 0x0D, 0x1A, 0x72, 0x1B, 0x01, 0x30, 0x01, 0x39, - 0x4B, 0x06, 0x03, 0x1A, 0x04, 0x74, 0x01, 0x80, 0x5A, 0x10, 0x06, 0x02, - 0x2F, 0x1D, 0x51, 0x02, 0x03, 0x02, 0x02, 0x00, 0x01, 0x72, 0x53, 0x01, - 0x0A, 0x08, 0x03, 0x00, 0x72, 0x53, 0x02, 0x00, 0x09, 0x00, 0x02, 0x03, - 0x00, 0x03, 0x01, 0x66, 0x1B, 0x02, 0x01, 0x02, 0x00, 0x4B, 0x05, 0x02, - 0x2F, 0x1D, 0x00, 0x00, 0x23, 0x70, 0x01, 0x02, 0x50, 0x0B, 0x69, 0x00, - 0x03, 0x1B, 0x03, 0x00, 0x03, 0x01, 0x03, 0x02, 0x6B, 0x72, 0x1B, 0x01, - 0x81, 0x00, 0x13, 0x06, 0x02, 0x36, 0x1D, 0x1B, 0x01, 0x00, 0x11, 0x06, - 0x0B, 0x1A, 0x1B, 0x05, 0x04, 0x1A, 0x01, 0x00, 0x00, 0x72, 0x04, 0x6F, - 0x02, 0x01, 0x1B, 0x05, 0x02, 0x33, 0x1D, 0x2A, 0x03, 0x01, 0x02, 0x02, - 0x25, 0x02, 0x02, 0x29, 0x03, 0x02, 0x1B, 0x06, 0x03, 0x72, 0x04, 0x68, - 0x1A, 0x02, 0x00, 0x02, 0x01, 0x0A, 0x00, 0x01, 0x72, 0x1B, 0x01, 0x81, - 0x00, 0x0D, 0x06, 0x01, 0x00, 0x01, 0x81, 0x00, 0x0A, 0x1B, 0x05, 0x02, - 0x31, 0x1D, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x12, 0x06, - 0x19, 0x02, 0x00, 0x2A, 0x03, 0x00, 0x1B, 0x01, 0x83, 0xFF, 0xFF, 0x7F, - 0x12, 0x06, 0x02, 0x32, 0x1D, 0x01, 0x08, 0x0E, 0x26, 0x72, 0x23, 0x09, - 0x04, 0x60, 0x00, 0x00, 0x6A, 0x5E, 0x00, 0x00, 0x6B, 0x7A, 0x00, 0x00, - 0x70, 0x4E, 0x6B, 0x00, 0x01, 0x6B, 0x1B, 0x05, 0x02, 0x36, 0x1D, 0x72, - 0x1B, 0x01, 0x81, 0x00, 0x13, 0x06, 0x02, 0x36, 0x1D, 0x03, 0x00, 0x1B, - 0x06, 0x16, 0x72, 0x02, 0x00, 0x1B, 0x01, 0x87, 0xFF, 0xFF, 0x7F, 0x13, - 0x06, 0x02, 0x36, 0x1D, 0x01, 0x08, 0x0E, 0x09, 0x03, 0x00, 0x04, 0x67, - 0x1A, 0x02, 0x00, 0x00, 0x00, 0x6B, 0x1B, 0x01, 0x81, 0x7F, 0x12, 0x06, - 0x08, 0x7A, 0x01, 0x00, 0x44, 0x25, 0x01, 0x00, 0x00, 0x1B, 0x44, 0x25, - 0x44, 0x29, 0x62, 0x01, 0x7F, 0x00, 0x01, 0x72, 0x03, 0x00, 0x02, 0x00, - 0x01, 0x05, 0x14, 0x01, 0x01, 0x15, 0x1E, 0x02, 0x00, 0x01, 0x06, 0x14, - 0x1B, 0x01, 0x01, 0x15, 0x06, 0x02, 0x2D, 0x1D, 0x01, 0x04, 0x0E, 0x02, - 0x00, 0x01, 0x1F, 0x15, 0x1B, 0x01, 0x1F, 0x11, 0x06, 0x02, 0x2E, 0x1D, - 0x09, 0x00, 0x00, 0x1B, 0x05, 0x05, 0x01, 0x00, 0x01, 0x7F, 0x00, 0x70, - 0x00, 0x00, 0x1B, 0x05, 0x02, 0x32, 0x1D, 0x2A, 0x73, 0x00, 0x00, 0x22, - 0x1B, 0x01, 0x00, 0x13, 0x06, 0x01, 0x00, 0x1A, 0x16, 0x04, 0x74, 0x00, - 0x01, 0x01, 0x00, 0x00, 0x01, 0x0B, 0x00, 0x00, 0x01, 0x15, 0x00, 0x00, - 0x01, 0x1F, 0x00, 0x00, 0x01, 0x29, 0x00, 0x00, 0x01, 0x33, 0x00, 0x00, - 0x7B, 0x1A, 0x00, 0x00, 0x1B, 0x06, 0x07, 0x7C, 0x1B, 0x06, 0x01, 0x16, - 0x04, 0x76, 0x00, 0x00, 0x01, 0x00, 0x20, 0x21, 0x0B, 0x2B, 0x00 -}; - -static const uint16_t t0_caddr[] = { - 0, - 5, - 10, - 15, - 20, - 24, - 28, - 32, - 36, - 40, - 44, - 48, - 52, - 56, - 60, - 64, - 68, - 72, - 76, - 80, - 84, - 88, - 93, - 98, - 103, - 111, - 116, - 121, - 126, - 131, - 136, - 141, - 146, - 151, - 156, - 161, - 166, - 181, - 187, - 193, - 198, - 206, - 214, - 220, - 231, - 246, - 250, - 255, - 260, - 265, - 270, - 275, - 279, - 289, - 620, - 625, - 639, - 659, - 666, - 678, - 692, - 707, - 740, - 960, - 974, - 991, - 1000, - 1067, - 1123, - 1127, - 1131, - 1136, - 1184, - 1210, - 1254, - 1265, - 1274, - 1287, - 1291, - 1295, - 1299, - 1303, - 1307, - 1311, - 1315, - 1327 -}; - -#define T0_INTERPRETED 39 - -#define T0_ENTER(ip, rp, slot) do { \ - const unsigned char *t0_newip; \ - uint32_t t0_lnum; \ - t0_newip = &t0_codeblock[t0_caddr[(slot) - T0_INTERPRETED]]; \ - t0_lnum = t0_parse7E_unsigned(&t0_newip); \ - (rp) += t0_lnum; \ - *((rp) ++) = (uint32_t)((ip) - &t0_codeblock[0]) + (t0_lnum << 16); \ - (ip) = t0_newip; \ - } while (0) - -#define T0_DEFENTRY(name, slot) \ -void \ -name(void *ctx) \ -{ \ - t0_context *t0ctx = ctx; \ - t0ctx->ip = &t0_codeblock[0]; \ - T0_ENTER(t0ctx->ip, t0ctx->rp, slot); \ -} - -T0_DEFENTRY(br_x509_decoder_init_main, 92) - -#define T0_NEXT(t0ipp) (*(*(t0ipp)) ++) - -void -br_x509_decoder_run(void *t0ctx) -{ - uint32_t *dp, *rp; - const unsigned char *ip; - -#define T0_LOCAL(x) (*(rp - 2 - (x))) -#define T0_POP() (*-- dp) -#define T0_POPi() (*(int32_t *)(-- dp)) -#define T0_PEEK(x) (*(dp - 1 - (x))) -#define T0_PEEKi(x) (*(int32_t *)(dp - 1 - (x))) -#define T0_PUSH(v) do { *dp = (v); dp ++; } while (0) -#define T0_PUSHi(v) do { *(int32_t *)dp = (v); dp ++; } while (0) -#define T0_RPOP() (*-- rp) -#define T0_RPOPi() (*(int32_t *)(-- rp)) -#define T0_RPUSH(v) do { *rp = (v); rp ++; } while (0) -#define T0_RPUSHi(v) do { *(int32_t *)rp = (v); rp ++; } while (0) -#define T0_ROLL(x) do { \ - size_t t0len = (size_t)(x); \ - uint32_t t0tmp = *(dp - 1 - t0len); \ - memmove(dp - t0len - 1, dp - t0len, t0len * sizeof *dp); \ - *(dp - 1) = t0tmp; \ -} while (0) -#define T0_SWAP() do { \ - uint32_t t0tmp = *(dp - 2); \ - *(dp - 2) = *(dp - 1); \ - *(dp - 1) = t0tmp; \ -} while (0) -#define T0_ROT() do { \ - uint32_t t0tmp = *(dp - 3); \ - *(dp - 3) = *(dp - 2); \ - *(dp - 2) = *(dp - 1); \ - *(dp - 1) = t0tmp; \ -} while (0) -#define T0_NROT() do { \ - uint32_t t0tmp = *(dp - 1); \ - *(dp - 1) = *(dp - 2); \ - *(dp - 2) = *(dp - 3); \ - *(dp - 3) = t0tmp; \ -} while (0) -#define T0_PICK(x) do { \ - uint32_t t0depth = (x); \ - T0_PUSH(T0_PEEK(t0depth)); \ -} while (0) -#define T0_CO() do { \ - goto t0_exit; \ -} while (0) -#define T0_RET() goto t0_next - - dp = ((t0_context *)t0ctx)->dp; - rp = ((t0_context *)t0ctx)->rp; - ip = ((t0_context *)t0ctx)->ip; - goto t0_next; - for (;;) { - uint32_t t0x; - - t0_next: - t0x = T0_NEXT(&ip); - if (t0x < T0_INTERPRETED) { - switch (t0x) { - int32_t t0off; - - case 0: /* ret */ - t0x = T0_RPOP(); - rp -= (t0x >> 16); - t0x &= 0xFFFF; - if (t0x == 0) { - ip = NULL; - goto t0_exit; - } - ip = &t0_codeblock[t0x]; - break; - case 1: /* literal constant */ - T0_PUSHi(t0_parse7E_signed(&ip)); - break; - case 2: /* read local */ - T0_PUSH(T0_LOCAL(t0_parse7E_unsigned(&ip))); - break; - case 3: /* write local */ - T0_LOCAL(t0_parse7E_unsigned(&ip)) = T0_POP(); - break; - case 4: /* jump */ - t0off = t0_parse7E_signed(&ip); - ip += t0off; - break; - case 5: /* jump if */ - t0off = t0_parse7E_signed(&ip); - if (T0_POP()) { - ip += t0off; - } - break; - case 6: /* jump if not */ - t0off = t0_parse7E_signed(&ip); - if (!T0_POP()) { - ip += t0off; - } - break; - case 7: { - /* %25 */ - - int32_t b = T0_POPi(); - int32_t a = T0_POPi(); - T0_PUSHi(a % b); - - } - break; - case 8: { - /* * */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(a * b); - - } - break; - case 9: { - /* + */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(a + b); - - } - break; - case 10: { - /* - */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(a - b); - - } - break; - case 11: { - /* -rot */ - T0_NROT(); - } - break; - case 12: { - /* / */ - - int32_t b = T0_POPi(); - int32_t a = T0_POPi(); - T0_PUSHi(a / b); - - } - break; - case 13: { - /* < */ - - int32_t b = T0_POPi(); - int32_t a = T0_POPi(); - T0_PUSH(-(uint32_t)(a < b)); - - } - break; - case 14: { - /* << */ - - int c = (int)T0_POPi(); - uint32_t x = T0_POP(); - T0_PUSH(x << c); - - } - break; - case 15: { - /* <= */ - - int32_t b = T0_POPi(); - int32_t a = T0_POPi(); - T0_PUSH(-(uint32_t)(a <= b)); - - } - break; - case 16: { - /* <> */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(-(uint32_t)(a != b)); - - } - break; - case 17: { - /* = */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(-(uint32_t)(a == b)); - - } - break; - case 18: { - /* > */ - - int32_t b = T0_POPi(); - int32_t a = T0_POPi(); - T0_PUSH(-(uint32_t)(a > b)); - - } - break; - case 19: { - /* >= */ - - int32_t b = T0_POPi(); - int32_t a = T0_POPi(); - T0_PUSH(-(uint32_t)(a >= b)); - - } - break; - case 20: { - /* >> */ - - int c = (int)T0_POPi(); - int32_t x = T0_POPi(); - T0_PUSHi(x >> c); - - } - break; - case 21: { - /* and */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(a & b); - - } - break; - case 22: { - /* co */ - T0_CO(); - } - break; - case 23: { - /* copy-ec-pkey */ - - size_t qlen = T0_POP(); - uint32_t curve = T0_POP(); - CTX->pkey.key_type = BR_KEYTYPE_EC; - CTX->pkey.key.ec.curve = curve; - CTX->pkey.key.ec.q = CTX->pkey_data; - CTX->pkey.key.ec.qlen = qlen; - - } - break; - case 24: { - /* copy-rsa-pkey */ - - size_t elen = T0_POP(); - size_t nlen = T0_POP(); - CTX->pkey.key_type = BR_KEYTYPE_RSA; - CTX->pkey.key.rsa.n = CTX->pkey_data; - CTX->pkey.key.rsa.nlen = nlen; - CTX->pkey.key.rsa.e = CTX->pkey_data + nlen; - CTX->pkey.key.rsa.elen = elen; - - } - break; - case 25: { - /* data-get8 */ - - size_t addr = T0_POP(); - T0_PUSH(t0_datablock[addr]); - - } - break; - case 26: { - /* drop */ - (void)T0_POP(); - } - break; - case 27: { - /* dup */ - T0_PUSH(T0_PEEK(0)); - } - break; - case 28: { - /* eqOID */ - - const unsigned char *a2 = &t0_datablock[T0_POP()]; - const unsigned char *a1 = &CTX->pad[0]; - size_t len = a1[0]; - int x; - if (len == a2[0]) { - x = -(memcmp(a1 + 1, a2 + 1, len) == 0); - } else { - x = 0; - } - T0_PUSH((uint32_t)x); - - } - break; - case 29: { - /* fail */ - - CTX->err = T0_POPi(); - T0_CO(); - - } - break; - case 30: { - /* neg */ - - uint32_t a = T0_POP(); - T0_PUSH(-a); - - } - break; - case 31: { - /* or */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(a | b); - - } - break; - case 32: { - /* over */ - T0_PUSH(T0_PEEK(1)); - } - break; - case 33: { - /* read-blob-inner */ - - uint32_t len = T0_POP(); - uint32_t addr = T0_POP(); - size_t clen = CTX->hlen; - if (clen > len) { - clen = (size_t)len; - } - if (addr != 0) { - memcpy((unsigned char *)CTX + addr, CTX->hbuf, clen); - } - if (CTX->copy_dn && CTX->append_dn) { - CTX->append_dn(CTX->append_dn_ctx, CTX->hbuf, clen); - } - CTX->hbuf += clen; - CTX->hlen -= clen; - T0_PUSH(addr + clen); - T0_PUSH(len - clen); - - } - break; - case 34: { - /* read8-low */ - - if (CTX->hlen == 0) { - T0_PUSHi(-1); - } else { - unsigned char x = *CTX->hbuf ++; - if (CTX->copy_dn && CTX->append_dn) { - CTX->append_dn(CTX->append_dn_ctx, &x, 1); - } - CTX->hlen --; - T0_PUSH(x); - } - - } - break; - case 35: { - /* rot */ - T0_ROT(); - } - break; - case 36: { - /* set32 */ - - uint32_t addr = T0_POP(); - *(uint32_t *)(void *)((unsigned char *)CTX + addr) = T0_POP(); - - } - break; - case 37: { - /* set8 */ - - uint32_t addr = T0_POP(); - *((unsigned char *)CTX + addr) = (unsigned char)T0_POP(); - - } - break; - case 38: { - /* swap */ - T0_SWAP(); - } - break; - } - - } else { - T0_ENTER(ip, rp, t0x); - } - } -t0_exit: - ((t0_context *)t0ctx)->dp = dp; - ((t0_context *)t0ctx)->rp = rp; - ((t0_context *)t0ctx)->ip = ip; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/x509_knownkey.c b/src/tls/bearssl/x509_knownkey.c deleted file mode 100644 index 0587f8a5c..000000000 --- a/src/tls/bearssl/x509_knownkey.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_x509.h */ -void -br_x509_knownkey_init_rsa(br_x509_knownkey_context *ctx, - const br_rsa_public_key *pk, unsigned usages) -{ - ctx->vtable = &br_x509_knownkey_vtable; - ctx->pkey.key_type = BR_KEYTYPE_RSA; - ctx->pkey.key.rsa = *pk; - ctx->usages = usages; -} - -/* see bearssl_x509.h */ -void -br_x509_knownkey_init_ec(br_x509_knownkey_context *ctx, - const br_ec_public_key *pk, unsigned usages) -{ - ctx->vtable = &br_x509_knownkey_vtable; - ctx->pkey.key_type = BR_KEYTYPE_EC; - ctx->pkey.key.ec = *pk; - ctx->usages = usages; -} - -static void -kk_start_chain(const br_x509_class **ctx, const char *server_name) -{ - (void)ctx; - (void)server_name; -} - -static void -kk_start_cert(const br_x509_class **ctx, uint32_t length) -{ - (void)ctx; - (void)length; -} - -static void -kk_append(const br_x509_class **ctx, const unsigned char *buf, size_t len) -{ - (void)ctx; - (void)buf; - (void)len; -} - -static void -kk_end_cert(const br_x509_class **ctx) -{ - (void)ctx; -} - -static unsigned -kk_end_chain(const br_x509_class **ctx) -{ - (void)ctx; - return 0; -} - -static const br_x509_pkey * -kk_get_pkey(const br_x509_class *const *ctx, unsigned *usages) -{ - const br_x509_knownkey_context *xc; - - xc = (const br_x509_knownkey_context *)ctx; - if (usages != NULL) { - *usages = xc->usages; - } - return &xc->pkey; -} - -/* see bearssl_x509.h */ -const br_x509_class br_x509_knownkey_vtable = { - sizeof(br_x509_knownkey_context), - kk_start_chain, - kk_start_cert, - kk_append, - kk_end_cert, - kk_end_chain, - kk_get_pkey -}; - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/x509_minimal.c b/src/tls/bearssl/x509_minimal.c deleted file mode 100644 index 7fb35e728..000000000 --- a/src/tls/bearssl/x509_minimal.c +++ /dev/null @@ -1,1718 +0,0 @@ -/* Automatically generated code; do not modify directly. */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include -#include - -typedef struct { - uint32_t *dp; - uint32_t *rp; - const unsigned char *ip; -} t0_context; - -static uint32_t -t0_parse7E_unsigned(const unsigned char **p) -{ - uint32_t x; - - x = 0; - for (;;) { - unsigned y; - - y = *(*p) ++; - x = (x << 7) | (uint32_t)(y & 0x7F); - if (y < 0x80) { - return x; - } - } -} - -static int32_t -t0_parse7E_signed(const unsigned char **p) -{ - int neg; - uint32_t x; - - neg = ((**p) >> 6) & 1; - x = (uint32_t)-neg; - for (;;) { - unsigned y; - - y = *(*p) ++; - x = (x << 7) | (uint32_t)(y & 0x7F); - if (y < 0x80) { - if (neg) { - return -(int32_t)~x - 1; - } else { - return (int32_t)x; - } - } - } -} - -#define T0_VBYTE(x, n) (unsigned char)((((uint32_t)(x) >> (n)) & 0x7F) | 0x80) -#define T0_FBYTE(x, n) (unsigned char)(((uint32_t)(x) >> (n)) & 0x7F) -#define T0_SBYTE(x) (unsigned char)((((uint32_t)(x) >> 28) + 0xF8) ^ 0xF8) -#define T0_INT1(x) T0_FBYTE(x, 0) -#define T0_INT2(x) T0_VBYTE(x, 7), T0_FBYTE(x, 0) -#define T0_INT3(x) T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) -#define T0_INT4(x) T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) -#define T0_INT5(x) T0_SBYTE(x), T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) - -/* static const unsigned char t0_datablock[]; */ - - -void br_x509_minimal_init_main(void *t0ctx); - -void br_x509_minimal_run(void *t0ctx); - - - -#include "inner.h" - - - - - -#include "inner.h" - -/* - * Implementation Notes - * -------------------- - * - * The C code pushes the data by chunks; all decoding is done in the - * T0 code. The cert_length value is set to the certificate length when - * a new certificate is started; the T0 code picks it up as outer limit, - * and decoding functions use it to ensure that no attempt is made at - * reading past it. The T0 code also checks that once the certificate is - * decoded, there are no trailing bytes. - * - * The T0 code sets cert_length to 0 when the certificate is fully - * decoded. - * - * The C code must still perform two checks: - * - * -- If the certificate length is 0, then the T0 code will not be - * invoked at all. This invalid condition must thus be reported by the - * C code. - * - * -- When reaching the end of certificate, the C code must verify that - * the certificate length has been set to 0, thereby signaling that - * the T0 code properly decoded a certificate. - * - * Processing of a chain works in the following way: - * - * -- The error flag is set to a non-zero value when validation is - * finished. The value is either BR_ERR_X509_OK (validation is - * successful) or another non-zero error code. When a non-zero error - * code is obtained, the remaining bytes in the current certificate and - * the subsequent certificates (if any) are completely ignored. - * - * -- Each certificate is decoded in due course, with the following - * "interesting points": - * - * -- Start of the TBS: the multihash engine is reset and activated. - * - * -- Start of the issuer DN: the secondary hash engine is started, - * to process the encoded issuer DN. - * - * -- End of the issuer DN: the secondary hash engine is stopped. The - * resulting hash value is computed and then copied into the - * next_dn_hash[] buffer. - * - * -- Start of the subject DN: the secondary hash engine is started, - * to process the encoded subject DN. - * - * -- For the EE certificate only: the Common Name, if any, is matched - * against the expected server name. - * - * -- End of the subject DN: the secondary hash engine is stopped. The - * resulting hash value is computed into the pad. It is then processed: - * - * -- If this is the EE certificate, then the hash is ignored - * (except for direct trust processing, see later; the hash is - * simply left in current_dn_hash[]). - * - * -- Otherwise, the hashed subject DN is compared with the saved - * hash value (in saved_dn_hash[]). They must match. - * - * Either way, the next_dn_hash[] value is then copied into the - * saved_dn_hash[] value. Thus, at that point, saved_dn_hash[] - * contains the hash of the issuer DN for the current certificate, - * and current_dn_hash[] contains the hash of the subject DN for the - * current certificate. - * - * -- Public key: it is decoded into the cert_pkey[] buffer. Unknown - * key types are reported at that point. - * - * -- If this is the EE certificate, then the key type is compared - * with the expected key type (initialization parameter). The public - * key data is copied to ee_pkey_data[]. The key and hashed subject - * DN are also compared with the "direct trust" keys; if the key - * and DN are matched, then validation ends with a success. - * - * -- Otherwise, the saved signature (cert_sig[]) is verified - * against the saved TBS hash (tbs_hash[]) and that freshly - * decoded public key. Failure here ends validation with an error. - * - * -- Extensions: extension values are processed in due order. - * - * -- Basic Constraints: for all certificates except EE, must be - * present, indicate a CA, and have a path length compatible with - * the chain length so far. - * - * -- Key Usage: for the EE, if present, must allow signatures - * or encryption/key exchange, as required for the cipher suite. - * For non-EE, if present, must have the "certificate sign" bit. - * - * -- Subject Alt Name: for the EE, dNSName names are matched - * against the server name. Ignored for non-EE. - * - * -- Authority Key Identifier, Subject Key Identifier, Issuer - * Alt Name, Subject Directory Attributes, CRL Distribution Points - * Freshest CRL, Authority Info Access and Subject Info Access - * extensions are always ignored: they either contain only - * informative data, or they relate to revocation processing, which - * we explicitly do not support. - * - * -- All other extensions are ignored if non-critical. If a - * critical extension other than the ones above is encountered, - * then a failure is reported. - * - * -- End of the TBS: the multihash engine is stopped. - * - * -- Signature algorithm: the signature algorithm on the - * certificate is decoded. A failure is reported if that algorithm - * is unknown. The hashed TBS corresponding to the signature hash - * function is computed and stored in tbs_hash[] (if not supported, - * then a failure is reported). The hash OID and length are stored - * in cert_sig_hash_oid and cert_sig_hash_len. - * - * -- Signature value: the signature value is copied into the - * cert_sig[] array. - * - * -- Certificate end: the hashed issuer DN (saved_dn_hash[]) is - * looked up in the trust store (CA trust anchors only); for all - * that match, the signature (cert_sig[]) is verified against the - * anchor public key (hashed TBS is in tbs_hash[]). If one of these - * signatures is valid, then validation ends with a success. - * - * -- If the chain end is reached without obtaining a validation success, - * then validation is reported as failed. - */ - -#if BR_USE_UNIX_TIME -#include -#endif - -#if BR_USE_WIN32_TIME -#include -#endif - -/* - * The T0 compiler will produce these prototypes declarations in the - * header. - * -void br_x509_minimal_init_main(void *ctx); -void br_x509_minimal_run(void *ctx); - */ - -/* see bearssl_x509.h */ -void -br_x509_minimal_init(br_x509_minimal_context *ctx, - const br_hash_class *dn_hash_impl, - const br_x509_trust_anchor *trust_anchors, size_t trust_anchors_num) -{ - memset(ctx, 0, sizeof *ctx); - ctx->vtable = &br_x509_minimal_vtable; - ctx->dn_hash_impl = dn_hash_impl; - ctx->trust_anchors = trust_anchors; - ctx->trust_anchors_num = trust_anchors_num; -} - -static void -xm_start_chain(const br_x509_class **ctx, const char *server_name) -{ - br_x509_minimal_context *cc; - size_t u; - - cc = (br_x509_minimal_context *)(void *)ctx; - for (u = 0; u < cc->num_name_elts; u ++) { - cc->name_elts[u].status = 0; - cc->name_elts[u].buf[0] = 0; - } - memset(&cc->pkey, 0, sizeof cc->pkey); - cc->num_certs = 0; - cc->err = 0; - cc->cpu.dp = cc->dp_stack; - cc->cpu.rp = cc->rp_stack; - br_x509_minimal_init_main(&cc->cpu); - if (server_name == NULL || *server_name == 0) { - cc->server_name = NULL; - } else { - cc->server_name = server_name; - } -} - -static void -xm_start_cert(const br_x509_class **ctx, uint32_t length) -{ - br_x509_minimal_context *cc; - - cc = (br_x509_minimal_context *)(void *)ctx; - if (cc->err != 0) { - return; - } - if (length == 0) { - cc->err = BR_ERR_X509_TRUNCATED; - return; - } - cc->cert_length = length; -} - -static void -xm_append(const br_x509_class **ctx, const unsigned char *buf, size_t len) -{ - br_x509_minimal_context *cc; - - cc = (br_x509_minimal_context *)(void *)ctx; - if (cc->err != 0) { - return; - } - cc->hbuf = buf; - cc->hlen = len; - br_x509_minimal_run(&cc->cpu); -} - -static void -xm_end_cert(const br_x509_class **ctx) -{ - br_x509_minimal_context *cc; - - cc = (br_x509_minimal_context *)(void *)ctx; - if (cc->err == 0 && cc->cert_length != 0) { - cc->err = BR_ERR_X509_TRUNCATED; - } - cc->num_certs ++; -} - -static unsigned -xm_end_chain(const br_x509_class **ctx) -{ - br_x509_minimal_context *cc; - - cc = (br_x509_minimal_context *)(void *)ctx; - if (cc->err == 0) { - if (cc->num_certs == 0) { - cc->err = BR_ERR_X509_EMPTY_CHAIN; - } else { - cc->err = BR_ERR_X509_NOT_TRUSTED; - } - } else if (cc->err == BR_ERR_X509_OK) { - return 0; - } - return (unsigned)cc->err; -} - -static const br_x509_pkey * -xm_get_pkey(const br_x509_class *const *ctx, unsigned *usages) -{ - br_x509_minimal_context *cc; - - cc = (br_x509_minimal_context *)(void *)ctx; - if (cc->err == BR_ERR_X509_OK - || cc->err == BR_ERR_X509_NOT_TRUSTED) - { - if (usages != NULL) { - *usages = cc->key_usages; - } - return &((br_x509_minimal_context *)(void *)ctx)->pkey; - } else { - return NULL; - } -} - -/* see bearssl_x509.h */ -const br_x509_class br_x509_minimal_vtable = { - sizeof(br_x509_minimal_context), - xm_start_chain, - xm_start_cert, - xm_append, - xm_end_cert, - xm_end_chain, - xm_get_pkey -}; - -#define CTX ((br_x509_minimal_context *)(void *)((unsigned char *)t0ctx - offsetof(br_x509_minimal_context, cpu))) -#define CONTEXT_NAME br_x509_minimal_context - -#define DNHASH_LEN ((CTX->dn_hash_impl->desc >> BR_HASHDESC_OUT_OFF) & BR_HASHDESC_OUT_MASK) - -/* - * Hash a DN (from a trust anchor) into the provided buffer. This uses the - * DN hash implementation and context structure from the X.509 engine - * context. - */ -static void -hash_dn(br_x509_minimal_context *ctx, const void *dn, size_t len, - unsigned char *out) -{ - ctx->dn_hash_impl->init(&ctx->dn_hash.vtable); - ctx->dn_hash_impl->update(&ctx->dn_hash.vtable, dn, len); - ctx->dn_hash_impl->out(&ctx->dn_hash.vtable, out); -} - -/* - * Compare two big integers for equality. The integers use unsigned big-endian - * encoding; extra leading bytes (of value 0) are allowed. - */ -static int -eqbigint(const unsigned char *b1, size_t len1, - const unsigned char *b2, size_t len2) -{ - while (len1 > 0 && *b1 == 0) { - b1 ++; - len1 --; - } - while (len2 > 0 && *b2 == 0) { - b2 ++; - len2 --; - } - if (len1 != len2) { - return 0; - } - return memcmp(b1, b2, len1) == 0; -} - -/* - * Compare two strings for equality, in a case-insensitive way. This - * function handles casing only for ASCII letters. - */ -static int -eqnocase(const void *s1, const void *s2, size_t len) -{ - const unsigned char *buf1, *buf2; - - buf1 = s1; - buf2 = s2; - while (len -- > 0) { - int x1, x2; - - x1 = *buf1 ++; - x2 = *buf2 ++; - if (x1 >= 'A' && x1 <= 'Z') { - x1 += 'a' - 'A'; - } - if (x2 >= 'A' && x2 <= 'Z') { - x2 += 'a' - 'A'; - } - if (x1 != x2) { - return 0; - } - } - return 1; -} - -static int verify_signature(br_x509_minimal_context *ctx, - const br_x509_pkey *pk); - - - -static const unsigned char t0_datablock[] = { - 0x00, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x09, - 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x05, 0x09, 0x2A, 0x86, - 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0E, 0x09, 0x2A, 0x86, 0x48, 0x86, - 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, - 0x01, 0x01, 0x0C, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, - 0x0D, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x09, 0x60, 0x86, 0x48, 0x01, - 0x65, 0x03, 0x04, 0x02, 0x04, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, - 0x04, 0x02, 0x01, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, - 0x02, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x07, - 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x08, 0x2A, 0x86, 0x48, 0xCE, - 0x3D, 0x03, 0x01, 0x07, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22, 0x05, 0x2B, - 0x81, 0x04, 0x00, 0x23, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x01, - 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x01, 0x08, 0x2A, 0x86, - 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, - 0x04, 0x03, 0x03, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x04, - 0x03, 0x55, 0x04, 0x03, 0x00, 0x1F, 0x03, 0xFC, 0x07, 0x7F, 0x0B, 0x5E, - 0x0F, 0x1F, 0x12, 0xFE, 0x16, 0xBF, 0x1A, 0x9F, 0x1E, 0x7E, 0x22, 0x3F, - 0x26, 0x1E, 0x29, 0xDF, 0x00, 0x1F, 0x03, 0xFD, 0x07, 0x9F, 0x0B, 0x7E, - 0x0F, 0x3F, 0x13, 0x1E, 0x16, 0xDF, 0x1A, 0xBF, 0x1E, 0x9E, 0x22, 0x5F, - 0x26, 0x3E, 0x29, 0xFF, 0x03, 0x55, 0x1D, 0x13, 0x03, 0x55, 0x1D, 0x0F, - 0x03, 0x55, 0x1D, 0x11, 0x03, 0x55, 0x1D, 0x20, 0x08, 0x2B, 0x06, 0x01, - 0x05, 0x05, 0x07, 0x02, 0x01, 0x03, 0x55, 0x1D, 0x23, 0x03, 0x55, 0x1D, - 0x0E, 0x03, 0x55, 0x1D, 0x12, 0x03, 0x55, 0x1D, 0x09, 0x03, 0x55, 0x1D, - 0x1F, 0x03, 0x55, 0x1D, 0x2E, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, - 0x01, 0x01, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x0B -}; - -static const unsigned char t0_codeblock[] = { - 0x00, 0x01, 0x00, 0x0D, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x01, - 0x00, 0x11, 0x00, 0x00, 0x01, 0x01, 0x09, 0x00, 0x00, 0x01, 0x01, 0x0A, - 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_BAD_BOOLEAN), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_BAD_DN), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_BAD_SERVER_NAME), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_BAD_TAG_CLASS), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_BAD_TAG_VALUE), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_BAD_TIME), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_CRITICAL_EXTENSION), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_DN_MISMATCH), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_EXPIRED), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_EXTRA_ELEMENT), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_FORBIDDEN_KEY_USAGE), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_INDEFINITE_LENGTH), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_INNER_TRUNC), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_LIMIT_EXCEEDED), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_NOT_CA), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_NOT_CONSTRUCTED), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_NOT_PRIMITIVE), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_OVERFLOW), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_PARTIAL_BYTE), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_UNEXPECTED), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_UNSUPPORTED), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_WEAK_PUBLIC_KEY), 0x00, 0x00, 0x01, - T0_INT1(BR_KEYTYPE_EC), 0x00, 0x00, 0x01, T0_INT1(BR_KEYTYPE_RSA), - 0x00, 0x00, 0x01, T0_INT2(offsetof(CONTEXT_NAME, cert_length)), 0x00, - 0x00, 0x01, T0_INT2(offsetof(CONTEXT_NAME, cert_sig)), 0x00, 0x00, - 0x01, T0_INT2(offsetof(CONTEXT_NAME, cert_sig_hash_len)), 0x00, 0x00, - 0x01, T0_INT2(offsetof(CONTEXT_NAME, cert_sig_hash_oid)), 0x00, 0x00, - 0x01, T0_INT2(offsetof(CONTEXT_NAME, cert_sig_len)), 0x00, 0x00, 0x01, - T0_INT2(offsetof(CONTEXT_NAME, cert_signer_key_type)), 0x00, 0x00, - 0x01, T0_INT2(offsetof(CONTEXT_NAME, current_dn_hash)), 0x00, 0x00, - 0x01, T0_INT2(offsetof(CONTEXT_NAME, key_usages)), 0x00, 0x00, 0x01, - T0_INT2(offsetof(br_x509_minimal_context, pkey_data)), 0x01, - T0_INT2(BR_X509_BUFSIZE_KEY), 0x00, 0x00, 0x01, - T0_INT2(offsetof(CONTEXT_NAME, min_rsa_size)), 0x00, 0x00, 0x01, - T0_INT2(offsetof(CONTEXT_NAME, next_dn_hash)), 0x00, 0x00, 0x01, - T0_INT2(offsetof(CONTEXT_NAME, num_certs)), 0x00, 0x00, 0x01, - T0_INT2(offsetof(CONTEXT_NAME, pad)), 0x00, 0x00, 0x01, - T0_INT2(offsetof(CONTEXT_NAME, saved_dn_hash)), 0x00, 0x00, 0xC9, 0x71, - 0x00, 0x00, 0x01, 0x80, 0x73, 0x00, 0x00, 0x01, 0x80, 0x7C, 0x00, 0x00, - 0x01, 0x81, 0x02, 0x00, 0x00, 0x92, 0x05, 0x05, 0x34, 0x42, 0x01, 0x00, - 0x00, 0x34, 0x01, 0x0A, 0x0E, 0x09, 0x01, 0x9A, 0xFF, 0xB8, 0x00, 0x0A, - 0x00, 0x00, 0x01, 0x82, 0x19, 0x00, 0x00, 0x01, 0x82, 0x01, 0x00, 0x00, - 0x01, 0x81, 0x68, 0x00, 0x04, 0x03, 0x00, 0x03, 0x01, 0x03, 0x02, 0x03, - 0x03, 0x02, 0x03, 0x02, 0x01, 0x11, 0x06, 0x07, 0x02, 0x02, 0x02, 0x00, - 0x0D, 0x04, 0x05, 0x02, 0x03, 0x02, 0x01, 0x0D, 0x00, 0x02, 0x03, 0x00, - 0x03, 0x01, 0x25, 0x02, 0x01, 0x13, 0x3B, 0x02, 0x00, 0x0F, 0x15, 0x00, - 0x00, 0x01, 0x81, 0x74, 0x00, 0x00, 0x05, 0x02, 0x52, 0x28, 0x00, 0x00, - 0x06, 0x02, 0x53, 0x28, 0x00, 0x00, 0x01, 0x10, 0x77, 0x00, 0x00, 0x11, - 0x05, 0x02, 0x56, 0x28, 0x74, 0x00, 0x00, 0x11, 0x05, 0x02, 0x56, 0x28, - 0x75, 0x00, 0x00, 0x06, 0x02, 0x4C, 0x28, 0x00, 0x00, 0x01, 0x82, 0x11, - 0x00, 0x00, 0x25, 0x20, 0x01, 0x08, 0x0E, 0x3B, 0x40, 0x20, 0x09, 0x00, - 0x09, 0x03, 0x00, 0x5B, 0x2B, 0xAF, 0x39, 0xAF, 0xB3, 0x25, 0x01, 0x20, - 0x11, 0x06, 0x11, 0x24, 0x74, 0xAD, 0xB3, 0x01, 0x02, 0x78, 0xB0, 0x01, - 0x02, 0x12, 0x06, 0x02, 0x57, 0x28, 0x79, 0xB3, 0x01, 0x02, 0x78, 0xAE, - 0xAF, 0xC2, 0x9C, 0x65, 0x61, 0x21, 0x16, 0xAF, 0xA7, 0x29, 0x69, 0x06, - 0x02, 0x4B, 0x28, 0xA7, 0x29, 0x71, 0x06, 0x02, 0x4B, 0x28, 0x79, 0x02, - 0x00, 0x06, 0x05, 0x9D, 0x03, 0x01, 0x04, 0x09, 0x9C, 0x61, 0x68, 0x21, - 0x27, 0x05, 0x02, 0x4A, 0x28, 0x68, 0x65, 0x21, 0x16, 0xAF, 0xAF, 0x9E, - 0x05, 0x02, 0x57, 0x28, 0xBC, 0x26, 0x06, 0x27, 0xC2, 0xA4, 0xAF, 0x63, - 0xAA, 0x03, 0x03, 0x63, 0x3B, 0x02, 0x03, 0x09, 0x3B, 0x02, 0x03, 0x0A, - 0xAA, 0x03, 0x04, 0x79, 0x64, 0x2A, 0x01, 0x81, 0x00, 0x09, 0x02, 0x03, - 0x12, 0x06, 0x02, 0x58, 0x28, 0x79, 0x5A, 0x03, 0x02, 0x04, 0x3A, 0x88, - 0x26, 0x06, 0x34, 0x9E, 0x05, 0x02, 0x57, 0x28, 0x6A, 0x26, 0x06, 0x04, - 0x01, 0x17, 0x04, 0x12, 0x6B, 0x26, 0x06, 0x04, 0x01, 0x18, 0x04, 0x0A, - 0x6C, 0x26, 0x06, 0x04, 0x01, 0x19, 0x04, 0x02, 0x57, 0x28, 0x03, 0x05, - 0x79, 0xA4, 0x25, 0x03, 0x06, 0x25, 0x63, 0x34, 0x0D, 0x06, 0x02, 0x50, - 0x28, 0xA5, 0x59, 0x03, 0x02, 0x04, 0x02, 0x57, 0x28, 0x79, 0x02, 0x00, - 0x06, 0x21, 0x02, 0x02, 0x5A, 0x30, 0x11, 0x06, 0x08, 0x24, 0x02, 0x03, - 0x02, 0x04, 0x1D, 0x04, 0x10, 0x59, 0x30, 0x11, 0x06, 0x08, 0x24, 0x02, - 0x05, 0x02, 0x06, 0x1C, 0x04, 0x03, 0x57, 0x28, 0x24, 0x04, 0x24, 0x02, - 0x02, 0x5A, 0x30, 0x11, 0x06, 0x08, 0x24, 0x02, 0x03, 0x02, 0x04, 0x23, - 0x04, 0x10, 0x59, 0x30, 0x11, 0x06, 0x08, 0x24, 0x02, 0x05, 0x02, 0x06, - 0x22, 0x04, 0x03, 0x57, 0x28, 0x24, 0x25, 0x06, 0x01, 0x28, 0x24, 0x01, - 0x00, 0x03, 0x07, 0xB4, 0x01, 0x21, 0x8F, 0x01, 0x22, 0x8F, 0x25, 0x01, - 0x23, 0x11, 0x06, 0x81, 0x26, 0x24, 0x74, 0xAD, 0xAF, 0x25, 0x06, 0x81, - 0x1A, 0x01, 0x00, 0x03, 0x08, 0xAF, 0x9E, 0x24, 0xB3, 0x25, 0x01, 0x01, - 0x11, 0x06, 0x04, 0xA6, 0x03, 0x08, 0xB3, 0x01, 0x04, 0x78, 0xAD, 0x70, - 0x26, 0x06, 0x0F, 0x02, 0x00, 0x06, 0x03, 0xC3, 0x04, 0x05, 0x99, 0x01, - 0x7F, 0x03, 0x07, 0x04, 0x80, 0x6C, 0x91, 0x26, 0x06, 0x06, 0x02, 0x00, - 0x9B, 0x04, 0x80, 0x62, 0xC5, 0x26, 0x06, 0x11, 0x02, 0x00, 0x06, 0x09, - 0x01, 0x00, 0x03, 0x01, 0x98, 0x03, 0x01, 0x04, 0x01, 0xC3, 0x04, 0x80, - 0x4D, 0x73, 0x26, 0x06, 0x0A, 0x02, 0x08, 0x06, 0x03, 0x9A, 0x04, 0x01, - 0xC3, 0x04, 0x3F, 0x6F, 0x26, 0x06, 0x03, 0xC3, 0x04, 0x38, 0xC8, 0x26, - 0x06, 0x03, 0xC3, 0x04, 0x31, 0x90, 0x26, 0x06, 0x03, 0xC3, 0x04, 0x2A, - 0xC6, 0x26, 0x06, 0x03, 0xC3, 0x04, 0x23, 0x7A, 0x26, 0x06, 0x03, 0xC3, - 0x04, 0x1C, 0x85, 0x26, 0x06, 0x03, 0xC3, 0x04, 0x15, 0x6E, 0x26, 0x06, - 0x03, 0xC3, 0x04, 0x0E, 0xC7, 0x26, 0x06, 0x03, 0xC3, 0x04, 0x07, 0x02, - 0x08, 0x06, 0x02, 0x49, 0x28, 0xC3, 0x79, 0x79, 0x04, 0xFE, 0x62, 0x79, - 0x79, 0x04, 0x08, 0x01, 0x7F, 0x11, 0x05, 0x02, 0x56, 0x28, 0x24, 0x79, - 0x3A, 0x02, 0x00, 0x06, 0x08, 0x02, 0x01, 0x3C, 0x2F, 0x05, 0x02, 0x45, - 0x28, 0x02, 0x00, 0x06, 0x01, 0x17, 0x02, 0x00, 0x02, 0x07, 0x2F, 0x05, - 0x02, 0x51, 0x28, 0xB3, 0x76, 0xAD, 0x9E, 0x06, 0x80, 0x77, 0xBD, 0x26, - 0x06, 0x07, 0x01, 0x02, 0x5A, 0x8A, 0x04, 0x80, 0x5E, 0xBE, 0x26, 0x06, - 0x07, 0x01, 0x03, 0x5A, 0x8B, 0x04, 0x80, 0x53, 0xBF, 0x26, 0x06, 0x07, - 0x01, 0x04, 0x5A, 0x8C, 0x04, 0x80, 0x48, 0xC0, 0x26, 0x06, 0x06, 0x01, - 0x05, 0x5A, 0x8D, 0x04, 0x3E, 0xC1, 0x26, 0x06, 0x06, 0x01, 0x06, 0x5A, - 0x8E, 0x04, 0x34, 0x7F, 0x26, 0x06, 0x06, 0x01, 0x02, 0x59, 0x8A, 0x04, - 0x2A, 0x80, 0x26, 0x06, 0x06, 0x01, 0x03, 0x59, 0x8B, 0x04, 0x20, 0x81, - 0x26, 0x06, 0x06, 0x01, 0x04, 0x59, 0x8C, 0x04, 0x16, 0x82, 0x26, 0x06, - 0x06, 0x01, 0x05, 0x59, 0x8D, 0x04, 0x0C, 0x83, 0x26, 0x06, 0x06, 0x01, - 0x06, 0x59, 0x8E, 0x04, 0x02, 0x57, 0x28, 0x5E, 0x35, 0x60, 0x37, 0x1B, - 0x25, 0x05, 0x02, 0x57, 0x28, 0x5D, 0x37, 0x04, 0x02, 0x57, 0x28, 0xC2, - 0xA4, 0x25, 0x01, T0_INT2(BR_X509_BUFSIZE_SIG), 0x12, 0x06, 0x02, 0x50, - 0x28, 0x25, 0x5F, 0x35, 0x5C, 0xA5, 0x79, 0x79, 0x01, 0x00, 0x5B, 0x36, - 0x18, 0x00, 0x00, 0x01, 0x30, 0x0A, 0x25, 0x01, 0x00, 0x01, 0x09, 0x72, - 0x05, 0x02, 0x48, 0x28, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x01, 0x81, - 0x08, 0x00, 0x00, 0x01, 0x81, 0x10, 0x00, 0x00, 0x01, 0x81, 0x19, 0x00, - 0x00, 0x01, 0x81, 0x22, 0x00, 0x00, 0x01, 0x81, 0x2B, 0x00, 0x01, 0x7E, - 0x01, 0x01, 0x11, 0x3B, 0x01, 0x83, 0xFD, 0x7F, 0x11, 0x15, 0x06, 0x03, - 0x3B, 0x24, 0x00, 0x3B, 0x25, 0x03, 0x00, 0x25, 0xCA, 0x05, 0x04, 0x42, - 0x01, 0x00, 0x00, 0x25, 0x01, 0x81, 0x00, 0x0D, 0x06, 0x04, 0x96, 0x04, - 0x80, 0x49, 0x25, 0x01, 0x90, 0x00, 0x0D, 0x06, 0x0F, 0x01, 0x06, 0x14, - 0x01, 0x81, 0x40, 0x2F, 0x96, 0x02, 0x00, 0x01, 0x00, 0x97, 0x04, 0x33, - 0x25, 0x01, 0x83, 0xFF, 0x7F, 0x0D, 0x06, 0x14, 0x01, 0x0C, 0x14, 0x01, - 0x81, 0x60, 0x2F, 0x96, 0x02, 0x00, 0x01, 0x06, 0x97, 0x02, 0x00, 0x01, - 0x00, 0x97, 0x04, 0x17, 0x01, 0x12, 0x14, 0x01, 0x81, 0x70, 0x2F, 0x96, - 0x02, 0x00, 0x01, 0x0C, 0x97, 0x02, 0x00, 0x01, 0x06, 0x97, 0x02, 0x00, - 0x01, 0x00, 0x97, 0x00, 0x00, 0x01, 0x82, 0x15, 0x00, 0x00, 0x25, 0x01, - 0x83, 0xB0, 0x00, 0x01, 0x83, 0xB7, 0x7F, 0x72, 0x00, 0x00, 0x01, 0x81, - 0x34, 0x00, 0x00, 0x01, 0x80, 0x6B, 0x00, 0x00, 0x01, 0x81, 0x78, 0x00, - 0x00, 0x01, 0x3D, 0x00, 0x00, 0x01, 0x80, 0x43, 0x00, 0x00, 0x01, 0x80, - 0x4D, 0x00, 0x00, 0x01, 0x80, 0x57, 0x00, 0x00, 0x01, 0x80, 0x61, 0x00, - 0x00, 0x30, 0x11, 0x06, 0x04, 0x42, 0xAD, 0xC2, 0xB4, 0x00, 0x00, 0x01, - 0x82, 0x09, 0x00, 0x00, 0x01, 0x81, 0x6C, 0x00, 0x00, 0x25, 0x01, 0x83, - 0xB8, 0x00, 0x01, 0x83, 0xBF, 0x7F, 0x72, 0x00, 0x00, 0x01, 0x30, 0x62, - 0x37, 0x01, 0x7F, 0x7C, 0x19, 0x01, 0x00, 0x7C, 0x19, 0x04, 0x7A, 0x00, - 0x01, 0x81, 0x38, 0x00, 0x01, 0x7E, 0x0D, 0x06, 0x02, 0x4F, 0x28, 0x25, - 0x03, 0x00, 0x0A, 0x02, 0x00, 0x00, 0x00, 0x30, 0x25, 0x3F, 0x3B, 0x01, - 0x82, 0x00, 0x13, 0x2F, 0x06, 0x04, 0x42, 0x01, 0x00, 0x00, 0x30, 0x67, - 0x09, 0x37, 0x40, 0x00, 0x00, 0x14, 0x01, 0x3F, 0x15, 0x01, 0x81, 0x00, - 0x2F, 0x96, 0x00, 0x02, 0x01, 0x00, 0x03, 0x00, 0xAF, 0x25, 0x06, 0x80, - 0x59, 0xB3, 0x01, 0x20, 0x30, 0x11, 0x06, 0x17, 0x24, 0x74, 0xAD, 0x9E, - 0x24, 0x01, 0x7F, 0x2E, 0x03, 0x01, 0xB3, 0x01, 0x20, 0x77, 0xAD, 0xB2, - 0x02, 0x01, 0x1F, 0x79, 0x79, 0x04, 0x38, 0x01, 0x21, 0x30, 0x11, 0x06, - 0x08, 0x24, 0x75, 0xB6, 0x01, 0x01, 0x1E, 0x04, 0x2A, 0x01, 0x22, 0x30, - 0x11, 0x06, 0x11, 0x24, 0x75, 0xB6, 0x25, 0x06, 0x06, 0x2C, 0x02, 0x00, - 0x2F, 0x03, 0x00, 0x01, 0x02, 0x1E, 0x04, 0x13, 0x01, 0x26, 0x30, 0x11, - 0x06, 0x08, 0x24, 0x75, 0xB6, 0x01, 0x06, 0x1E, 0x04, 0x05, 0x42, 0xAE, - 0x01, 0x00, 0x24, 0x04, 0xFF, 0x23, 0x79, 0x02, 0x00, 0x00, 0x00, 0xAF, - 0xB4, 0x25, 0x01, 0x01, 0x11, 0x06, 0x08, 0xA6, 0x05, 0x02, 0x51, 0x28, - 0xB4, 0x04, 0x02, 0x51, 0x28, 0x25, 0x01, 0x02, 0x11, 0x06, 0x0C, 0x24, - 0x75, 0xB0, 0x66, 0x2B, 0x41, 0x0D, 0x06, 0x02, 0x51, 0x28, 0xB4, 0x01, - 0x7F, 0x10, 0x06, 0x02, 0x56, 0x28, 0x24, 0x79, 0x00, 0x00, 0xAF, 0x25, - 0x06, 0x1A, 0xAF, 0x9E, 0x24, 0x25, 0x06, 0x11, 0xAF, 0x25, 0x06, 0x0C, - 0xAF, 0x9E, 0x24, 0x89, 0x26, 0x05, 0x02, 0x49, 0x28, 0xC2, 0x04, 0x71, - 0x79, 0x79, 0x04, 0x63, 0x79, 0x00, 0x02, 0x03, 0x00, 0xB3, 0x01, 0x03, - 0x78, 0xAD, 0xBA, 0x03, 0x01, 0x02, 0x01, 0x01, 0x07, 0x12, 0x06, 0x02, - 0x56, 0x28, 0x25, 0x01, 0x00, 0x30, 0x11, 0x06, 0x05, 0x24, 0x4D, 0x28, - 0x04, 0x15, 0x01, 0x01, 0x30, 0x11, 0x06, 0x0A, 0x24, 0xBA, 0x02, 0x01, - 0x14, 0x02, 0x01, 0x0E, 0x04, 0x05, 0x24, 0xBA, 0x01, 0x00, 0x24, 0x02, - 0x00, 0x06, 0x19, 0x01, 0x00, 0x30, 0x01, 0x38, 0x15, 0x06, 0x03, 0x01, - 0x10, 0x2F, 0x3B, 0x01, 0x81, 0x40, 0x15, 0x06, 0x03, 0x01, 0x20, 0x2F, - 0x62, 0x37, 0x04, 0x07, 0x01, 0x04, 0x15, 0x05, 0x02, 0x4D, 0x28, 0xC2, - 0x00, 0x00, 0x38, 0xAF, 0xC2, 0x1A, 0x00, 0x03, 0x01, 0x00, 0x03, 0x00, - 0x38, 0xAF, 0x25, 0x06, 0x30, 0xB3, 0x01, 0x11, 0x77, 0xAD, 0x25, 0x05, - 0x02, 0x44, 0x28, 0x25, 0x06, 0x20, 0xAF, 0x9E, 0x24, 0x87, 0x26, 0x03, - 0x01, 0x01, 0x00, 0x2E, 0x03, 0x02, 0xB2, 0x25, 0x02, 0x01, 0x15, 0x06, - 0x07, 0x2C, 0x06, 0x04, 0x01, 0x7F, 0x03, 0x00, 0x02, 0x02, 0x1F, 0x79, - 0x04, 0x5D, 0x79, 0x04, 0x4D, 0x79, 0x1A, 0x02, 0x00, 0x00, 0x00, 0xB3, - 0x01, 0x06, 0x78, 0xB1, 0x00, 0x00, 0xB8, 0x86, 0x06, 0x0E, 0x3B, 0x25, - 0x05, 0x06, 0x42, 0x01, 0x00, 0x01, 0x00, 0x00, 0xB8, 0x6D, 0x04, 0x08, - 0x92, 0x06, 0x05, 0x24, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0xB9, 0x86, - 0x06, 0x0E, 0x3B, 0x25, 0x05, 0x06, 0x42, 0x01, 0x00, 0x01, 0x00, 0x00, - 0xB9, 0x6D, 0x04, 0x08, 0x92, 0x06, 0x05, 0x24, 0x01, 0x00, 0x04, 0x00, - 0x00, 0x00, 0xBA, 0x25, 0x01, 0x81, 0x00, 0x0D, 0x06, 0x04, 0x00, 0x04, - 0x80, 0x55, 0x25, 0x01, 0x81, 0x40, 0x0D, 0x06, 0x07, 0x24, 0x01, 0x00, - 0x00, 0x04, 0x80, 0x47, 0x25, 0x01, 0x81, 0x60, 0x0D, 0x06, 0x0E, 0x01, - 0x1F, 0x15, 0x01, 0x01, 0xA3, 0x01, 0x81, 0x00, 0x01, 0x8F, 0x7F, 0x04, - 0x32, 0x25, 0x01, 0x81, 0x70, 0x0D, 0x06, 0x0F, 0x01, 0x0F, 0x15, 0x01, - 0x02, 0xA3, 0x01, 0x90, 0x00, 0x01, 0x83, 0xFF, 0x7F, 0x04, 0x1C, 0x25, - 0x01, 0x81, 0x78, 0x0D, 0x06, 0x11, 0x01, 0x07, 0x15, 0x01, 0x03, 0xA3, - 0x01, 0x84, 0x80, 0x00, 0x01, 0x80, 0xC3, 0xFF, 0x7F, 0x04, 0x04, 0x24, - 0x01, 0x00, 0x00, 0x72, 0x05, 0x03, 0x24, 0x01, 0x00, 0x00, 0x00, 0x3B, - 0x25, 0x05, 0x06, 0x42, 0x01, 0x00, 0x01, 0x7F, 0x00, 0xBA, 0x34, 0x25, - 0x3D, 0x06, 0x03, 0x3B, 0x24, 0x00, 0x01, 0x06, 0x0E, 0x3B, 0x25, 0x01, - 0x06, 0x14, 0x01, 0x02, 0x10, 0x06, 0x04, 0x42, 0x01, 0x7F, 0x00, 0x01, - 0x3F, 0x15, 0x09, 0x00, 0x00, 0x25, 0x06, 0x06, 0x0B, 0xA2, 0x34, 0x41, - 0x04, 0x77, 0x24, 0x25, 0x00, 0x00, 0xB3, 0x01, 0x03, 0x78, 0xAD, 0xBA, - 0x06, 0x02, 0x55, 0x28, 0x00, 0x00, 0x3B, 0x25, 0x06, 0x07, 0x31, 0x25, - 0x06, 0x01, 0x19, 0x04, 0x76, 0x42, 0x00, 0x00, 0x01, 0x01, 0x78, 0xAC, - 0x01, 0x01, 0x10, 0x06, 0x02, 0x43, 0x28, 0xBA, 0x3E, 0x00, 0x04, 0xB3, - 0x25, 0x01, 0x17, 0x01, 0x18, 0x72, 0x05, 0x02, 0x48, 0x28, 0x01, 0x18, - 0x11, 0x03, 0x00, 0x75, 0xAD, 0xA8, 0x02, 0x00, 0x06, 0x0C, 0x01, 0x80, - 0x64, 0x08, 0x03, 0x01, 0xA8, 0x02, 0x01, 0x09, 0x04, 0x0E, 0x25, 0x01, - 0x32, 0x0D, 0x06, 0x04, 0x01, 0x80, 0x64, 0x09, 0x01, 0x8E, 0x6C, 0x09, - 0x03, 0x01, 0x02, 0x01, 0x01, 0x82, 0x6D, 0x08, 0x02, 0x01, 0x01, 0x03, - 0x09, 0x01, 0x04, 0x0C, 0x09, 0x02, 0x01, 0x01, 0x80, 0x63, 0x09, 0x01, - 0x80, 0x64, 0x0C, 0x0A, 0x02, 0x01, 0x01, 0x83, 0x0F, 0x09, 0x01, 0x83, - 0x10, 0x0C, 0x09, 0x03, 0x03, 0x01, 0x01, 0x01, 0x0C, 0xA9, 0x41, 0x01, - 0x01, 0x0E, 0x02, 0x01, 0x01, 0x04, 0x07, 0x3F, 0x02, 0x01, 0x01, 0x80, - 0x64, 0x07, 0x3E, 0x02, 0x01, 0x01, 0x83, 0x10, 0x07, 0x3F, 0x2F, 0x15, - 0x06, 0x03, 0x01, 0x18, 0x09, 0x94, 0x09, 0x7B, 0x25, 0x01, 0x05, 0x14, - 0x02, 0x03, 0x09, 0x03, 0x03, 0x01, 0x1F, 0x15, 0x01, 0x01, 0x3B, 0xA9, - 0x02, 0x03, 0x09, 0x41, 0x03, 0x03, 0x01, 0x00, 0x01, 0x17, 0xA9, 0x01, - 0x9C, 0x10, 0x08, 0x03, 0x02, 0x01, 0x00, 0x01, 0x3B, 0xA9, 0x01, 0x3C, - 0x08, 0x02, 0x02, 0x09, 0x03, 0x02, 0x01, 0x00, 0x01, 0x3C, 0xA9, 0x02, - 0x02, 0x09, 0x03, 0x02, 0xBA, 0x25, 0x01, 0x2E, 0x11, 0x06, 0x0D, 0x24, - 0xBA, 0x25, 0x01, 0x30, 0x01, 0x39, 0x72, 0x06, 0x03, 0x24, 0x04, 0x74, - 0x01, 0x80, 0x5A, 0x10, 0x06, 0x02, 0x48, 0x28, 0x79, 0x02, 0x03, 0x02, - 0x02, 0x00, 0x01, 0xBA, 0x7D, 0x01, 0x0A, 0x08, 0x03, 0x00, 0xBA, 0x7D, - 0x02, 0x00, 0x09, 0x00, 0x02, 0x03, 0x00, 0x03, 0x01, 0xA8, 0x25, 0x02, - 0x01, 0x02, 0x00, 0x72, 0x05, 0x02, 0x48, 0x28, 0x00, 0x00, 0x34, 0xB3, - 0x01, 0x02, 0x78, 0x0B, 0xAB, 0x00, 0x03, 0x25, 0x03, 0x00, 0x03, 0x01, - 0x03, 0x02, 0xAD, 0xBA, 0x25, 0x01, 0x81, 0x00, 0x13, 0x06, 0x02, 0x54, - 0x28, 0x25, 0x01, 0x00, 0x11, 0x06, 0x0B, 0x24, 0x25, 0x05, 0x04, 0x24, - 0x01, 0x00, 0x00, 0xBA, 0x04, 0x6F, 0x02, 0x01, 0x25, 0x05, 0x02, 0x50, - 0x28, 0x41, 0x03, 0x01, 0x02, 0x02, 0x37, 0x02, 0x02, 0x40, 0x03, 0x02, - 0x25, 0x06, 0x03, 0xBA, 0x04, 0x68, 0x24, 0x02, 0x00, 0x02, 0x01, 0x0A, - 0x00, 0x01, 0xBA, 0x25, 0x01, 0x81, 0x00, 0x0D, 0x06, 0x01, 0x00, 0x01, - 0x81, 0x00, 0x0A, 0x25, 0x05, 0x02, 0x4E, 0x28, 0x03, 0x00, 0x01, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x12, 0x06, 0x19, 0x02, 0x00, 0x41, 0x03, 0x00, - 0x25, 0x01, 0x83, 0xFF, 0xFF, 0x7F, 0x12, 0x06, 0x02, 0x4F, 0x28, 0x01, - 0x08, 0x0E, 0x3B, 0xBA, 0x34, 0x09, 0x04, 0x60, 0x00, 0x00, 0xAC, 0x95, - 0x00, 0x00, 0xAD, 0xC2, 0x00, 0x00, 0xB3, 0x76, 0xAD, 0x00, 0x01, 0xAD, - 0x25, 0x05, 0x02, 0x54, 0x28, 0xBA, 0x25, 0x01, 0x81, 0x00, 0x13, 0x06, - 0x02, 0x54, 0x28, 0x03, 0x00, 0x25, 0x06, 0x16, 0xBA, 0x02, 0x00, 0x25, - 0x01, 0x87, 0xFF, 0xFF, 0x7F, 0x13, 0x06, 0x02, 0x54, 0x28, 0x01, 0x08, - 0x0E, 0x09, 0x03, 0x00, 0x04, 0x67, 0x24, 0x02, 0x00, 0x00, 0x00, 0xAD, - 0x25, 0x01, 0x81, 0x7F, 0x12, 0x06, 0x08, 0xC2, 0x01, 0x00, 0x67, 0x37, - 0x01, 0x00, 0x00, 0x25, 0x67, 0x37, 0x67, 0x40, 0xA5, 0x01, 0x7F, 0x00, - 0x00, 0xB3, 0x01, 0x0C, 0x30, 0x11, 0x06, 0x05, 0x24, 0x75, 0xB6, 0x04, - 0x3E, 0x01, 0x12, 0x30, 0x11, 0x06, 0x05, 0x24, 0x75, 0xB7, 0x04, 0x33, - 0x01, 0x13, 0x30, 0x11, 0x06, 0x05, 0x24, 0x75, 0xB7, 0x04, 0x28, 0x01, - 0x14, 0x30, 0x11, 0x06, 0x05, 0x24, 0x75, 0xB7, 0x04, 0x1D, 0x01, 0x16, - 0x30, 0x11, 0x06, 0x05, 0x24, 0x75, 0xB7, 0x04, 0x12, 0x01, 0x1E, 0x30, - 0x11, 0x06, 0x05, 0x24, 0x75, 0xB5, 0x04, 0x07, 0x42, 0xAE, 0x01, 0x00, - 0x01, 0x00, 0x24, 0x00, 0x01, 0xBA, 0x03, 0x00, 0x02, 0x00, 0x01, 0x05, - 0x14, 0x01, 0x01, 0x15, 0x2D, 0x02, 0x00, 0x01, 0x06, 0x14, 0x25, 0x01, - 0x01, 0x15, 0x06, 0x02, 0x46, 0x28, 0x01, 0x04, 0x0E, 0x02, 0x00, 0x01, - 0x1F, 0x15, 0x25, 0x01, 0x1F, 0x11, 0x06, 0x02, 0x47, 0x28, 0x09, 0x00, - 0x00, 0x25, 0x05, 0x05, 0x01, 0x00, 0x01, 0x7F, 0x00, 0xB3, 0x00, 0x01, - 0xAD, 0x25, 0x05, 0x05, 0x67, 0x37, 0x01, 0x7F, 0x00, 0x01, 0x01, 0x03, - 0x00, 0x9F, 0x25, 0x01, 0x83, 0xFF, 0x7E, 0x11, 0x06, 0x16, 0x24, 0x25, - 0x06, 0x10, 0xA0, 0x25, 0x05, 0x05, 0x24, 0xC2, 0x01, 0x00, 0x00, 0x02, - 0x00, 0x84, 0x03, 0x00, 0x04, 0x6D, 0x04, 0x1B, 0x25, 0x05, 0x05, 0x24, - 0xC2, 0x01, 0x00, 0x00, 0x02, 0x00, 0x84, 0x03, 0x00, 0x25, 0x06, 0x0B, - 0x9F, 0x25, 0x05, 0x05, 0x24, 0xC2, 0x01, 0x00, 0x00, 0x04, 0x6D, 0x24, - 0x02, 0x00, 0x25, 0x05, 0x01, 0x00, 0x41, 0x67, 0x37, 0x01, 0x7F, 0x00, - 0x01, 0xAD, 0x01, 0x01, 0x03, 0x00, 0x25, 0x06, 0x10, 0xA1, 0x25, 0x05, - 0x05, 0x24, 0xC2, 0x01, 0x00, 0x00, 0x02, 0x00, 0x84, 0x03, 0x00, 0x04, - 0x6D, 0x24, 0x02, 0x00, 0x25, 0x05, 0x01, 0x00, 0x41, 0x67, 0x37, 0x01, - 0x7F, 0x00, 0x01, 0xAD, 0x01, 0x01, 0x03, 0x00, 0x25, 0x06, 0x10, 0xBA, - 0x25, 0x05, 0x05, 0x24, 0xC2, 0x01, 0x00, 0x00, 0x02, 0x00, 0x84, 0x03, - 0x00, 0x04, 0x6D, 0x24, 0x02, 0x00, 0x25, 0x05, 0x01, 0x00, 0x41, 0x67, - 0x37, 0x01, 0x7F, 0x00, 0x00, 0xBA, 0x01, 0x08, 0x0E, 0x3B, 0xBA, 0x34, - 0x09, 0x00, 0x00, 0xBA, 0x3B, 0xBA, 0x01, 0x08, 0x0E, 0x34, 0x09, 0x00, - 0x00, 0x25, 0x05, 0x02, 0x4F, 0x28, 0x41, 0xBB, 0x00, 0x00, 0x32, 0x25, - 0x01, 0x00, 0x13, 0x06, 0x01, 0x00, 0x24, 0x19, 0x04, 0x74, 0x00, 0x01, - 0x01, 0x00, 0x00, 0x01, 0x0B, 0x00, 0x00, 0x01, 0x15, 0x00, 0x00, 0x01, - 0x1F, 0x00, 0x00, 0x01, 0x29, 0x00, 0x00, 0x01, 0x33, 0x00, 0x00, 0xC3, - 0x24, 0x00, 0x00, 0x25, 0x06, 0x07, 0xC4, 0x25, 0x06, 0x01, 0x19, 0x04, - 0x76, 0x00, 0x00, 0x01, 0x00, 0x30, 0x31, 0x0B, 0x42, 0x00, 0x00, 0x01, - 0x81, 0x70, 0x00, 0x00, 0x01, 0x82, 0x0D, 0x00, 0x00, 0x01, 0x82, 0x22, - 0x00, 0x00, 0x01, 0x82, 0x05, 0x00, 0x00, 0x01, 0x03, 0x33, 0x01, 0x03, - 0x33, 0x00, 0x00, 0x25, 0x01, 0x83, 0xFB, 0x50, 0x01, 0x83, 0xFD, 0x5F, - 0x72, 0x06, 0x04, 0x24, 0x01, 0x00, 0x00, 0x25, 0x01, 0x83, 0xB0, 0x00, - 0x01, 0x83, 0xBF, 0x7F, 0x72, 0x06, 0x04, 0x24, 0x01, 0x00, 0x00, 0x01, - 0x83, 0xFF, 0x7F, 0x15, 0x01, 0x83, 0xFF, 0x7E, 0x0D, 0x00 -}; - -static const uint16_t t0_caddr[] = { - 0, - 5, - 10, - 15, - 20, - 25, - 29, - 33, - 37, - 41, - 45, - 49, - 53, - 57, - 61, - 65, - 69, - 73, - 77, - 81, - 85, - 89, - 93, - 97, - 101, - 105, - 109, - 113, - 117, - 121, - 125, - 130, - 135, - 140, - 145, - 150, - 155, - 160, - 165, - 173, - 178, - 183, - 188, - 193, - 198, - 202, - 207, - 212, - 217, - 238, - 243, - 248, - 253, - 282, - 297, - 302, - 308, - 314, - 319, - 327, - 335, - 341, - 346, - 357, - 992, - 1007, - 1011, - 1016, - 1021, - 1026, - 1031, - 1036, - 1150, - 1155, - 1167, - 1172, - 1177, - 1182, - 1186, - 1191, - 1196, - 1201, - 1206, - 1216, - 1221, - 1226, - 1238, - 1253, - 1258, - 1272, - 1294, - 1305, - 1408, - 1455, - 1488, - 1579, - 1585, - 1648, - 1655, - 1683, - 1711, - 1816, - 1858, - 1871, - 1883, - 1897, - 1912, - 2132, - 2146, - 2163, - 2172, - 2239, - 2295, - 2299, - 2303, - 2308, - 2356, - 2382, - 2458, - 2502, - 2513, - 2598, - 2636, - 2674, - 2684, - 2694, - 2703, - 2716, - 2720, - 2724, - 2728, - 2732, - 2736, - 2740, - 2744, - 2756, - 2764, - 2769, - 2774, - 2779, - 2784, - 2792 -}; - -#define T0_INTERPRETED 61 - -#define T0_ENTER(ip, rp, slot) do { \ - const unsigned char *t0_newip; \ - uint32_t t0_lnum; \ - t0_newip = &t0_codeblock[t0_caddr[(slot) - T0_INTERPRETED]]; \ - t0_lnum = t0_parse7E_unsigned(&t0_newip); \ - (rp) += t0_lnum; \ - *((rp) ++) = (uint32_t)((ip) - &t0_codeblock[0]) + (t0_lnum << 16); \ - (ip) = t0_newip; \ - } while (0) - -#define T0_DEFENTRY(name, slot) \ -void \ -name(void *ctx) \ -{ \ - t0_context *t0ctx = ctx; \ - t0ctx->ip = &t0_codeblock[0]; \ - T0_ENTER(t0ctx->ip, t0ctx->rp, slot); \ -} - -T0_DEFENTRY(br_x509_minimal_init_main, 147) - -#define T0_NEXT(t0ipp) (*(*(t0ipp)) ++) - -void -br_x509_minimal_run(void *t0ctx) -{ - uint32_t *dp, *rp; - const unsigned char *ip; - -#define T0_LOCAL(x) (*(rp - 2 - (x))) -#define T0_POP() (*-- dp) -#define T0_POPi() (*(int32_t *)(-- dp)) -#define T0_PEEK(x) (*(dp - 1 - (x))) -#define T0_PEEKi(x) (*(int32_t *)(dp - 1 - (x))) -#define T0_PUSH(v) do { *dp = (v); dp ++; } while (0) -#define T0_PUSHi(v) do { *(int32_t *)dp = (v); dp ++; } while (0) -#define T0_RPOP() (*-- rp) -#define T0_RPOPi() (*(int32_t *)(-- rp)) -#define T0_RPUSH(v) do { *rp = (v); rp ++; } while (0) -#define T0_RPUSHi(v) do { *(int32_t *)rp = (v); rp ++; } while (0) -#define T0_ROLL(x) do { \ - size_t t0len = (size_t)(x); \ - uint32_t t0tmp = *(dp - 1 - t0len); \ - memmove(dp - t0len - 1, dp - t0len, t0len * sizeof *dp); \ - *(dp - 1) = t0tmp; \ -} while (0) -#define T0_SWAP() do { \ - uint32_t t0tmp = *(dp - 2); \ - *(dp - 2) = *(dp - 1); \ - *(dp - 1) = t0tmp; \ -} while (0) -#define T0_ROT() do { \ - uint32_t t0tmp = *(dp - 3); \ - *(dp - 3) = *(dp - 2); \ - *(dp - 2) = *(dp - 1); \ - *(dp - 1) = t0tmp; \ -} while (0) -#define T0_NROT() do { \ - uint32_t t0tmp = *(dp - 1); \ - *(dp - 1) = *(dp - 2); \ - *(dp - 2) = *(dp - 3); \ - *(dp - 3) = t0tmp; \ -} while (0) -#define T0_PICK(x) do { \ - uint32_t t0depth = (x); \ - T0_PUSH(T0_PEEK(t0depth)); \ -} while (0) -#define T0_CO() do { \ - goto t0_exit; \ -} while (0) -#define T0_RET() goto t0_next - - dp = ((t0_context *)t0ctx)->dp; - rp = ((t0_context *)t0ctx)->rp; - ip = ((t0_context *)t0ctx)->ip; - goto t0_next; - for (;;) { - uint32_t t0x; - - t0_next: - t0x = T0_NEXT(&ip); - if (t0x < T0_INTERPRETED) { - switch (t0x) { - int32_t t0off; - - case 0: /* ret */ - t0x = T0_RPOP(); - rp -= (t0x >> 16); - t0x &= 0xFFFF; - if (t0x == 0) { - ip = NULL; - goto t0_exit; - } - ip = &t0_codeblock[t0x]; - break; - case 1: /* literal constant */ - T0_PUSHi(t0_parse7E_signed(&ip)); - break; - case 2: /* read local */ - T0_PUSH(T0_LOCAL(t0_parse7E_unsigned(&ip))); - break; - case 3: /* write local */ - T0_LOCAL(t0_parse7E_unsigned(&ip)) = T0_POP(); - break; - case 4: /* jump */ - t0off = t0_parse7E_signed(&ip); - ip += t0off; - break; - case 5: /* jump if */ - t0off = t0_parse7E_signed(&ip); - if (T0_POP()) { - ip += t0off; - } - break; - case 6: /* jump if not */ - t0off = t0_parse7E_signed(&ip); - if (!T0_POP()) { - ip += t0off; - } - break; - case 7: { - /* %25 */ - - int32_t b = T0_POPi(); - int32_t a = T0_POPi(); - T0_PUSHi(a % b); - - } - break; - case 8: { - /* * */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(a * b); - - } - break; - case 9: { - /* + */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(a + b); - - } - break; - case 10: { - /* - */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(a - b); - - } - break; - case 11: { - /* -rot */ - T0_NROT(); - } - break; - case 12: { - /* / */ - - int32_t b = T0_POPi(); - int32_t a = T0_POPi(); - T0_PUSHi(a / b); - - } - break; - case 13: { - /* < */ - - int32_t b = T0_POPi(); - int32_t a = T0_POPi(); - T0_PUSH(-(uint32_t)(a < b)); - - } - break; - case 14: { - /* << */ - - int c = (int)T0_POPi(); - uint32_t x = T0_POP(); - T0_PUSH(x << c); - - } - break; - case 15: { - /* <= */ - - int32_t b = T0_POPi(); - int32_t a = T0_POPi(); - T0_PUSH(-(uint32_t)(a <= b)); - - } - break; - case 16: { - /* <> */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(-(uint32_t)(a != b)); - - } - break; - case 17: { - /* = */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(-(uint32_t)(a == b)); - - } - break; - case 18: { - /* > */ - - int32_t b = T0_POPi(); - int32_t a = T0_POPi(); - T0_PUSH(-(uint32_t)(a > b)); - - } - break; - case 19: { - /* >= */ - - int32_t b = T0_POPi(); - int32_t a = T0_POPi(); - T0_PUSH(-(uint32_t)(a >= b)); - - } - break; - case 20: { - /* >> */ - - int c = (int)T0_POPi(); - int32_t x = T0_POPi(); - T0_PUSHi(x >> c); - - } - break; - case 21: { - /* and */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(a & b); - - } - break; - case 22: { - /* blobcopy */ - - size_t len = T0_POP(); - unsigned char *src = (unsigned char *)CTX + T0_POP(); - unsigned char *dst = (unsigned char *)CTX + T0_POP(); - memcpy(dst, src, len); - - } - break; - case 23: { - /* check-direct-trust */ - - size_t u; - - for (u = 0; u < CTX->trust_anchors_num; u ++) { - const br_x509_trust_anchor *ta; - unsigned char hashed_DN[64]; - int kt; - - ta = &CTX->trust_anchors[u]; - if (ta->flags & BR_X509_TA_CA) { - continue; - } - hash_dn(CTX, ta->dn.data, ta->dn.len, hashed_DN); - if (memcmp(hashed_DN, CTX->current_dn_hash, DNHASH_LEN)) { - continue; - } - kt = CTX->pkey.key_type; - if ((ta->pkey.key_type & 0x0F) != kt) { - continue; - } - switch (kt) { - - case BR_KEYTYPE_RSA: - if (!eqbigint(CTX->pkey.key.rsa.n, - CTX->pkey.key.rsa.nlen, - ta->pkey.key.rsa.n, - ta->pkey.key.rsa.nlen) - || !eqbigint(CTX->pkey.key.rsa.e, - CTX->pkey.key.rsa.elen, - ta->pkey.key.rsa.e, - ta->pkey.key.rsa.elen)) - { - continue; - } - break; - - case BR_KEYTYPE_EC: - if (CTX->pkey.key.ec.curve != ta->pkey.key.ec.curve - || CTX->pkey.key.ec.qlen != ta->pkey.key.ec.qlen - || memcmp(CTX->pkey.key.ec.q, - ta->pkey.key.ec.q, - ta->pkey.key.ec.qlen) != 0) - { - continue; - } - break; - - default: - continue; - } - - /* - * Direct trust match! - */ - CTX->err = BR_ERR_X509_OK; - T0_CO(); - } - - } - break; - case 24: { - /* check-trust-anchor-CA */ - - size_t u; - - for (u = 0; u < CTX->trust_anchors_num; u ++) { - const br_x509_trust_anchor *ta; - unsigned char hashed_DN[64]; - - ta = &CTX->trust_anchors[u]; - if (!(ta->flags & BR_X509_TA_CA)) { - continue; - } - hash_dn(CTX, ta->dn.data, ta->dn.len, hashed_DN); - if (memcmp(hashed_DN, CTX->saved_dn_hash, DNHASH_LEN)) { - continue; - } - if (verify_signature(CTX, &ta->pkey) == 0) { - CTX->err = BR_ERR_X509_OK; - T0_CO(); - } - } - - } - break; - case 25: { - /* co */ - T0_CO(); - } - break; - case 26: { - /* compute-dn-hash */ - - CTX->dn_hash_impl->out(&CTX->dn_hash.vtable, CTX->current_dn_hash); - CTX->do_dn_hash = 0; - - } - break; - case 27: { - /* compute-tbs-hash */ - - int id = T0_POPi(); - size_t len; - len = br_multihash_out(&CTX->mhash, id, CTX->tbs_hash); - T0_PUSH(len); - - } - break; - case 28: { - /* copy-ee-ec-pkey */ - - size_t qlen = T0_POP(); - uint32_t curve = T0_POP(); - memcpy(CTX->ee_pkey_data, CTX->pkey_data, qlen); - CTX->pkey.key_type = BR_KEYTYPE_EC; - CTX->pkey.key.ec.curve = curve; - CTX->pkey.key.ec.q = CTX->ee_pkey_data; - CTX->pkey.key.ec.qlen = qlen; - - } - break; - case 29: { - /* copy-ee-rsa-pkey */ - - size_t elen = T0_POP(); - size_t nlen = T0_POP(); - memcpy(CTX->ee_pkey_data, CTX->pkey_data, nlen + elen); - CTX->pkey.key_type = BR_KEYTYPE_RSA; - CTX->pkey.key.rsa.n = CTX->ee_pkey_data; - CTX->pkey.key.rsa.nlen = nlen; - CTX->pkey.key.rsa.e = CTX->ee_pkey_data + nlen; - CTX->pkey.key.rsa.elen = elen; - - } - break; - case 30: { - /* copy-name-SAN */ - - unsigned tag = T0_POP(); - unsigned ok = T0_POP(); - size_t u, len; - - len = CTX->pad[0]; - for (u = 0; u < CTX->num_name_elts; u ++) { - br_name_element *ne; - - ne = &CTX->name_elts[u]; - if (ne->status == 0 && ne->oid[0] == 0 && ne->oid[1] == tag) { - if (ok && ne->len > len) { - memcpy(ne->buf, CTX->pad + 1, len); - ne->buf[len] = 0; - ne->status = 1; - } else { - ne->status = -1; - } - break; - } - } - - } - break; - case 31: { - /* copy-name-element */ - - size_t len; - int32_t off = T0_POPi(); - int ok = T0_POPi(); - - if (off >= 0) { - br_name_element *ne = &CTX->name_elts[off]; - - if (ok) { - len = CTX->pad[0]; - if (len < ne->len) { - memcpy(ne->buf, CTX->pad + 1, len); - ne->buf[len] = 0; - ne->status = 1; - } else { - ne->status = -1; - } - } else { - ne->status = -1; - } - } - - } - break; - case 32: { - /* data-get8 */ - - size_t addr = T0_POP(); - T0_PUSH(t0_datablock[addr]); - - } - break; - case 33: { - /* dn-hash-length */ - - T0_PUSH(DNHASH_LEN); - - } - break; - case 34: { - /* do-ecdsa-vrfy */ - - size_t qlen = T0_POP(); - int curve = T0_POP(); - br_x509_pkey pk; - - pk.key_type = BR_KEYTYPE_EC; - pk.key.ec.curve = curve; - pk.key.ec.q = CTX->pkey_data; - pk.key.ec.qlen = qlen; - T0_PUSH(verify_signature(CTX, &pk)); - - } - break; - case 35: { - /* do-rsa-vrfy */ - - size_t elen = T0_POP(); - size_t nlen = T0_POP(); - br_x509_pkey pk; - - pk.key_type = BR_KEYTYPE_RSA; - pk.key.rsa.n = CTX->pkey_data; - pk.key.rsa.nlen = nlen; - pk.key.rsa.e = CTX->pkey_data + nlen; - pk.key.rsa.elen = elen; - T0_PUSH(verify_signature(CTX, &pk)); - - } - break; - case 36: { - /* drop */ - (void)T0_POP(); - } - break; - case 37: { - /* dup */ - T0_PUSH(T0_PEEK(0)); - } - break; - case 38: { - /* eqOID */ - - const unsigned char *a2 = &t0_datablock[T0_POP()]; - const unsigned char *a1 = &CTX->pad[0]; - size_t len = a1[0]; - int x; - if (len == a2[0]) { - x = -(memcmp(a1 + 1, a2 + 1, len) == 0); - } else { - x = 0; - } - T0_PUSH((uint32_t)x); - - } - break; - case 39: { - /* eqblob */ - - size_t len = T0_POP(); - const unsigned char *a2 = (const unsigned char *)CTX + T0_POP(); - const unsigned char *a1 = (const unsigned char *)CTX + T0_POP(); - T0_PUSHi(-(memcmp(a1, a2, len) == 0)); - - } - break; - case 40: { - /* fail */ - - CTX->err = T0_POPi(); - T0_CO(); - - } - break; - case 41: { - /* get-system-date */ - - if (CTX->days == 0 && CTX->seconds == 0) { -#if BR_USE_UNIX_TIME - time_t x = time(NULL); - - T0_PUSH((uint32_t)(x / 86400) + 719528); - T0_PUSH((uint32_t)(x % 86400)); -#elif BR_USE_WIN32_TIME - FILETIME ft; - uint64_t x; - - GetSystemTimeAsFileTime(&ft); - x = ((uint64_t)ft.dwHighDateTime << 32) - + (uint64_t)ft.dwLowDateTime; - x = (x / 10000000); - T0_PUSH((uint32_t)(x / 86400) + 584754); - T0_PUSH((uint32_t)(x % 86400)); -#else - CTX->err = BR_ERR_X509_TIME_UNKNOWN; - T0_CO(); -#endif - } else { - T0_PUSH(CTX->days); - T0_PUSH(CTX->seconds); - } - - } - break; - case 42: { - /* get16 */ - - uint32_t addr = T0_POP(); - T0_PUSH(*(uint16_t *)(void *)((unsigned char *)CTX + addr)); - - } - break; - case 43: { - /* get32 */ - - uint32_t addr = T0_POP(); - T0_PUSH(*(uint32_t *)(void *)((unsigned char *)CTX + addr)); - - } - break; - case 44: { - /* match-server-name */ - - size_t n1, n2; - - if (CTX->server_name == NULL) { - T0_PUSH(0); - T0_RET(); - } - n1 = strlen(CTX->server_name); - n2 = CTX->pad[0]; - if (n1 == n2 && eqnocase(&CTX->pad[1], CTX->server_name, n1)) { - T0_PUSHi(-1); - T0_RET(); - } - if (n2 >= 2 && CTX->pad[1] == '*' && CTX->pad[2] == '.') { - size_t u; - - u = 0; - while (u < n1 && CTX->server_name[u] != '.') { - u ++; - } - u ++; - n1 -= u; - if ((n2 - 2) == n1 - && eqnocase(&CTX->pad[3], CTX->server_name + u, n1)) - { - T0_PUSHi(-1); - T0_RET(); - } - } - T0_PUSH(0); - - } - break; - case 45: { - /* neg */ - - uint32_t a = T0_POP(); - T0_PUSH(-a); - - } - break; - case 46: { - /* offset-name-element */ - - unsigned san = T0_POP(); - size_t u; - - for (u = 0; u < CTX->num_name_elts; u ++) { - if (CTX->name_elts[u].status == 0) { - const unsigned char *oid; - size_t len, off; - - oid = CTX->name_elts[u].oid; - if (san) { - if (oid[0] != 0 || oid[1] != 0) { - continue; - } - off = 2; - } else { - off = 0; - } - len = oid[off]; - if (len != 0 && len == CTX->pad[0] - && memcmp(oid + off + 1, - CTX->pad + 1, len) == 0) - { - T0_PUSH(u); - T0_RET(); - } - } - } - T0_PUSHi(-1); - - } - break; - case 47: { - /* or */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(a | b); - - } - break; - case 48: { - /* over */ - T0_PUSH(T0_PEEK(1)); - } - break; - case 49: { - /* read-blob-inner */ - - uint32_t len = T0_POP(); - uint32_t addr = T0_POP(); - size_t clen = CTX->hlen; - if (clen > len) { - clen = (size_t)len; - } - if (addr != 0) { - memcpy((unsigned char *)CTX + addr, CTX->hbuf, clen); - } - if (CTX->do_mhash) { - br_multihash_update(&CTX->mhash, CTX->hbuf, clen); - } - if (CTX->do_dn_hash) { - CTX->dn_hash_impl->update( - &CTX->dn_hash.vtable, CTX->hbuf, clen); - } - CTX->hbuf += clen; - CTX->hlen -= clen; - T0_PUSH(addr + clen); - T0_PUSH(len - clen); - - } - break; - case 50: { - /* read8-low */ - - if (CTX->hlen == 0) { - T0_PUSHi(-1); - } else { - unsigned char x = *CTX->hbuf ++; - if (CTX->do_mhash) { - br_multihash_update(&CTX->mhash, &x, 1); - } - if (CTX->do_dn_hash) { - CTX->dn_hash_impl->update(&CTX->dn_hash.vtable, &x, 1); - } - CTX->hlen --; - T0_PUSH(x); - } - - } - break; - case 51: { - /* roll */ - T0_ROLL(T0_POP()); - } - break; - case 52: { - /* rot */ - T0_ROT(); - } - break; - case 53: { - /* set16 */ - - uint32_t addr = T0_POP(); - *(uint16_t *)(void *)((unsigned char *)CTX + addr) = T0_POP(); - - } - break; - case 54: { - /* set32 */ - - uint32_t addr = T0_POP(); - *(uint32_t *)(void *)((unsigned char *)CTX + addr) = T0_POP(); - - } - break; - case 55: { - /* set8 */ - - uint32_t addr = T0_POP(); - *((unsigned char *)CTX + addr) = (unsigned char)T0_POP(); - - } - break; - case 56: { - /* start-dn-hash */ - - CTX->dn_hash_impl->init(&CTX->dn_hash.vtable); - CTX->do_dn_hash = 1; - - } - break; - case 57: { - /* start-tbs-hash */ - - br_multihash_init(&CTX->mhash); - CTX->do_mhash = 1; - - } - break; - case 58: { - /* stop-tbs-hash */ - - CTX->do_mhash = 0; - - } - break; - case 59: { - /* swap */ - T0_SWAP(); - } - break; - case 60: { - /* zero-server-name */ - - T0_PUSHi(-(CTX->server_name == NULL)); - - } - break; - } - - } else { - T0_ENTER(ip, rp, t0x); - } - } -t0_exit: - ((t0_context *)t0ctx)->dp = dp; - ((t0_context *)t0ctx)->rp = rp; - ((t0_context *)t0ctx)->ip = ip; -} - - - -/* - * Verify the signature on the certificate with the provided public key. - * This function checks the public key type with regards to the expected - * type. Returned value is either 0 on success, or a non-zero error code. - */ -static int -verify_signature(br_x509_minimal_context *ctx, const br_x509_pkey *pk) -{ - int kt; - - kt = ctx->cert_signer_key_type; - if ((pk->key_type & 0x0F) != kt) { - return BR_ERR_X509_WRONG_KEY_TYPE; - } - switch (kt) { - unsigned char tmp[64]; - - case BR_KEYTYPE_RSA: - if (ctx->irsa == 0) { - return BR_ERR_X509_UNSUPPORTED; - } - if (!ctx->irsa(ctx->cert_sig, ctx->cert_sig_len, - &t0_datablock[ctx->cert_sig_hash_oid], - ctx->cert_sig_hash_len, &pk->key.rsa, tmp)) - { - return BR_ERR_X509_BAD_SIGNATURE; - } - if (memcmp(ctx->tbs_hash, tmp, ctx->cert_sig_hash_len) != 0) { - return BR_ERR_X509_BAD_SIGNATURE; - } - return 0; - - case BR_KEYTYPE_EC: - if (ctx->iecdsa == 0) { - return BR_ERR_X509_UNSUPPORTED; - } - if (!ctx->iecdsa(ctx->iec, ctx->tbs_hash, - ctx->cert_sig_hash_len, &pk->key.ec, - ctx->cert_sig, ctx->cert_sig_len)) - { - return BR_ERR_X509_BAD_SIGNATURE; - } - return 0; - - default: - return BR_ERR_X509_UNSUPPORTED; - } -} - - - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/bearssl/x509_minimal_full.c b/src/tls/bearssl/x509_minimal_full.c deleted file mode 100644 index c0dc6c7c7..000000000 --- a/src/tls/bearssl/x509_minimal_full.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "inner.h" - -/* see bearssl_x509.h */ -void -br_x509_minimal_init_full(br_x509_minimal_context *xc, - const br_x509_trust_anchor *trust_anchors, size_t trust_anchors_num) -{ - /* - * All hash functions are activated. - * Note: the X.509 validation engine will nonetheless refuse to - * validate signatures that use MD5 as hash function. - */ - static const br_hash_class *hashes[] = { - &br_md5_vtable, - &br_sha1_vtable, - &br_sha224_vtable, - &br_sha256_vtable, - &br_sha384_vtable, - &br_sha512_vtable - }; - - int id; - - br_x509_minimal_init(xc, &br_sha256_vtable, - trust_anchors, trust_anchors_num); - br_x509_minimal_set_rsa(xc, &br_rsa_i31_pkcs1_vrfy); - br_x509_minimal_set_ecdsa(xc, - &br_ec_prime_i31, &br_ecdsa_i31_vrfy_asn1); - for (id = br_md5_ID; id <= br_sha512_ID; id ++) { - const br_hash_class *hc; - - hc = hashes[id - 1]; - br_x509_minimal_set_hash(xc, id, hc); - } -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/utility/TLSClientMqtt.cpp b/src/tls/utility/TLSClientMqtt.cpp index c2fb95725..d775f868d 100644 --- a/src/tls/utility/TLSClientMqtt.cpp +++ b/src/tls/utility/TLSClientMqtt.cpp @@ -24,11 +24,8 @@ #ifdef BOARD_HAS_ECCX08 #include "tls/BearSSLTrustAnchors.h" + #include "tls/BearSSLClientProfile.h" extern "C" { - void aiotc_client_profile_init(br_ssl_client_context *cc, - br_x509_minimal_context *xc, - const br_x509_trust_anchor *trust_anchors, - size_t trust_anchors_num); unsigned long getTime(); } #endif @@ -46,7 +43,7 @@ void TLSClientMqtt::begin(ConnectionHandler & connection, ArduinoIoTAuthenticati setClient(connection.getClient()); setProfile(aiotc_client_profile_init); setTrustAnchors(ArduinoIoTCloudTrustAnchor, ArduinoIoTCloudTrustAnchor_NUM); - onGetTime(getTime); + ArduinoBearSSL.onGetTime(getTime); #elif defined(ARDUINO_PORTENTA_C33) (void)authMode; setClient(connection.getClient()); diff --git a/src/tls/utility/TLSClientMqtt.h b/src/tls/utility/TLSClientMqtt.h index a66ef430e..689eff2f8 100644 --- a/src/tls/utility/TLSClientMqtt.h +++ b/src/tls/utility/TLSClientMqtt.h @@ -35,7 +35,8 @@ enum class ArduinoIoTAuthenticationMode * Arduino Giga R1 * OPTA */ - #include + #include + #include class TLSClientMqtt : public BearSSLClient { #elif defined(ARDUINO_PORTENTA_C33) /* diff --git a/src/tls/utility/TLSClientOta.cpp b/src/tls/utility/TLSClientOta.cpp index 7f9ea981d..8d90e64b6 100644 --- a/src/tls/utility/TLSClientOta.cpp +++ b/src/tls/utility/TLSClientOta.cpp @@ -24,11 +24,8 @@ #ifdef BOARD_HAS_ECCX08 #include "tls/BearSSLTrustAnchors.h" + #include "tls/BearSSLClientProfile.h" extern "C" { - void aiotc_client_profile_init(br_ssl_client_context *cc, - br_x509_minimal_context *xc, - const br_x509_trust_anchor *trust_anchors, - size_t trust_anchors_num); unsigned long getTime(); } #endif @@ -42,7 +39,7 @@ void TLSClientOta::begin(ConnectionHandler &connection) { setClient(*getNewClient(connection.getInterface())); setProfile(aiotc_client_profile_init); setTrustAnchors(ArduinoIoTCloudTrustAnchor, ArduinoIoTCloudTrustAnchor_NUM); - onGetTime(getTime); + ArduinoBearSSL.onGetTime(getTime); #elif defined(ARDUINO_PORTENTA_C33) setClient(*getNewClient(connection.getInterface())); setCACert(AIoTSSCert); diff --git a/src/tls/utility/TLSClientOta.h b/src/tls/utility/TLSClientOta.h index d03c2d28c..6859a96e6 100644 --- a/src/tls/utility/TLSClientOta.h +++ b/src/tls/utility/TLSClientOta.h @@ -29,7 +29,8 @@ * Arduino Giga R1 * OPTA */ - #include + #include + #include class TLSClientOta : public BearSSLClient { #elif defined(ARDUINO_PORTENTA_C33) /* diff --git a/src/tls/utility/eccX08_asn1.h b/src/tls/utility/eccX08_asn1.h deleted file mode 100644 index 571c56605..000000000 --- a/src/tls/utility/eccX08_asn1.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2018 Arduino SA. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef _ECCX08_ASN1_H_ -#define _ECCX08_ASN1_H_ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "../bearssl/bearssl.h" - -size_t -eccX08_sign_asn1(const br_ec_impl *impl, - const br_hash_class *hf, const void *hash_value, - const br_ec_private_key *sk, void *sig); - -uint32_t -eccX08_vrfy_asn1(const br_ec_impl *impl, - const void *hash, size_t hash_len, - const br_ec_public_key *pk, - const void *sig, size_t sig_len); - -#endif /* #ifdef BOARD_HAS_ECCX08 */ - -#endif diff --git a/src/tls/utility/eccX08_sign_asn1.cpp b/src/tls/utility/eccX08_sign_asn1.cpp deleted file mode 100644 index 95be607fe..000000000 --- a/src/tls/utility/eccX08_sign_asn1.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * Copyright (c) 2018 Arduino SA. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "eccX08_asn1.h" - -#include - -#define BR_MAX_EC_SIZE 528 -#define ORDER_LEN ((BR_MAX_EC_SIZE + 7) >> 3) - -size_t -eccX08_sign_asn1(const br_ec_impl * /*impl*/, - const br_hash_class * /*hf*/, const void *hash_value, - const br_ec_private_key *sk, void *sig) -{ - unsigned char rsig[(ORDER_LEN << 1) + 12]; - size_t sig_len; - - if (sk->curve != BR_EC_secp256r1) { - return 0; - } - - if (!ECCX08.ecSign((int)(sk->x), (const uint8_t*)hash_value, (uint8_t*)rsig)) { - return 0; - } - sig_len = 64; - - sig_len = br_ecdsa_raw_to_asn1(rsig, sig_len); - memcpy(sig, rsig, sig_len); - return sig_len; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */ diff --git a/src/tls/utility/eccX08_vrfy_asn1.cpp b/src/tls/utility/eccX08_vrfy_asn1.cpp deleted file mode 100644 index 4745a6ec5..000000000 --- a/src/tls/utility/eccX08_vrfy_asn1.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * Copyright (c) 2018 Arduino SA. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#ifdef BOARD_HAS_ECCX08 - -#include "eccX08_asn1.h" - -#include - -#define BR_MAX_EC_SIZE 528 -#define FIELD_LEN ((BR_MAX_EC_SIZE + 7) >> 3) - -uint32_t -eccX08_vrfy_asn1(const br_ec_impl * /*impl*/, - const void *hash, size_t hash_len, - const br_ec_public_key *pk, - const void *sig, size_t sig_len) -{ - /* - * We use a double-sized buffer because a malformed ASN.1 signature - * may trigger a size expansion when converting to "raw" format. - */ - unsigned char rsig[(FIELD_LEN << 2) + 24]; - - if (sig_len > ((sizeof rsig) >> 1)) { - return 0; - } - - memcpy(rsig, sig, sig_len); - sig_len = br_ecdsa_asn1_to_raw(rsig, sig_len); - - if (hash_len != 32 || pk->curve != BR_EC_secp256r1 || pk->qlen != 65 || sig_len != 64) { - return 0; - } - - // TODO: understand why the public key is &pk->q[1] instead of &pk->q[0] ... - if (!ECCX08.ecdsaVerify((const uint8_t*)hash, (const uint8_t*)rsig, (const uint8_t*)&pk->q[1])) { - return 0; - } - - return 1; -} - -#endif /* #ifdef BOARD_HAS_ECCX08 */